コンテナイメージは、開発・検証・本番で同じものを使えることが理想です。環境ごとの差分とデータを外へ分けるため、KubernetesにはConfigMap、Secret、Volumeがあります。
何をどこへ置くか
| データ | 適した仕組み | 例 |
|---|---|---|
| 秘密でない設定 | ConfigMap | ログレベル、機能フラグ、接続先ホスト名 |
| 機密情報 | 外部Secret Managerを優先 | DBパスワード、APIトークン、証明書 |
| 一時ファイル | emptyDir Volume | キャッシュ、コンテナ間の一時共有 |
| 永続データ | PersistentVolumeClaim | 再作成後も必要なファイル |
Kubernetes Secretは便利ですが、Secret Managerと同義ではありません。第11回で外部保管を含む選択肢を比較します。
ConfigMapを環境変数として読む
apiVersion: v1
kind: ConfigMap
metadata:
name: example-app-config
namespace: YOUR_NAMESPACE
data:
APP_MODE: production
LOG_LEVEL: info
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
namespace: YOUR_NAMESPACE
spec:
replicas: 2
selector:
matchLabels:
app: example-app
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: app
image: registry.gitlab.com/GROUP/PROJECT/IMAGE:TAG
envFrom:
- configMapRef:
name: example-app-config
環境変数として注入したConfigMapを変更しても、実行中プロセスの環境変数は自動更新されません。Deploymentを更新または再起動し、新しいPodへ反映します。
kubectl apply -f configmap-deployment.yaml
kubectl rollout restart deployment/example-app -n YOUR_NAMESPACE
kubectl rollout status deployment/example-app -n YOUR_NAMESPACE
ConfigMapをファイルとしてマウントする
apiVersion: v1
kind: ConfigMap
metadata:
name: example-nginx-config
namespace: YOUR_NAMESPACE
data:
default.conf: |
server {
listen 8080;
location /health { return 200 "ok\n"; }
}
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: nginx-config
configMap:
name: example-nginx-config
VolumeとしてマウントしたConfigMapは更新が反映される場合がありますが、反映は即時ではなく、subPath マウントでは自動更新されません。また、アプリケーション自身がファイルを再読込できる必要があります。
Kubernetes Secretの基礎
次は構造説明のためのダミー値です。実在する秘密値をこのようなマニフェストへ書き、Gitへ保存しないでください。
apiVersion: v1
kind: Secret
metadata:
name: example-app-secret
namespace: YOUR_NAMESPACE
type: Opaque
stringData:
DATABASE_PASSWORD: EXAMPLE_VALUE_NOT_FOR_PRODUCTION
PodからはConfigMapと似た形で参照できます。
env:
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: example-app-secret
key: DATABASE_PASSWORD
data フィールドへBase64文字列を書く方式もありますが、Base64は暗号化ではありません。読める人なら元へ戻せます。マニフェストを非公開リポジトリに置くだけでも十分ではなく、秘密値自体をリポジトリ外へ置きます。
Volumeはコンテナのファイルシステムと寿命を分ける
emptyDir
volumeMounts:
- name: work
mountPath: /work
volumes:
- name: work
emptyDir: {}
Pod作成時に空で用意され、同じPod内のコンテナで共有できます。コンテナが再起動してもPodが同じなら残りますが、Podが削除されると消えます。
PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: example-data
namespace: YOUR_NAMESPACE
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
PVCはストレージ要求を宣言し、GKEのStorageClassなどを通じて永続ディスクを割り当てます。アクセスモード、ゾーン、スナップショット、バックアップ、削除ポリシーまで確認します。PVCを削除した結果、背後のディスクも削除される構成があるため慎重に扱います。
使い分けの原則
- イメージ:アプリケーションと実行に必要な不変物
- ConfigMap:公開しても問題ない環境設定
- Secret Manager:秘密値の正本
- Kubernetes Secret:Kubernetes API経由で必要な場合の配布形態
- Volume:ファイルをPodへ見せる手段
- PVC:Podより長く残すストレージ要求
機密性と永続性は別軸です。SecretをVolumeマウントしても、それだけで外部保管やローテーションが解決するわけではありません。