1. TOP
  2. BLOG
  3. TECH ARTICLE:第19回
    Kubernetes環境変数の使用方法と
    Probeの設定方法
TECH ARTICLE

2025年04月28日

第19回
Kubernetes環境変数の使用方法と
Probeの設定方法

今回は Podの環境変数を使用する方法とSecret Fileを安全に保存するSealedSecret、 コンテナを安定的に運用するための ReadinessとLiveness Probeについて確認します。

主な実習内容:
• ConfigMapとSecretの実習
• SealedSecretの実習

1. Kubernetes ConfigMapとSecretの理解と実習

Kubernetesの ConfigMapは、アプリケーションの構成情報をコンテナイメージと分離して管理するために使用されるKubernetesの基本リソースです。環境変数、設定ファイル、コマンド等の設定データの保存に主に使用されます。

前にインストールしたArgoCDを例に確認します。

1.	$ (⎈ |switch-singapore-test:argocd) k get cm -n argocd
2.	NAME DATA AGE
3.	argocd-cm 6 31d
4.	argocd-cmd-params-cm 23 31d
5.	argocd-gpg-keys-cm 0 31d
6.	argocd-notifications-cm 1 31d
7.	argocd-rbac-cm 3 31d
8.	argocd-ssh-known-hosts-cm 1 31d
9.	argocd-tls-certs-cm 0 31d
10.	kube-root-ca.crt 1 31d

上記で ‘argocd-cmd-params-cm’ を確認すると、Argocdサーバで実行に必要な構成情報があります。

ConfigMapは、次のようにYAMLファイルで定義されます。

1.	$ (⎈ |switch-singapore-test:argocd) k get cm argocd-cmd-params-cm -oyaml
2.	apiVersion: v1
3.	data:
4.	controller.log.format: text
5.	controller.log.level: info
6.	(省略)
7.	server.basehref: /
8.	server.dex.server: https://argocd-dex-server:5556
9.	server.dex.server.strict.tls: "false"
10.	server.disable.auth: "false"
11.	server.enable.gzip: "false"
12.	server.insecure: "false"
13.	(省略)
14.	kind: ConfigMap
15.	metadata:
16.	name: argocd-cmd-params-cm
17.	namespace: argocd
18.	(省略)

定義は他のリソースと同じくapiVersion、kind、metadataとdataフィールドで構成されています。dataフィールドに Key-Value形式で必要な情報を指定します。 ConfigMapはネームスペース単位に指定し、必要なネームスペースの ConfigMap名を指定します。

Podでは環境変数にConfigMapを使用できます。

1.	$ (⎈ |switch-singapore-test:redis) k get pod -n argocd argocd-server-b694d4bc6-bxnz6 -oyaml
2.	(省略)
3.	spec:
4.	    containers:
5.	    - command:
6.	        - argocd-server
7.	        - --insecure
8.	        env:
9.	        - name: ARGOCD_SERVER_INSECURE
10.	            valueFrom:
11.	                configMapKeyRef:
12.	                    key: server.insecure
13.	                    name: argocd-cmd-params-cm
14.	                    optional: true
15.	        - name: ARGOCD_SERVER_BASEHREF
16.	            valueFrom:
17.	                configMapKeyRef:
18.	                    key: server.basehref
19.	                    name: argocd-cmd-params-cm
20.	                    optional: true
21.	        - name: ARGOCD_SERVER_ROOTPATH
1.	$ (⎈ |switch-singapore-test:argocd) k exec -it argocd-server-b694d4bc6-bxnz6 -- sh
2.	$ echo $ARGOCD_SERVER_INSECURE
3.	false

Podの YAMLファイルの ‘env’ に ConfigMapのキー値を指定します。この構成情報を Podで環境変数に使用します。このようにアプリケーションの構成情報をコンテナイメージと分離することで、コンテナをビルドしている最中に構成情報を変更しなくても、多様な設定でアプリケーションを実行できます。これはイメージを変更しなくても、多様な環境で実行できる重要な特徴で、環境の変更によってアプリケーションの構成を変更するために使用されます。複数のConfigMapを組み合わせてアプリケーションを簡単にカスタマイズできます。

また、 構成情報を ConfigMapに保存すると、この情報を複数のPodで共有できます。複数のPodが同じ構成情報を使用でき、中央で構成情報をアップデートすると、全てのPodに変更事項が反映されます。

管理者の立場でもConfigMapだけを確認すれば、サーバに接続しなくても構成情報を把握できるため、障害処理等が非常に容易です。

ConfigMapはボリュームディレクトリでマウントすると、使用できます。前にインストールした Redisを例に説明します。

1.	$ (⎈ |switch-singapore-test:redis) k get pod -o yaml redis-master-0 
2.	(省略)
3.	    volumeMounts:
4.	    - mountPath: /opt/bitnami/redis/mounted-etc
5.	        name: config
6.	(省略)
7.	volumes:
8.	- configMap:
9.	        defaultMode: 420
10.	        name: redis-configuration
11.	    name: config

redis-configuration名の ConfigMapを ‘/opt/bitnami/redis/mounted-etc’ のマウントポイントでボリュームに使用しています。redis-configuration ConfigMapを確認すると、Redis設定時に多く使用する redis.conf等のRedis設定関連ファイルを確認できます。

1.	apiVersion: v1
2.	data:
3.	    master.conf: |-
4.	        dir /data
5.	        # User-supplied master configuration:
6.	        rename-command FLUSHDB ""
7.	        rename-command FLUSHALL ""
8.	        # End of master configuration
9.	    redis.conf: |-
10.	        # User-supplied common configuration:
11.	        # Enable AOF https://redis.io/topics/persistence#append-only-file
12.	        appendonly yes
13.	        # Disable RDB persistence, AOF persistence already enabled.
14.	        save ""
15.	        # End of common configuration
16.	    replica.conf: |-
17.	        dir /data
18.	        # User-supplied replica configuration:
19.	        rename-command FLUSHDB ""
20.	        rename-command FLUSHALL ""
21.	        # End of replica configuration

上記の設定では helm values.yamlに指定された値が使用されます。

Volumeで使用した ConfigMapは環境変数で設定した場合と異なり、Podを再開しなくても変更が適用されるという違いがあります。

このようにConfigMapはアプリケーションの構成情報を分離して管理を簡単にし、アプリケーションの柔軟性を高め、構成情報を中央に置くことで複数のPodで共有できるようにします。

次に、Kubernetesの Secretは、構成情報の中で敏感なデータ(例:パスワード、トークン、認証情報等)を安全に保存し、管理するために使用されるKubernetesの基本リソースです。Secretは ConfigMapと同様に、アプリケーションの構成情報をコンテナイメージと分離して管理できます。また、 Secretは base64でエンコードして保存するため、より高いセキュリティーレベルを提供します。

しかし、Secretはbase64でエンコードしても露出する可能性があるので、secret情報を GitHub等には絶対に公開しないでください。Secretはその名称と異なり安全ではないため、露出しないように注意が必要です。

Secretの特徴をまとめると次の通りです。

敏感なデータの保護
パスワード、トークン、認証情報のような敏感なデータを平文でコンテナイメージに含まないように、安全に保存して使用します。

セキュリティーの強化
Secretは Base64でエンコードして、保存され、データは暗号化されるため、より高いセキュリティーレベルを提供します。

環境構成による分離
互いに異なる環境(例: 開発、テスト、プロダクション)では、異なるセキュリティー情報で構成を分離します。

SecretもKubernetesリソースで YAMLファイルで生成します。先ず、必要な情報を base64でエンコードします。

1.	$ (⎈ |switch-singapore-test:redis) echo -n "admin"|base64
2.	YWRtaW4=
3.	
4.	$ (⎈ |switch-singapore-test:redis) echo -n "password"|base64
5.	cGFzc3dvcmQ=

echo -nオプションを追加してnewline(/n)を含まないようにエンコードし、このエンコード情報で Secretファイルを生成します。

下記は Secretファイルの例です。

secret.yaml

1.	apiVersion: v1
2.	kind: Secret
3.	metadata:
4.	    name: my-secret
5.	    namespace: default
6.	type: Opaque
7.	data:
8.	    username: YWRtaW4= # "admin"のBase64エンコーディング結果
9.	    password: cGFzc3dvcmQ= # "password"の Base64エンコーディング結果

上記のファイルでリソースを生成すると、次のような Secretリソースになります。

1.	$ (⎈ |switch-singapore-test:default) k apply -f secret.yaml 
2.	secret/my-secret created
3.	
4.	$ (⎈ |switch-singapore-test:default) k get secrets my-secret 
5.	NAME TYPE DATA AGE
6.	my-secret Opaque 2 10s

GitOpsで管理するとGitに Secretファイルを共有できますが、この重要な情報は簡単に露出します。

1.	$ (⎈ |switch-singapore-test:default) echo -n cGFzc3dvcmQ= |base64 -d
2.	password%

Private GitレポジトリでもローカルにGitソースをダウンロードできます。外部の会社と協力する場合もあるため注意が必要で、平文でGitに重要な情報をアップロードすることと同じです。より安全に重要な情報を保存する方法が必要です。

2. Secretを安全に保存する Sealed Secretの実習

Secretを安全に保存する方法としてVault、External Secrets Operator、Sealed Secretsが使用できます。その中でKubernetesとの統合など相性がよく、使用が簡単なSealed Secretsを実習で確認します。

簡単にSealed Secretsの構成を確認します。

https://docs.bitnami.com/tutorials/sealed-secretsから出典

一般にSecretは Base64でエンコードされて、Sealed Secretsはデータを暗号化して保存します。暗号化されたデータはクラスター内部のコントローラーでのみデコードできる片方向のデータのため、外部に公開しても安全です。既存のSecretリソースは Gitに情報を共有することはできませんが、Sealed Secretは暗号化されているため、Gitで共有しても問題ありません。開発者は既存の暗号化されていないSecretリソースを使用する場合と同じように使用できるため、他のツールと比べて便利です。

簡単に使用方法を整理します。

① ローカル PCと遠隔 Kubernetesクラスターにkubesealと Sealed Secret Controllerをインストールします。
② Secretデータを暗号化するために Sealed Secret Controllerの公開キーをローカルにコピーします。
③ 暗号化されたデータを生成して、このデータでSealed Secret CRDマニフェストを生成します。
④ Sealed Secretリソースは自動的に同じ名前の Secretリソースを生成して、ユーザは暗号化前と同様に Secretリソースを使用します。
⑤ 遠隔 Gitソースに安全な Sealed Secret CRDを同期化して管理します。

次は実習で確認します。

先ず、ローカル PCとクラスターにSealed Secretをインストールします。ローカル PCに一般のSecretを暗号化する kubeseal ツールをインストールします。

1.	$ (⎈ |switch-singapore-test:redis) brew install kubeseal

次に、Kubernetesクラスターにsealed-secrets controllerを helmでインストールします。

1.	$ (⎈ |switch-singapore-test:redis) helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
2.	$ (⎈ |switch-singapore-test:redis) helm pull sealed-secrets/sealed-secrets --version 2.10.0
3.	$ (⎈ |switch-singapore-test:redis) tar xvfz sealed-secrets-2.10.0.tgz 
4.	$ (⎈ |switch-singapore-test:redis) rm -rf sealed-secrets-2.10.0.tgz 
5.	$ (⎈ |switch-singapore-test:redis) mv sealed-secrets sealed-secrets-2.10.0
6.	$ (⎈ |switch-singapore-test:redis) cd sealed-secrets-2.10.0 
7.	$ (⎈ |switch-singapore-test:redis) mkdir ci 
8.	$ (⎈ |switch-singapore-test:redis) cp values.yaml ci/my-values.yaml

Valuesファイルは基本設定を変更しないでインストールします。 helm installコマンドで、ローカルでインストールできますが、GitOpsポリシーを維持するために ArgoCDでインストールします。 ArgoCD Applicationのyamlファイルは以下の通りです。

sealed-secrets-application.yaml

1.	apiVersion: argoproj.io/v1alpha1
2.	kind: Application
3.	metadata:
4.	    name: sealed-secrets
5.	    namespace: argocd
6.	    finalizers:
7.	    - resources-finalizer.argocd.argoproj.io
8.	spec:
9.	    destination:
10.	        namespace: kube-system
11.	        server: {{ .Values.spec.destination.server }}
12.	    project: default
13.	    source:
14.	        path: sealed-secrets-2.10.0
15.	        helm:
16.	            valueFiles:
17.	            - ci/singapore-test-values.yaml
18.	        repoURL: {{ .Values.spec.source.repoURL }}
19.	        targetRevision: {{ .Values.spec.source.targetRevision }}
20.	    syncPolicy:
21.	        automated:
22.	            prune: true
23.	            selfHeal: true
24.	        syncOptions:
25.	        - CreateNamespace=true
26.	        - RespectIgnoreDifferences=true

ArgoCD Applicationファイルを生成します。

1.	$ (⎈ |switch-singapore-test:redis) k apply -f sealed-secrets-application.yaml 

ArgoCDで配布状況を確認します。

kube-systemネームスペースにsealed-secrets controllerがインストールされました。

1.	$ (⎈ |switch-singapore-test:kube-system) k get pod -n kube-system sealed-secrets-5fcf64df9d-xnw9v 
2.	NAME READY STATUS RESTARTS AGE
3.	sealed-secrets-5fcf64df9d-xnw9v 1/1 Running 0 63s

次は、クライアントとサーバで Sealed Secretsを使用する準備をします。Sealed Secretesを使用するには、ローカル PCでkubesealコマンドを使用して、暗号化されたSecretを生成します。先ず、データを暗号化するためには、Sealed Secret Controllerの認証証明書をローカル PCに保存します。認証証明書はSealed Secretの Secretリソースに保存されています。

1.	$ (⎈ |switch-singapore-test:default) k get secrets -n kube-system sealed-secrets-keywwwh4
2.	NAME TYPE DATA AGE
3.	sealed-secrets-keywwwh4 kubernetes.io/tls 2 4h37m

Secretリソースの認証証明書 (tls.crt) データを使用するためにデコード (view-secret)し、Exportして、ローカルファイルに保存します。デコードコマンド(base64 -d)ではなく、k view-secretコマンドでできます。

1.	$ (⎈ |switch-singapore-test:default) k view-secret -n kube-system sealed-secrets-keywwwh4 tls.crt
2.	-----BEGIN CERTIFICATE-----
3.	MIIEzTCCArWgAwIBAgIRAPIshqc93BboOE3wcaUBdK0wDQYJKoZIhvcNAQELBQAw
4.	(省略)
5.	
6.	
7.	$ (⎈ |switch-singapore-test:default) k view-secret -n kube-system sealed-secrets-keywwwh4 tls.crt > ~/my-tls.crt 
8.	
9.	$ (⎈ |switch-singapore-test:default) ls ~/my-tls.crt 
10.	/Users/jerry/my-tls.crt

認証証明書で暗号化されたファイルを生成します。暗号化するデータと Secret名、ネームスペースを指定して暗号化されたRawデータを kubeseal –rawオプションで生成します。

1.	$ (⎈ |switch-singapore-test:default) echo -n password |kubeseal --raw --cert ~/my-tls.crt --namespace default --name sealed-secret
2.	AgAMmdw96eh/Yu4cXY+aTfXRZDL2tgwVMlqR3cchMp6no3rDoxnp3C2UkQiUBwyhzU+50pAcjO9RldOBofmPyAtRblXwt/(省略)

生成した暗号化データで SealedSecret CRDリソースを生成します。 SealedSecretリソースは、 Sealed Secret Controllerで管理され、暗号化されたデータでKubernetes Secretリソースを生成します。下記の YAMLファイルで生成します。

1.	apiVersion: bitnami.com/v1alpha1
2.	kind: SealedSecret
3.	metadata:
4.	    name: sealed-secret
5.	    namespace: default
6.	spec:
7.	    encryptedData:
8.	        PostgreSQL_PASSWORD: AgAMmdw96eh/Yu4cXY+aTfXRZDL2tgwVMlqR3cchMp6no3rDoxnp3C2UkQiUBwyhzU+50pAcjO9RldOBofm(省略)

SealedSecret マニフェストを適用するとsealedsecret CRDが生成されます。

1.	$ (⎈ |switch-singapore-test:default) k apply -f SealedSecret.yaml 
2.	sealedsecret.bitnami.com/sealed-secret created
3.	
4.	$ (⎈ |switch-singapore-test:default) k get sealedsecrets.bitnami.com 
5.	NAME STATUS SYNCED AGE
6.	sealed-secret True 14s

すると、自動的に同じ名前 (sealed-secret)の secretリソースが確認できます。

1.	$ (⎈ |switch-singapore-test:default) k get secrets sealed-secret 
2.	NAME TYPE DATA AGE
3.	sealed-secret Opaque 1 44s

詳細に見ると、Secretリソースは SealedSecret CRDが管理するという説明が確認できます。即ち、 Secretリソースを直接生成せず、SealedSecretで生成しました。

1.	$ (⎈ |switch-singapore-test:default) k get secrets sealed-secret -oyaml
2.	(省略)
3.	metadata:
4.	    name: sealed-secret
5.	    namespace: default
6.	    ownerReferences:
7.	    - apiVersion: bitnami.com/v1alpha1
8.	        controller: true
9.	        kind: SealedSecret
10.	        name: sealed-secret
11.	        uid: 8c8a95c8-8152-44ed-a16c-c2e3fdfb4652

SealedSecret Controller Podのログを確認すると、下記のように SealedSecretリソースが unsealed作業を行ったことを確認できます。もし、Secret関連エラーが発生すると、Podのログを確認する必要があります。

1.	$ (⎈ |switch-singapore-test:default) k -n kube-system logs sealed-secrets-controller-68b68d6866-7m799
2.	(省略)
3.	Event(v1.ObjectReference{Kind:"SealedSecret", Namespace:"default", Name:"sealed-secret", UID:"8c8a95c8-8152-44ed-a16c-c2e3fdfb4652", APIVersion:"bitnami.com/v1alpha1", ResourceVersion:"23261565", FieldPath:""}): type: 'Normal' reason: 'Unsealed' SealedSecret unsealed successfully
4.	WARNING: Empty API version & kind, filling it...
5.	update suppressed, no changes in sealed secret spec of default/sealed-secret

このように SealedSecretリソースでSecretリソースを生成できます。Git上の安全ではない Secretリソースを削除することで、暗号化されたSealedSecretマニフェストを安全に共有できます。

3. Readiness と Liveness Probeの設定

Kubernetesで実行中のアプリケーションの安定性を向上させるために使用する Probeを確認します。

ReadinessとLiveness Probeは Kubernetesでコンテナの状態を確認し、モニタリングするために使用します。この Probeはコンテナの準備状態と生存状態を検査し、アプリケーションの安定性と可用性を維持する時に役に立ちます。

Readiness Probeはコンテナが開始後、 リクエストを処理する準備ができたかを確認する時に使用されます。もし、 Readiness Probeが失敗すると、EndPointでPodが除外され、そのPodはトラフィックが伝達できません。主にアプリケーションが開始後に正常に初期化されたか、外部サービスとコネクションが可能かを確認する時に使用されます。DBとのコネクションが正常になり、サービスが開始する時に多く使用されます。

もし、 Readiness Probeが失敗すると、Podはトラフィックを受信しないので、ロードバランサー又はサービスディスカバリーメカニズムでその Podを除外します。これは一時的なエラー、初期化が完了する前のトラフィックを受けつけない時に有用です。

Liveness Probeはコンテナが実行中であり、コンテナが正常な状態であるかを確認する時に使用されます。アプリケーションが実行中に予想外のエラーにより正常な状態ではない場合、Liveness Probeが失敗してコンテナが再度開始できるように誘導します。 Podが実行できるが、正常なトラフィック処理を行えないHang 状態で、Podを自動で再開する時に非常に有用です。

MariaDB等ほとんどのApplication設定には、下記のように Liveness、Readiness Probe設定を含めています。Kafka、Redis、Prometheus、ArgoCD等も同じです。筆者も運用中の独自開発のアプリケーションにProbeを含むように開発担当者に指導しています。

実際にMariaDBで使用する Probeの事例です。

1.	$ (⎈ |alooo:mariadb) k get pod mariadb-mariadb-galera-0 -oyaml
2.	(省略)
3.	    livenessProbe:
4.	        failureThreshold: 3
5.	        httpGet:
6.	            path: /
7.	            port: metrics
8.	            scheme: HTTP
9.	        initialDelaySeconds: 30
10.	        periodSeconds: 10
11.	        successThreshold: 1
12.	        timeoutSeconds: 5
13.	(省略)
14.	    readinessProbe:
15.	        failureThreshold: 3
16.	        httpGet:
17.	            path: /
18.	            port: metrics
19.	            scheme: HTTP
20.	        initialDelaySeconds: 5
21.	        periodSeconds: 10
22.	        successThreshold: 1
23.	        timeoutSeconds: 1

アプリケーションの状況により Probeオプションを別途構成します。

failureThreshold
Probeが成功せず、その後でコンテナの失敗が確定する前に許容される最大連続失敗回数を指定します。デフォルトは3回です。つまり、3回連続で失敗した場合、Probeは失敗と見做されます。

httpGet
Probeを検証する方法で、httpGetだけでなく tcp、command、grpc等が使用できます。

initialDelaySeconds
コンテナが開始後、 Probeを開始するまでの待機時間を指定します。つまり、コンテナが開始して、指定された時間(秒)以降に Probeが実行されます。起動時間が必要なアプリケーションはこのオプションを 180s(3分)程度に指定する場合もあります。

periodSeconds
Probeが実行される周期を指定します。つまり、Probe実行間の時間間隔を指定します。

successThreshold
コンテナの成功を確認する前に必要な最少の連続成功回数を指定します。デフォルト値は1回で、 1回成功すると、 Probeは成功と見做されます。

timeoutSeconds
Probeが応答を待つ最大時間を指定します。つまり、Probeが指定された時間(秒)を待って応答がないと、Probeは失敗と見做されます。

このように Probeのオプションを適切に設定して、アプリケーションの状態を正確にモニタリングし、エラーを迅速に検知することは、サービスの可用性と安定性を維持する時に役に立ちます。

その他のStartup Probeは Kubernetes 1.16バージョンからサポートする新しいタイプのProbeで、 アプリケーションの初期化ステップをモニタリングするために使用されます。Startup Probeはコンテナが開始して初期化を完了するまでの間でのみ動作します。主にデータベースのようなバックエンドサービスを初期化する時に長い時間がかかる場合に使用します。

以上で Kubernetes環境で環境変数と Probeの使用方法を確認しました。


注1. Hashcorp Vault: https://www.vaultproject.io/
注2. External Secrets Operator : https://external-secrets.io/v0.8.5/
注3.Sealed Secrets : https://github.com/bitnami-labs/sealed-secrets
注4. 暗号化されたSealed Secret生成方法 : https://github.com/bitnami-labs/sealed-secrets#raw-mode-experimental

お気軽にお問い合わせください

製品に関する事やご不明な点など、お気軽にご相談ください。
また、ジェニファーソフトでは2週間の無償トライアルを提供しています。

詳しく知りたい方は
導入や費用のご相談は