ConfigMapとSecretによる設定管理
APIの保存値、マウントされたファイル、起動時の環境変数のどれを変更・参照しているか説明します。
説明
ConfigMapは設定値、Secretは秘密として扱う値をPodへ渡す資源です。Secretのdata欄のBase64は保存表現であり、暗号化そのものではありません。環境変数へ渡した値と、ファイルとしてマウントした値では更新の反映方法が違います。
公開用の例示値を使って、同じmodeを環境変数とファイルの両方へ渡します。ConfigMapを変更し、ファイルの反映と既存プロセスの環境を比較した後、Podを作り直して確認します。
APIの保存値、マウントされたファイル、起動時の環境変数のどれを変更・参照しているか説明します。
1設定と例示用Secretを登録する
mode=blueと、公開試料のdemo-keyをそれぞれ登録します。ここで使う値は認証サービスの資格情報ではなく、表現を調べるための文字列です。
kubectl create configmap settings設定値を登録する --from-literal=mode=blue
kubectl create secret generic example-key例示値をSecretへ登録する --from-literal=token=demo-keyConfigMapとSecretが作られました。別の名前を持つ別の資源として管理されます。
2Base64の保存表現
Secretのdata.tokenを取得し、Base64を復号します。
kubectl get secret example-keyAPIのdata欄を読む -o jsonpath='{.data.token}{"\n"}'
kubectl get secret example-key同じ値を復号処理へ渡す -o jsonpath='{.data.token}' | python3 -cBase64から元のバイト列へ戻す 'import sys,base64; print(base64.b64decode(sys.stdin.read()).decode())'ZGVtby1rZXk=からdemo-keyへ戻せます。data欄を読める主体には元の値も読めるため、アクセス権や保存時の暗号化が別途必要です。
3環境変数とファイルで参照する
readerはConfigMapのmodeをMODEへ渡し、同じConfigMapを/configへ、Secretを/credentialsへマウントします。
kubectl apply -f reader.json三つの参照を持つPodを作る
kubectl wait起動を待つ --for=condition=Ready pod/reader --timeout=60s > /dev/null
python3 inspect.py config blueファイルと環境変数を比較する
kubectl exec reader -- cat /credentials/tokenマウントしたSecretを読むfile=blue、env=blueで一致し、Secretの例示値もファイルから読めます。参照方法はPod定義で決めています。
4ConfigMapだけを変更する
APIのmodeをgreenへ変えます。Podは作り直しません。
kubectl patch configmap settingsAPIに保存するmodeをgreenへ変更する --type=merge -p '{"data":{"mode":"green"}}'APIにはgreenが保存されました。既存プロセスの環境まで書き換える操作ではありません。
5設定ファイルと環境変数への反映の違い
マウントしたファイルにgreenが反映されるまで待ち、MODEも読みます。ConfigMapの反映には遅れがあります。
python3 inspect.py config green反映後のファイルと既存の環境を読むfile=greenですがenv=blueです。マウントしたファイルの更新と、起動時に受け取った環境変数は異なります。アプリがファイルを再読込するかも別の条件です。
6Podを作り直して環境を更新する
同じPod定義で作り直すと、現在のConfigMapから環境変数を設定します。
kubectl delete pod reader旧プロセスを終了する --wait=true > /dev/null
kubectl apply -f reader.json同じ参照定義で作り直す
kubectl waitReadyを待つ --for=condition=Ready pod/reader --timeout=60s > /dev/null
python3 inspect.py config green新しいプロセスの値を照合するfile=green、env=greenにそろいました。Pod定義にblueを直書きしていたわけではなく、起動時に参照した時点が違っていました。
7ConfigMapとSecretの名前空間
二つの資源の名前空間を確認します。Podは原則として同じ名前空間のConfigMapとSecretを参照します。
kubectl get configmap settings設定の名前空間を読む -o jsonpath='{.metadata.namespace}{"/"}{.metadata.name}{"\n"}'
kubectl get secret example-keySecretの名前空間を読む -o jsonpath='{.metadata.namespace}{"/"}{.metadata.name}{"\n"}'どちらもlessonにあります。資源名だけでなく名前空間も参照先の識別に含まれます。
まとめ
Base64は秘密を守る暗号化ではありません。
環境変数は起動時の値、マウントされた設定ファイルは更新後の値になり得ます。
設定ファイルの更新とアプリによる再読込も別々に確認します。
操作履歴と解説を振り返れます。
Kubernetes 1.37.0 / kind 0.33.0 / Linux arm64
kubectl create configmap settings --from-literal=mode=blue
kubectl create secret generic example-key --from-literal=token=demo-keyconfigmap/settings created secret/example-key created
kubectl get secret example-key -o jsonpath='{.data.token}{"\n"}'
kubectl get secret example-key -o jsonpath='{.data.token}' | python3 -c 'import sys,base64; print(base64.b64decode(sys.stdin.read()).decode())'ZGVtby1rZXk= demo-key
kubectl apply -f reader.json
kubectl wait --for=condition=Ready pod/reader --timeout=60s > /dev/null
python3 inspect.py config blue
kubectl exec reader -- cat /credentials/tokenpod/reader created file=blue env=blue demo-key
kubectl patch configmap settings --type=merge -p '{"data":{"mode":"green"}}'configmap/settings patched
python3 inspect.py config greenfile=green env=blue
kubectl delete pod reader --wait=true > /dev/null
kubectl apply -f reader.json
kubectl wait --for=condition=Ready pod/reader --timeout=60s > /dev/null
python3 inspect.py config greenpod/reader created file=green env=green
kubectl get configmap settings -o jsonpath='{.metadata.namespace}{"/"}{.metadata.name}{"\n"}'
kubectl get secret example-key -o jsonpath='{.metadata.namespace}{"/"}{.metadata.name}{"\n"}'lesson/settings lesson/example-key
演習完了