TT Lab
はじめる
学ぶ 学習パス コース

CKAD — Kubernetesアプリケーション開発者

ConfigMapとSecretで設定を注入する

TT Labで続きを見る

目標

同じイメージを環境ごとに異なる動作をさせる4つの注入経路(全体の環境変数、個別の環境変数、ファイルボリューム、subPathファイル)を使い分け、SecretとConfigMapの違いをフィールドレベルで扱えるようになります。

なぜ重要なのか

設定の注入で実務の事故が起きるのは、ほとんどが「更新が反映されるか」という点です。環境変数で入れた値はプロセスの開始時に1回読まれて終わりなので、ConfigMapを修正してもPodを作り直すまでは決して変わりません。ボリュームで入れたファイルはkubeletが定期的に更新してくれますが、subPathでマウントしたファイルだけは例外で、更新されません。この3つの動作の違いを知らないと、「設定を変えたのになぜ効かないのか」で時間を使い果たします。

defaultModeも実務でよく引っかかります。Secretをマウントするとデフォルトの権限が0644なので、同じノードの他のプロセスが読めてしまいます。TLSキーのように機密性の高いファイルは0400に絞ります。YAMLで0400を引用符なしで書くと8進数として解釈されますが、400だけを書くと10進数の400として読まれ、意図しない権限になります。

immutable: trueはセキュリティ機能ではなくパフォーマンス機能です。kubeletはマウントされたConfigMap/Secretの変更を監視するためにAPIサーバーを叩き続けますが、immutableなら監視をやめます。数千Pod規模では、apiserverの負荷が目に見えて減ります。

ステップ

  1. ネームスペースckad-configを作成し、その中にConfigMap app-configをリテラルで作成してください。キーはAPP_MODE=production、LOG_LEVEL=infoです。
  2. ディレクトリ/root/ckad-configを作成し、ファイル/root/ckad-config/app.propertiesにtimeout=30を1行書いたうえで、そのファイルからConfigMap app-propsを作成してください(キー名はapp.propertiesです)。
  3. Pod cfg-envを作成してください。イメージはbusybox:1.36、command: ["/bin/sh","-c","sleep 3600"]です。envFromでapp-config全体を注入し、さらにenvにLOGという名前でapp-configのLOG_LEVELキーを参照してください。
  4. Secret db-secretを作成してください。タイプはgeneric(Opaque)、キーはDB_USER=appuser、DB_PASSWORD=s3cr3tです。
  5. Pod secret-consumerを作成してください。イメージはbusybox:1.36、command: ["/bin/sh","-c","sleep 3600"]です。環境変数DB_PASSWORDをdb-secretのDB_PASSWORDキーから取得し、同じSecretをボリュームdbcredsとして/etc/dbにマウントして、defaultModeを0400にしてください。
  6. Pod cfg-volを作成してください。イメージはnginx:1.27です。ConfigMap app-propsをボリュームpropsとして2回マウントします。1つは/etc/appにディレクトリごと、もう1つはsubPath: app.propertiesで/opt/app/app.propertiesにマウントしてください。
  7. ConfigMap feature-flagsを作成してください。キーはNEW_UI=onで、immutable: trueを指定します。Pod optional-cmを作成し(イメージbusybox:1.36、command: ["/bin/sh","-c","sleep 3600"])、存在しないConfigMap maybe-configをenvFromで参照して、optional: trueを指定してください。
  8. Deployment web-configを作成してください。レプリカは2、ラベルはapp=web-config、イメージはnginx:1.27です。envFromにapp-config(configMapRef)とdb-secret(secretRef)の両方を入れ、ConfigMap app-propsをボリュームpropsとして/etc/appにマウントしてください。

参考

リテラルでConfigMapを作成する

ネームスペースckad-configを作成し、その中にConfigMap app-configをリテラルで作成してください。キーはAPP_MODE=production、LOG_LEVEL=infoです。

kubectl create configmapには、--from-literal=키=값を複数回指定できます(プレースホルダーはキーと値です)。ネームスペースを先に作成しておき、-nを忘れないようにします。

ファイルからConfigMapを作成する

ディレクトリ/root/ckad-configを作成し、ファイル/root/ckad-config/app.propertiesにtimeout=30を1行書いたうえで、そのファイルからConfigMap app-propsを作成してください(キー名はapp.propertiesです)。

--from-file=경로を使うとファイル名がキーになり、ファイルの内容全体が値になります(プレースホルダーはパスです)。キー名を変えたい場合は、--from-file=키이름=경로の形式を使います(プレースホルダーはキー名とパスです)。

envFromとconfigMapKeyRefを併用する

Pod cfg-envを作成してください。イメージはbusybox:1.36、command: ["/bin/sh","-c","sleep 3600"]です。envFromでapp-config全体を注入し、さらにenvにLOGという名前でapp-configのLOG_LEVELキーを参照してください。

envFrom[].configMapRefはすべてのキーをそのまま変数名にし、env[].valueFrom.configMapKeyRefはキーを1つ選んで別の名前で入れます。2つの方式を、1つのコンテナで併用できます。

Secretを作成してエンコードを確認する

Secret db-secretを作成してください。タイプはgeneric(Opaque)、キーはDB_USER=appuser、DB_PASSWORD=s3cr3tです。

kubectl create secret genericの--from-literalの値は、自動的にbase64でエンコードされます。YAMLで直接書くときに平文を入れたい場合は、dataの代わりにstringDataを使います。

Secretを環境変数とファイルの両方で注入する

Pod secret-consumerを作成してください。イメージはbusybox:1.36、command: ["/bin/sh","-c","sleep 3600"]です。環境変数DB_PASSWORDをdb-secretのDB_PASSWORDキーから取得し、同じSecretをボリュームdbcredsとして/etc/dbにマウントして、defaultModeを0400にしてください。

環境変数はenv[].valueFrom.secretKeyRef、ファイルはvolumes[].secret.secretNameとボリュームマウントです。ファイルの権限はボリューム側のdefaultModeで決めます。YAMLでは8進数の先頭の0を落としやすいので、注意してください。

ConfigMapボリュームとsubPath

Pod cfg-volを作成してください。イメージはnginx:1.27です。ConfigMap app-propsをボリュームpropsとして2回マウントします。1つは/etc/appにディレクトリごと、もう1つはsubPath: app.propertiesで/opt/app/app.propertiesにマウントしてください。

ディレクトリに丸ごとマウントすると、そのディレクトリの元の内容が隠れます。ファイル1つだけを載せたい場合は、volumeMounts[].subPathにキー名を書きます。subPathで載せたファイルは、ConfigMapを修正しても更新されません。

optional参照とimmutableなConfigMap

ConfigMap feature-flagsを作成してください。キーはNEW_UI=onで、immutable: trueを指定します。Pod optional-cmを作成し(イメージbusybox:1.36、command: ["/bin/sh","-c","sleep 3600"])、存在しないConfigMap maybe-configをenvFromで参照して、optional: trueを指定してください。

immutable: trueはConfigMapの定義の最上位のフィールドです(dataの中ではありません)。存在しないConfigMapを参照してもPodが起動するようにするには、参照する側にoptional: trueを指定します。

Deploymentで3つを一度に使う(総合)

Deployment web-configを作成してください。レプリカは2、ラベルはapp=web-config、イメージはnginx:1.27です。envFromにapp-config(configMapRef)とdb-secret(secretRef)の両方を入れ、ConfigMap app-propsをボリュームpropsとして/etc/appにマウントしてください。

前に作成したConfigMap 2つとSecret 1つを、1つのDeploymentで使います。envFromの配列には、configMapRefとsecretRefを並べて入れられます。ボリュームマウントも忘れないでください。