Day 19: ConfigMapとSecret:設定情報を安全に管理する方法 🔑
皆さん、こんにちは!30日集中講座、Day 19へようこそ。
昨日までに、アプリケーションを動かすための基本的なリソース(Pod、Deployment)と、外部に公開するためのネットワークリソース(Service、Ingress)について学びました。
しかし、実際のアプリケーション開発では、データベースの接続情報やAPIキー、環境ごとの設定(開発用、本番用など)をどのように管理するかが重要になります。Dockerイメージに直接書き込むのはセキュリティリスクが高く、変更が面倒です。
そこで今回は、Kubernetesが提供する設定情報管理のためのリソース、ConfigMapとSecretについて学びます。これらを使うことで、アプリケーションのコードと設定を分離し、より安全で柔軟な運用が可能になります。
1. アプリケーション設定を管理するConfigMap ⚙️
ConfigMapは、機密性のない設定情報をキーと値のペアで管理するためのリソースです。設定ファイルの内容や環境変数などを格納するのに適しています。
ConfigMapの作成と活用方法
ConfigMapは、以下のようにYAMLファイルで定義できます。
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data:
database_url: mysql-service:3306
api_endpoint: "https://api.example.com"
また、kubectl
コマンドを使えば、YAMLファイルを作成せずに簡単にConfigMapを作成できます。
kubectl create configmap my-app-config --from-literal=database_url=mysql-service:3306 --from-literal=api_endpoint=https://api.example.com
作成したConfigMapは、以下の2つの方法でPodに渡すことができます。
-
環境変数として注入:
envFrom
を使ってConfigMapの全てのキーと値を環境変数としてコンテナに渡します。 - ボリュームとしてマウント: ConfigMapをボリュームとしてPodにマウントし、ファイルとしてアクセスします。
ConfigMapのボリュームマウント
このYAML例は、volumesとvolumeMountsという2つのセクションで構成されています。
# deployment-with-configmap-volume.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
template:
spec:
containers:
- name: my-app-container
image: my-app:1.0.0
volumeMounts:
- name: config-volume
mountPath: /etc/config # このディレクトリにファイルとしてマウントされる
volumes:
- name: config-volume
configMap:
name: my-app-config
- volumes:
- name: config-volumeでボリュームに名前を付けています。
- configMap: name: my-app-configで、my-app-configという名前のConfigMapをこのボリュームのソースとして指定しています。
- volumeMounts:
- name: config-volumeで、先ほど定義したボリュームを参照しています。
- mountPath: /etc/configで、コンテナ内のどこにこのボリュームをマウントするかを指定しています。
この設定により、my-app-configにdatabase_urlとapi_endpointというキーがあった場合、コンテナ内の/etc/configディレクトリに、それぞれdatabase_urlとapi_endpointというファイルが作成され、そのファイルの中身は対応する値(mysql-service:3306とhttps://api.example.com
)になります。
2. 機密情報を安全に管理するSecret 🔒
Secretは、データベースのパスワードやAPIキー、SSL/TLS証明書など、機密性の高い情報を安全に管理するためのリソースです。
Secretのセキュリティについて
Secretに保存されたデータは、デフォルトでbase64エンコードされています。これは単なるデータフォーマットであり、暗号化ではありません。echo "password" | base64
で誰でも簡単に変換できるため、可読性を下げるだけのものです。
Secretの真のセキュリティは、Kubernetesの RBAC(Role-Based Access Control) による厳格なアクセス制御や、etcdの暗号化によって保護されています。EKSでは、AWS KMSと連携してetcdのデータを暗号化できます。
Secretの作成と活用方法
機密情報をYAMLファイルに直接書くのは避けるべきです。kubectl create secret
コマンドを使うことで、より安全にSecretを作成できます。
kubectl create secret generic my-db-secret --from-literal=db_password=my-super-secret-password
作成したSecretは、ConfigMap
と同様に、Deployment
から参照してPodに渡します。kubectl exec
でコンテナ内に入り、echo $DB_PASSWORD
を実行すると、パスワードが平文で表示されることを確認できます。
3. まとめ:ConfigMapとSecretの使い分け
リソース | 役割 | 格納するデータ | 特徴 |
---|---|---|---|
ConfigMap | アプリケーション設定の管理 | 設定ファイル、URL、環境変数など(機密性なし) | データはプレーンテキスト。コードと設定の分離が目的。 |
Secret | 機密情報の管理 | パスワード、APIキー、証明書など(機密性あり) | データはbase64でエンコードされる。厳格なアクセス制御が目的。 |
4. トラブルシューティングとベストプラクティス
よくある問題と解決法
-
Podが新しい設定を読み込まない:
Secret
やConfigMap
を更新しても、Podは自動で新しい設定を読み込みません。変更を反映するには、Deploymentの再デプロイ(kubectl rollout restart
)が必要です。 -
キー名の入力ミス:
secretKeyRef
のkey
名が間違っていると、環境変数が設定されず、アプリケーションが起動に失敗します。 -
内容の確認方法:
# ConfigMapの内容を確認 kubectl get configmap my-app-config -o yaml # Secretの内容を確認 kubectl get secret my-db-secret -o yaml
本番運用のベストプラクティス
-
SecretのYAMLはGit管理しない: Gitへの情報漏洩リスクがあるため避けるべきです。代わりに、
kubectl create secret
コマンドをCI/CDパイプラインに組み込むか、AWS Secrets Managerなどの外部ツールと連携しましょう。 - 最小権限の原則: RBACを使って、Secretにアクセスできるユーザーやサービスアカウントを最小限に制限しましょう。
次回の予告
Day 20: Helm入門:複雑なアプリケーションを簡単にデプロイする
それでは、また明日お会いしましょう!