Kubernetes ConfigMapの作成と参照


環境に依存して、アプリケーションの動作を切り替えたい場合など、Javaのコードからプロパティファイルを読み取り事があります。この様なケースで、k8sのConfigMapという機能が大変便利です。 ConfigMapの利用法についての簡単なメモです。


Javaでプロパティファイルを読み取る方法

* [【Java入門】プロパティファイルの読み込み方法(Properties) ](https://www.sejuku.net/blog/20794)
* [Java：Propertiesを使ってプロパティファイルを読み込む](http://www.hiihah.info/index.php?Java%EF%BC%9AProperties%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80)


もちろん、プロパティファイル以外にも利用できます。


## ディレクトリからのConfigMapの作成

例として、３つのプロパティをConfigMapに登録します。


~~~
$ ls config-1
game.properties  log.properties  ui.properties

$ ls -al config-1 
total 12
drwxr-xr-x 1 vagrant vagrant  170 Mar  2 06:22 .
drwxr-xr-x 1 vagrant vagrant 2142 Mar  2 06:22 ..
-rw-r--r-- 1 vagrant vagrant  158 Mar  2 06:13 game.properties
-rw-r--r-- 1 vagrant vagrant   29 Mar  2 06:15 log.properties
-rw-r--r-- 1 vagrant vagrant   83 Mar  2 06:14 ui.properties

$ cat config-1/game.properties 
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

$ cat config-1/log.properties 
level=debug
rotation=disable

$ cat config-1/ui.properties 
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
~~~


ディレクトリ名を指定して、game-configという名前で、ConfigMapを作成します。

~~~
$ kubectl create configmap game-config --from-file=config-1
configmap "game-config" created
~~~


登録の確認をします。 ３つのデータ（ファイル）で登録されている事が読み取れます。

~~~
$ kubectl get configmap game-config
NAME          DATA      AGE
game-config   3         10s
~~~


内容を表示してみます。

~~~
$ kubectl get configmap game-config -o yaml
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  log.properties: |
    level=debug
    rotation=disable
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  creationTimestamp: 2018-03-02T06:27:32Z
  name: game-config
  namespace: default
  resourceVersion: "504555"
  selfLink: /api/v1/namespaces/default/configmaps/game-config
  uid: c9e6304d-1de2-11e8-bda2-8a5c75064a39
~~~


## ポッドからConfigMapの参照

作成したconfigMapをポッドから参照します。 
参照用のポッドでは configMapを /etc/configにマウントします。 
つまり、ローカル環境にあったconfigMapのディレクトリは、ボリュームとして、コンテナにマウントされる事になります。


~~~
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: configmap-cnt
      image: ubuntu:latest
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
      command: ["tail",  "-f", "/dev/null"]
  volumes:
    - name: config-vol
      configMap:
        name: game-config
~~~

前述のYAMLファイルから、ポッドを作成します。

~~~
$ kubectl create -f v01-configmap.yaml
pod "configmap-pod" created
$ kubectl get pods
NAME                            READY     STATUS              RESTARTS   AGE
configmap-pod                   0/1       ContainerCreating   0          4s
mysql-server-6c949ddbbc-cq2lp   1/1       Running             0          19d
redis-7665764c55-vdrtp          1/1       Running             0          19d
web-app-6bb987f657-bxxjd        2/2       Running             0          19d
web-app-6bb987f657-v2c2c        2/2       Running             0          19d
web-app-6bb987f657-zw5t7        2/2       Running             0          19d
web-jenkins-84d889c69d-78pw5    1/1       Running             0          19d
web-pd-7697d4565-vzllz          1/1       Running             0          19d
$ kubectl get pods
NAME                            READY     STATUS    RESTARTS   AGE
configmap-pod                   1/1       Running   0          5s
mysql-server-6c949ddbbc-cq2lp   1/1       Running   0          19d
redis-7665764c55-vdrtp          1/1       Running   0          19d
web-app-6bb987f657-bxxjd        2/2       Running   0          19d
web-app-6bb987f657-v2c2c        2/2       Running   0          19d
web-app-6bb987f657-zw5t7        2/2       Running   0          19d
web-jenkins-84d889c69d-78pw5    1/1       Running   0          19d
web-pd-7697d4565-vzllz          1/1       Running   0          19d
~~~


ポッドが出来たら、ポッドへログインして、該当のディレクトリを参照します。 
３個のファイルが /etc/configにある事が解ります。 それぞれの内容を参照する事ができます。

~~~
$ kubectl exec -it configmap-pod bash
root@configmap-pod:/# df
Filesystem              1K-blocks    Used Available Use% Mounted on
overlay                 103079200 4599600  93220440   5% /
tmpfs                     2047996       0   2047996   0% /dev
tmpfs                     2047996       0   2047996   0% /sys/fs/cgroup
/dev/xvda2               25091960 2288616  22786960  10% /etc/hosts
/dev/mapper/docker_data 103079200 4599600  93220440   5% /etc/hostname
shm                         65536       0     65536   0% /dev/shm
tmpfs                     2047996      12   2047984   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                     2047996       0   2047996   0% /sys/firmware

root@configmap-pod:/# cd /etc/config
root@configmap-pod:/etc/config# ls -al
total 12
drwxrwxrwx 3 root root 4096 Mar  2 06:35 .
drwxr-xr-x 1 root root 4096 Mar  2 06:35 ..
drwxr-xr-x 2 root root 4096 Mar  2 06:35 ..3983_02_03_06_35_53.460563009
lrwxrwxrwx 1 root root   31 Mar  2 06:35 ..data -> ..3983_02_03_06_35_53.460563009
lrwxrwxrwx 1 root root   22 Mar  2 06:35 game.properties -> ..data/game.properties
lrwxrwxrwx 1 root root   21 Mar  2 06:35 log.properties -> ..data/log.properties
lrwxrwxrwx 1 root root   20 Mar  2 06:35 ui.properties -> ..data/ui.properties

root@configmap-pod:/etc/config# cat /etc/config/game.properties 
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

root@configmap-pod:/etc/config# cat /etc/config/log.properties  
level=debug
rotation=disable

root@configmap-pod:/etc/config# cat /etc/config/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
~~~


## 最後に

この方法以外に、リテラルで設定する方法、環境変数へセットする方法、ConfigMapをYAMLで定義する方法など、いろいろあるので、詳しい事は参考資料を参照してください。




## 参考資料
* Configure a Pod to Use a ConfigMap https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#create-configmaps-from-directories