はじめに
アプリケーションでは、パスワード、トークン、データベースの認証情報など、コンテナイメージやプレーンテキストのマニフェストに直接記述すべきではない値を扱うことがよくあります。Kubernetes の Secret は、こうした機密性の高い設定を独立したオブジェクトとして保存し、Pod の起動時にそれを利用できるようにします。
この実験では、Secret の作成、エンコードされたデータの慎重な確認、アプリケーション Pod への接続、Secret の更新、そしてアプリケーションが新しい値を読み込めるようにするための Pod の再作成を行います。この実験では、Secret の基本的なワークフローに焦点を当てます。後の実験では、環境変数の詳細な設定やファイルベースの設定マウントについて学習します。
Secret 実践用の名前空間を準備する
このステップでは、Secret の練習用にクリーンな名前空間を準備します。
/home/labex/project から開始します。このディレクトリ内に Pod のマニフェストを 1 つ作成します。
mkdir -p /home/labex/project
cd /home/labex/project
Kubernetes API サーバーに接続できるか確認します。VM が起動した直後でノードの準備ができていない場合は、数秒待ってから再度コマンドを実行してください。
kubectl get nodes --request-timeout=5s
期待される出力例:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
アプリケーションオブジェクトを作成する前に、クラスターのネットワーク Pod が「Ready」状態になるまで待ちます。
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
期待される出力:
pod/calico-node-... condition met
ckad-prep-secrets という名前の名前空間を作成します。
kubectl create namespace ckad-prep-secrets
この名前空間を現在のコンテキストの名前空間として設定します。
kubectl config set-context --current --namespace=ckad-prep-secrets
現在の名前空間を確認します。
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
期待される出力:
ckad-prep-secrets
Secret の作成と確認
このステップでは、小規模なアプリケーション用のデータベース接続設定を保存する Secret を作成します。
kubectl create secret generic コマンドは、不透明(Opaque)な Secret を作成します。generic は、Kubernetes がキーに対して特別な組み込みの意味を割り当てないことを意味します。各 --from-literal フラグは、Secret に 1 つのキーと値のペアを追加します。
kubectl create secret generic db-credentials \
--from-literal=DB_USER=orders-app \
--from-literal=DB_PASSWORD=dev-password-123 \
--from-literal=DB_NAME=orders
期待される出力:
secret/db-credentials created
Secret の概要を確認します。
kubectl get secret db-credentials
期待される出力:
NAME TYPE DATA AGE
db-credentials Opaque 3 ...
Secret を YAML 形式で表示します。Kubernetes は data フィールド内の値を base64 エンコードされた文字列として保存するため、この出力で元のパスワードがそのまま見えることはありません。
kubectl get secret db-credentials -o yaml
期待される出力例:
data:
DB_NAME: b3JkZXJz
DB_PASSWORD: ...
DB_USER: b3JkZXJzLWFwcA==
type: Opaque
Base64 エンコーディングは暗号化ではありません。Secret オブジェクトを読み取れる権限を持つ人は誰でも値をデコードできます。ここでは、パスワードを表示せずに表現方法を確認するために、ユーザー名のみをデコードします。
kubectl get secret db-credentials -o 'jsonpath={.data.DB_USER}' | base64 --decode; echo
期待される出力:
orders-app
Secret を使用した Pod の設定
このステップでは、Secret を環境変数として読み込む Pod を起動します。
envFrom.secretRef フィールドは、Secret 内のすべてのキーをコンテナ環境にインポートします。これは前回の実験の ConfigMap パターンと似ていますが、値は Secret オブジェクトから取得されます。この Pod 内のコマンドは、ユーザー名とデータベース名を表示し、パスワードが読み込まれたことのみを確認します。パスワード自体は表示しません。
secret-reader-pod.yaml を作成します。
cat > secret-reader-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: secret-reader
labels:
app: secret-reader
spec:
terminationGracePeriodSeconds: 0
containers:
- name: reader
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo user=${DB_USER}; echo database=${DB_NAME}; if [ -n "${DB_PASSWORD}" ]; then echo password-loaded; fi; sleep 3600'
envFrom:
- secretRef:
name: db-credentials
EOF
Pod マニフェストを適用します。
kubectl apply -f secret-reader-pod.yaml
期待される出力:
pod/secret-reader created
Pod が「Ready」になるまで待ちます。
kubectl wait --for=condition=Ready pod/secret-reader --timeout=120s
期待される出力:
pod/secret-reader condition met
Pod のログを読み取ります。アプリケーションは Secret の値が利用可能であることを確認していますが、パスワードの値は表示されていません。
kubectl logs secret-reader -c reader
期待される出力:
user=orders-app
database=orders
password-loaded
Secret の更新と Pod の再作成
このステップでは、Secret を更新し、コンテナが新しい値を受け取れるように Pod を再作成します。
コンテナの環境変数は、コンテナ起動時に確定されます。Secret が環境変数として使用されている場合、Secret オブジェクトを更新しても、実行中のコンテナ内の環境変数は自動的に書き換わりません。アプリケーションが更新された Secret の値を読み込む必要がある場合は、新しい Pod を起動する必要があります。
新しいアプリケーションユーザーとパスワードで Secret にパッチを適用します。
kubectl patch secret db-credentials --type merge --patch '{"stringData":{"DB_USER":"orders-worker","DB_PASSWORD":"rotated-password-456","DB_NAME":"orders"}}'
期待される出力:
secret/db-credentials patched
DB_USER のみをデコードして、更新されたユーザー名を確認します。
kubectl get secret db-credentials -o 'jsonpath={.data.DB_USER}' | base64 --decode; echo
期待される出力:
orders-worker
古い Pod を削除します。
kubectl delete pod secret-reader
期待される出力例:
pod "secret-reader" deleted
同じマニフェストから Pod を再作成し、「Ready」になるまで待ちます。
kubectl apply -f secret-reader-pod.yaml
kubectl wait --for=condition=Ready pod/secret-reader --timeout=120s
期待される出力:
pod/secret-reader created
pod/secret-reader condition met
再度ログを読み取ります。新しい Pod は Secret から更新されたユーザー名を参照しており、パスワードの生値をログに出力することなく動作しています。
kubectl logs secret-reader -c reader
期待される出力:
user=orders-worker
database=orders
password-loaded
まとめ
Kubernetes Secret を作成し、エンコードされたデータを確認し、非機密キーをデコードして表現方法を理解しました。また、Secret をアプリケーション Pod に接続し、Secret 更新後に Pod を再作成する手順を学びました。さらに、機密設定を扱う際の重要な習慣として、パスワードの値をログに出力することなく、アプリケーションが正しくパスワードを受け取ったことを検証する方法を実践しました。


