kawabatas技術ブログ

試してみたことを書いていきます

Kubernetes の ConfigMap と Secret の更新を試す

概要

ConfigMap や Secret の更新が動的に反映されるのか検証します。

ボリュームマウントで利用する場合と、それ以外で利用する場合とで変わるのか。

手順

事前準備

検証用の Namespace を作成

$ kubectl create namespace test-namespace

ConfigMap を作成

$ kubectl create configmap test-config --from-literal=KEY=hello --namespace test-namespace
$ kubectl get configmap -n test-namespace

Secret を作成

$ kubectl create secret generic test-secret --from-literal=username=testuser --from-literal=password=testpass --namespace test-namespace
$ kubectl get secret -n test-namespace

ConfigMap, Secret を扱う Pod を作成

ボリュームマウント以外の方法で読み込む

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: test-namespace
spec:
  containers:
    - name: app
      image: k8s.gcr.io/busybox
      # あとから exec で操作するため sleep させておく
      command: ["sleep", "3600"]
      env:
        - name: KEY
          valueFrom:
            configMapKeyRef:
              name: test-config
              key: KEY
        - name: USER
          valueFrom:
            secretKeyRef:
              name: test-secret
              key: username
        - name: PASS
          valueFrom:
            secretKeyRef:
              name: test-secret
              key: password

Pod に接続し env を確認

$ kubectl exec -it test-pod sh -n test-namespace
/ # env | grep -e KEY -e USER -e PASS
USER=testuser
KEY=hello
PASS=testpass

ボリュームマウントで読み込む

apiVersion: v1
kind: Pod
metadata:
  name: test-pod-2
  namespace: test-namespace
spec:
  containers:
    - name: app
      image: k8s.gcr.io/busybox
      command: ["sleep", "3600"]
      volumeMounts:
        - name: config-volume
          mountPath: /etc/config
        - name: secret-volume
          mountPath: /etc/secret
  volumes:
    - name: config-volume
      configMap:
        name: test-config
    - name: secret-volume
      secret:
        secretName: test-secret

確認

$ kubectl exec -it test-pod-2 sh -n test-namespace
/ # cat /etc/config/KEY
hello/ # cat /etc/secret/username
testuser/ # cat /etc/secret/password
testpass/ #

ConfigMap, Secret を削除し、確認

$ kubectl delete configmap test-config -n test-namespace
$ kubectl delete secret test-secret -n test-namespace

test-pod-2 は describe で変化が見られた。

$ kubectl describe pod test-pod-2 -n test-namespace
Events:
  Type     Reason                 Age               From                                       Message
  ----     ------                 ----              ----                                       -------
  Warning  FailedMount            12s (x8 over 1m)  kubelet, gke-xxxx-pool-6b5e92d3-t72h  MountVolume.SetUp failed for volume "config-volume" : configmaps "test-config" not found
  Warning  FailedMount            12s (x8 over 1m)  kubelet, gke-xxxx-pool-6b5e92d3-t72h  MountVolume.SetUp failed for volume "secret-volume" : secrets "test-secret" not found

ボリュームマウントで利用する場合は kubelet の sync loop で反映されるらしいので、その通りっぽい。

が、test-pod-2 で確認すると、削除前と同じ結果が得られた。

/ # cat /etc/config/KEY
hello/ # cat /etc/secret/username
testuser/ # cat /etc/secret/password
testpass/ #

test-pod の env は変化なし。

test-pod, test-pod-2 ともに Pod の再起動なし。

ConfigMap, Secret 値を変えて作成し直し、確認

$ kubectl create configmap test-config --from-literal=KEY=world --namespace test-namespace
$ kubectl create secret generic test-secret --from-literal=username=testuser2 --from-literal=password=testpass2 --namespace test-namespace

test-pod, test-pod-2 ともに describe コマンドで変更は特になし。

test-pod の env は変化なし。

test-pod-2 は更新されていた。

/ # cat /etc/config/KEY
world/ # cat /etc/secret/username
testuser2/ # cat /etc/secret/password
testpass2/ #

test-pod, test-pod-2 ともに Pod の再起動なし。

後片付け

kubectl delete namespace test-namespace

まとめ

  • ボリュームマウントで利用する場合、ConfigMap や Secret を更新すると、動的に反映される
  • ボリュームマウントで利用する場合、ConfigMap や Secret を削除しても、pod がエラーになるわけではない
  • kubelet の sync loop のタイミングで反映されるので、即座に反映されるわけではない
  • Pod の再起動がされるわけでもない

動画を追加(2019/02/24)

上の内容を実際にやってみた動画を追加しました。

※06:30ごろ、早送りの関係で、一部音声が乱れています。

youtu.be