KubernetesのPodにConfigMapを複数読み込ませたり、複数のPodで同じConfogMapを読み込ませてみる


これなに?

KubernetesでPodを2つデプロイした上で同じデータをConfigMapを使って動的に共有してみたり、複数のConfigMapを1つのPodに読み込ませたりします。
また、今回はConfigMapの公式ドキュメントだけでは理解しにくい同時にこれらを扱う使い方をRedisを使ったチュートリアル形式で紹介します。
※簡単に触るだけをしたい方はこちらの記事がオススメです

今回使用した環境とあらかじめいるもの

  • OSX El Capitan ver.10.11.6
  • exec
  • Vagrant
  • VirtualBox
  • CoreOS
  • Kubernetes

〜 Kubernetesの環境は構築済で進めます。構築の解説はこの記事を参考にしてください 〜

必要なファイルの準備

まず、下記の5つのファイルを作成して、同じフォルダにおいてください。
※yamlファイル以外の拡張子のないものは必ず拡張子なしで作成をしてください

次の2つのファイルは今回使うRedisのPodの指定したい設定情報のみが書かれたConfigMapの元です

redis-config1
maxmemory 2mb
maxmemory-policy allkeys-lru
redis-config2
maxmemory 4mb
maxmemory-policy allkeys-lru

次のファイルは今回使う2つのPodで使う動的な共有データをyamlで書いたConfigMapの元です

redis-example.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-example
data:
  example.property.1: hello
  example.property.2: area
  example.property.3: niki’s
  example.property.4: world
  example.property.5: create

次の2つのファイルは今回使う2つのRedisのPodの設定情報が書かれたものです

redis-pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: redis1
spec:
  containers:
  - name: redis
    image: kubernetes/redis:v1
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: "0.1"
    volumeMounts:
    - mountPath: /redis-master-data
      name: data
    - mountPath: /redis-master
      name: config
    - mountPath: /redis-cli
      name: redis-data
  volumes:
    - name: data
      emptyDir{}
    - name: config
      configMap:
        name: redis-config1
        items:
        - key: redis-config1
          path: redis.conf
    - name: redis-data
      configMap:
        name: redis-example
redis-pod2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: redis2
spec:
  containers:
  - name: redis
    image: kubernetes/redis:v1
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    resources:
      limits:
        cpu: "0.1"
    volumeMounts:
    - mountPath: /redis-master-data
      name: data
    - mountPath: /redis-master
      name: config
    - mountPath: /redis-cli
      name: redis-data
  volumes:
    - name: data
      emptyDir{}
    - name: config
      configMap:
        name: redis-config2
        items:
        - key: redis-config2
          path: redis.conf
    - name: redis-data
      configMap:
        name: redis-example

作成できたら、Kubernetesを立ち上げて次へ進みましょう!

ConfigMapを作成する

ConfigMapを作成する方法は下記の3パターンあります

  • yamlファイルなどの設定ファイル直接記述して作る方法
    • kubectl create -f config.conf 方式
  • 指定したい設定情報のみのファイルを記述して作る方法
    • kubectl create configmap --from-file 方式
  • コマンドの引数に直接設定情報の引数を入れる方法
    • kubectl create configmap --from-literal 方式

今回はyamlファイルを記述する方法と指定したい設定情報のみのファイルを記述する方法を使っていきます

まず、指定したい設定情報のみのファイルからConfigMapを作ります。

$ kubectl create configmap redis-config1 --from-file=redis-config1
configmap "redis-config1" created
$ kubectl create configmap redis-config2 --from-file=redis-config2
configmap "redis-config2" created

次にyamlファイルを使って設定情報を直接記述する方法でConfigMapを作ります。

$ kubectl create -f redis-example.yaml
configmap "redis-example" created

正しく作成できたかどうかを確認してみましょう。

$ kubectl get configmap
NAME            DATA      AGE
redis-config1   1         6m
redis-config2   1         5m
redis-example   5         3m

ConfigMapを用いてPodをデプロイしてみる

ConfigMapはbashコマンドを叩いてデプロイするときに環境変数に設定する方法とVolumeとしてマウントする方法があり、ここではVolumeを利用して異なる設定をしたPodを2つデプロイして、ファイルは共通のものを動的に利用することに挑戦します。

以下のコマンドでいっきに2つともPodをデプロイしちゃいましょう

$ kubectl create -f redis-pod1.yaml &&kubectl create -f redis-pod2.yaml
pod "redis1" created
pod "redis2" created

正しくPodがデプロイされたか確認してみましょう

$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
redis1    1/1       Running   0          1m
redis2    1/1       Running   0          1m

STATUSがRunningになっていたら準備は完了です。次へ進んで色々動かしてみましょう

各Podが正しくConfigMap通り設定されているか確認する

まずは「redis1」という名前のPodに入って確認しみましょう

$ kubectl exec -it redis1 redis-cli
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "2097152"
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"
127.0.0.1:6379> exit

次に「redis2」という名前のPodの中に入って確認してみましょう

$ kubectl exec -it redis2 redis-cli
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "4194304"
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"
127.0.0.1:6379> exit

※IPアドレスがポートまで同じなのはそうなるようにyamlで書いてあるからなので、別々でもOKです

今回はmaxmemoryが異なる設定にしたので、異なることが出力からわかるかと思います。

次に同じ動的なデータをConfigMapから持ってこれていることを確認してみましょう

$ kubectl exec redis1 cat /redis-cli/example.property.1
hello
$ kubectl exec redis2 cat /redis-cli/example.property.1
hello

ConfigMapで値を変更するとPod側の値も変わることを確認

 ConfigMapでVolumeの値を変えると即座にPod側にも反映されることを試してみましょう

$ kubectl edit configmap redis-example

標準だとviが立ち上がるので下記のように編集してみましょう

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  example.property.1: niki’s #Change
  example.property.2: area
  example.property.3: hello  #Change
  example.property.4: world
  example.property.5: create
kind: ConfigMap
metadata:
  creationTimestamp: 2016-08-23T04:27:36Z
  name: redis-example
  namespace: default
  resourceVersion: "93754"
  selfLink: /api/v1/namespaces/default/configmaps/redis-example
  uid: eb2a107c-68e9-11e6-96ee-080027e9ede8

escキーを押して:wqで変更を保存してViを終了させたら、変更が反映されているか確認してみましょう

$ kubectl exec redis1 cat /redis-cli/example.property.1
niki’s
$ kubectl exec redis2 cat /redis-cli/example.property.1
niki’s

ここで、もともとConfigMapを作るときに記述したファイルを確認してみましょう。

$ cat redis-example.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-example
data:
  example.property.1: hello
  example.property.2: area
  example.property.3: niki’s
  example.property.4: world
  example.property.5: create

ここからわかるように、もともとConfigMapを作成するために使用したファイルが書き換わるわけではなく、Kubernetes上のConfigMapが都度書き換わるという形のようです。また、同時に動的なデータを共有している仕組みについてはこの記事が参考になります。

では、次は自分で実際に色々データを書き換えて出力をして試してみてください。(example.property.1~5までありますよ)

遊び終えたら次のコマンドでもとどおりになります。お疲れさまでした!

$ kubectl delete pod redis1 && kubectl delete pod redis2 && kubectl delete configmap redis-example && kubectl delete configmap redis-config2 && kubectl delete configmap redis-config1
pod "redis1" deleted
pod "redis2" deleted
configmap "redis-example" deleted
configmap "redis-config2" deleted
configmap "redis-config1" deleted

参考文献