はじめに
こんにちは。akibaです。
本記事では、Amazon EKS上でConfigMapとSecretを使用し、アプリケーション設定を管理する構成を構築します。
EKS上でアプリケーションを動かす場合、環境ごとの設定値や接続情報などを、コンテナイメージとは分けて管理したい場面があります。
Kubernetesでは、ConfigMapやSecretを使用することで、設定値をPodから参照できる形で管理できます。
今回は、ConfigMapとSecretを作成し、Deploymentから環境変数として参照させることで、Pod内のコンテナから設定値を利用できることを確認します。
また、ConfigMapの値を変更した際に、Podへどのように反映されるかについても確認します。
前提
本記事では、作成済みのEKSクラスターを使用します。
EKSクラスターの作成や、kubectl の接続設定については過去のEKS関連記事で扱っているため、本記事では詳細な手順は省略します。
今回は、kubectl でEKSクラスターを操作できる状態から、検証用のNamespaceを作成し、その中にConfigMap、Secret、Deploymentを作成します。
Deploymentではnginxの公式イメージを使用し、ConfigMapとSecretの値を環境変数としてPodへ渡します。
その後、Pod内で環境変数を確認することで、設定値がコンテナから参照できることを確認します。
なお、本記事ではConfigMapとSecretによる設定管理を主題とするため、アプリケーションの外部公開は行いません。
ConfigMapとSecretの作成
まず、今回の検証で使用するNamespaceを作成します。
Namespaceを分けることで、今回作成するConfigMap、Secret、Deploymentなどのリソースを、他の検証リソースと分けて管理できます。
# 検証用Namespaceを作成する kubectl create namespace config-secret-test
作成後、Namespaceの状態を確認します。
# 作成したNamespaceがActiveになっているか確認する $ kubectl get namespace config-secret-test NAME STATUS AGE config-secret-test Active 69s
次に、アプリケーションで使用する通常の設定値をConfigMapとして作成します。
ConfigMapは、機密情報ではない設定値をkey-value形式で管理するために使用します。
今回は検証用に、環境名とメッセージを設定値として定義します。
# アプリケーションで使用する設定値をConfigMapとして作成する kubectl create configmap app-config \ --from-literal=APP_ENV=dev \ --from-literal=APP_MESSAGE="Hello from ConfigMap" \ -n config-secret-test
作成したConfigMapの内容を確認します。
# ConfigMapに登録したキーと値を確認する $ kubectl describe configmap app-config -n config-secret-test Name: app-config Namespace: config-secret-test Labels: <none> Annotations: <none> Data ==== APP_ENV: ---- dev APP_MESSAGE: ---- Hello from ConfigMap BinaryData ==== Events: <none>
APP_ENV と APP_MESSAGE が表示されていれば、ConfigMapに設定値が登録されていることが確認できます。
続いて、Secretを作成します。
Secretは、パスワードやトークンなどの機密情報を想定した値を管理するために使用します。
今回は検証用として、ダミーのユーザー名とパスワードを定義します。
# ダミーのユーザ名とパスワードの値をSecretとして作成する kubectl create secret generic app-secret \ --from-literal=DB_USER=test-user \ --from-literal=DB_PASSWORD=test-password \ -n config-secret-test
作成したSecretの内容を確認します。
# Secretに登録されたキー名とデータサイズを確認する $ kubectl describe secret app-secret -n config-secret-test Name: app-secret Namespace: config-secret-test Labels: <none> Annotations: <none> Type: Opaque Data ==== DB_PASSWORD: 13 bytes DB_USER: 9 bytes
Secretでは、値そのものではなく、キー名やデータサイズが表示されます。
DB_USER と DB_PASSWORD が確認できれば、Secretに値が登録されています。
これで、通常の設定値を管理するConfigMapと、機密情報を想定した値を管理するSecretを作成できました。
Deploymentへの反映
次に、作成したConfigMapとSecretをDeploymentから参照します。
Deploymentは、Podの起動数や使用するコンテナイメージなどを管理するリソースです。
今回はnginxの公式イメージを使用し、ConfigMapとSecretの値を環境変数としてPodへ渡します。
まず、CloudShell上で作業用ディレクトリを作成します。
# Deploymentマニフェストを配置する作業用ディレクトリを作成する mkdir -p ~/eks-config-secret-test # 作成した作業用ディレクトリへ移動する cd ~/eks-config-secret-test
以下の内容で、config-secret-deployment.yaml を作成します。
apiVersion: apps/v1 kind: Deployment metadata: name: config-secret-app namespace: config-secret-test spec: replicas: 1 selector: matchLabels: app: config-secret-app template: metadata: labels: app: config-secret-app spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 envFrom: - configMapRef: name: app-config - secretRef: name: app-secret
このマニフェストでは、envFrom を使用してConfigMapとSecretを環境変数として参照しています。
これにより、コンテナイメージの中に設定値を含めずに、Pod起動時にKubernetes側のリソースから値を渡すことができます。
作成したマニフェストを適用します。
# DeploymentマニフェストをEKSクラスターに適用する kubectl apply -f config-secret-deployment.yaml
DeploymentによってPodが作成されていることを確認します。
# Deploymentのロールアウトが完了したか確認する $ kubectl get pods -n config-secret-test NAME READY STATUS RESTARTS AGE config-secret-app-6dbf999896-zdxzf 1/1 Running 0 91s
STATUS が Running になっていれば、Podが正常に起動しています。
これで、ConfigMapとSecretを参照するDeploymentを作成できました。
動作確認
作成したDeploymentにより、ConfigMapとSecretの値がPodへ渡されているか確認します。
今回は、ConfigMapとSecretを環境変数として参照する設定にしているため、Pod内で環境変数を確認することで、値がコンテナへ渡されているかを確認できます。
まず、確認対象のPod名を変数に格納します。
# app=config-secret-app のラベルを持つPod名を取得し、変数に格納する
POD_NAME=$(kubectl get pods -n config-secret-test -l app=config-secret-app -o jsonpath='{.items[0].metadata.name}')
次に、Pod内で環境変数を確認します。
# Pod内の環境変数からConfigMapとSecretで定義した値を確認する $ kubectl exec -it $POD_NAME -n config-secret-test -- printenv | grep -E 'APP_ENV|APP_MESSAGE|DB_USER|DB_PASSWORD' DB_PASSWORD=test-password DB_USER=test-user APP_ENV=dev APP_MESSAGE=Hello from ConfigMap
ConfigMapで定義した APP_ENV、APP_MESSAGE と、Secretで定義した DB_USER、DB_PASSWORD が表示されました。
これにより、ConfigMapとSecretで定義した値を、Deployment経由でPodの環境変数として渡せることが確認できました。
なお、今回は検証用のダミー値を使用しています。
実運用でSecretを扱う場合は、実際のパスワードやトークンなどを不用意にログや画面に出力しないよう注意が必要です。
次に、ConfigMapの値を変更した場合の反映について確認します。
今回は、ConfigMapの値を環境変数としてPodへ渡しています。
この場合、ConfigMapを更新しても、すでに起動しているPod内の環境変数には即時反映されません。
まず、ConfigMapの値を変更します。
# ConfigMapの値を更新する kubectl create configmap app-config \ --from-literal=APP_ENV=stg \ --from-literal=APP_MESSAGE="Updated from ConfigMap" \ -n config-secret-test \ --dry-run=client -o yaml | kubectl apply -f - Warning: resource configmaps/app-config is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically. configmap/app-config configured
この警告は、最初に kubectl create configmap で作成したConfigMapを、後続で kubectl apply を使用して更新したために表示されています。
configmap/app-config configured と表示されていれば、ConfigMapの更新自体は完了しています。
変更後のConfigMapの内容を確認します。
# 更新後のConfigMapの値を確認する $ kubectl describe configmap app-config -n config-secret-test Name: app-config Namespace: config-secret-test Labels: <none> Annotations: <none> Data ==== APP_ENV: ---- stg APP_MESSAGE: ---- Updated from ConfigMap BinaryData ==== Events: <none>
APP_ENV と APP_MESSAGE の値が変更されていれば、ConfigMapの更新は完了しています。
変更後の値をPodに反映するため、Deploymentを再起動し、Podを再作成します。
# Deploymentを再起動し、ConfigMap変更後の値を読み込むPodを再作成する kubectl rollout restart deployment/config-secret-app -n config-secret-test
ロールアウトの状態を確認します。
# Deploymentのロールアウトの状態確認をする $ kubectl rollout status deployment/config-secret-app -n config-secret-test deployment "config-secret-app" successfully rolled out
Podが再作成されたことを確認します。
# Deployment再起動後に作成されたPodの状態を確認する $ kubectl get pods -n config-secret-test NAME READY STATUS RESTARTS AGE config-secret-app-674648df4c-l42rd 1/1 Running 0 3m42s
再作成されたPod内で、環境変数を確認します。
# 再作成後のPod名を取得し、変数を更新する
POD_NAME=$(kubectl get pods -n config-secret-test -l app=config-secret-app -o jsonpath='{.items[0].metadata.name}')
# 再作成後のPodで、ConfigMapの変更後の値が反映されているか確認する $ kubectl exec -it $POD_NAME -n config-secret-test -- printenv | grep -E 'APP_ENV|APP_MESSAGE' APP_ENV=stg APP_MESSAGE=Updated from ConfigMap
変更後のConfigMapの値が表示されました。
これにより、環境変数として参照しているConfigMapは、ConfigMapの値を変更しただけでは既存Podに即時反映されず、Podを再作成することで変更後の値が反映されることを確認できました。
これで、ConfigMapとSecretを環境変数としてPodに渡す構成と、ConfigMap変更後にPodを再作成して値を反映する流れを確認できました。
後片付け
検証が完了したため、作成したKubernetesリソースを削除します。
今回は検証用Namespace内にConfigMap、Secret、Deployment、Podを作成しているため、Namespaceを削除することでまとめて削除できます。
# 検証用Namespaceを削除し、関連するConfigMap、Secret、Deployment、Podもまとめて削除する kubectl delete namespace config-secret-test
まとめ
本記事では、EKS上でConfigMapとSecretを使用し、アプリケーション設定を管理する構成を構築しました。
ConfigMapには通常の設定値、Secretには機密情報を想定した値を定義し、Deploymentから環境変数として参照させることで、Pod内のコンテナから設定値を利用できることを確認しました。
アプリケーションの設定値をコンテナイメージから分離することで、環境ごとの設定変更や、設定値の管理をKubernetesリソースとして扱いやすくなります。
また、ConfigMapを環境変数として参照している場合、ConfigMapの値を変更しただけでは既存Pod内の環境変数には即時反映されないため、Podの再作成が必要になることも確認しました。
実運用でSecretを扱う場合は、値の管理方法やアクセス権限、ログへの出力有無などに注意が必要です。
EKS上でアプリケーションを運用する際は、ConfigMapとSecretを活用することで、設定値をコンテナイメージと分けて管理する構成を検討できます。




