CTS-KB

ConfigMap・Secret・Volume:設定、機密情報、永続データを分離する

⏱ 約 3 分で読めます
#Kubernetes#GKE#ConfigMap#Secret#Volume

コンテナイメージは、開発・検証・本番で同じものを使えることが理想です。環境ごとの差分とデータを外へ分けるため、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マウントしても、それだけで外部保管やローテーションが解決するわけではありません。

参考資料