第12章:Secretの扱い方(やりすぎない安全)🔐✨
この章は「事故りやすい“秘密情報”を、ちゃんと扱えるようになる」がゴールです💪 (パスワード・APIキー・トークンなど🗝️)
1) まず大事な現実チェック👀💥
Secretは“魔法の金庫”ではないです😇➡️😈 Secretの値は base64でエンコードされているだけで、デフォルトでは暗号化されずに保存されます。(Kubernetes) なので「Secretに入れた=安全」ではなく、置き方・渡し方・権限がセットで大事になります🔐
さらにクラスタ側の話として、KubernetesのAPIサーバはデフォルトだと etcd に 平文のまま保存します(= at-rest暗号化なし)。(Kubernetes) 👉 本番では「暗号化 at rest を有効化する」方向が基本になります。(Kubernetes)
2) SecretとConfigMapの違いを1分で🧠⚡
- ConfigMap:秘密じゃない設定(例:ログレベル、機能フラグ)🧩
- Secret:秘密の設定(例:DBパスワード、APIキー)🔑
この切り分け自体が、設計の第一歩です🧹✨(Kubernetes)
3) “やりすぎない安全”のルール8️⃣📏🔐
-
Gitに生のSecretを置かない(base64でも同じ😇)(Kubernetes)
-
Secretを使っても、アプリ側でログに出したら終わり(絶対出さない!)🪦(Kubernetes)
-
Podに渡す方法は2つ:
- 環境変数(簡単)🌱
- ファイル(volume)(更新に強い)📁
-
環境変数で渡したSecretは、更新しても自動でアプリに反映されない(Pod再起動が必要)🔁(Kubernetes)
-
ファイルでマウントしたSecretは、更新が“遅れて”反映される(eventually-consistent)⏳(Kubernetes)
-
subPathマウントだと自動更新されない(地雷⚠️)(Kubernetes)
-
変更事故が怖いなら immutable を検討(更新不可にして守る)🧱(Kubernetes)
-
本番は「誰が読めるか(権限)」と「保存の暗号化」をセットで🔐
- at-rest暗号化の考え方は公式でも推奨です。(Kubernetes)
4) ハンズオン🎮:DBパスワードをSecretで注入する(env版→file版)
ここでは、既にあるNode/TS API(Deployment)に DB_PASSWORD を注入します🍔 ※値はダミーでOKです🙆
4-1) Secretを作る(まずはCLIで)⌨️🔐
PowerShellで例(そのままOK)👇
kubectl create namespace demo
kubectl -n demo create secret generic app-secrets --from-literal=DB_PASSWORD="demo-password-123"
作れたか確認👇(中身は見なくてOK!)👀
kubectl -n demo get secret app-secrets
⚠️
kubectl get secret app-secrets -o yamlは、見ようと思えば見えます(base64なだけ)なので、むやみにやらないのが吉です🫠(Kubernetes)
4-2) Deploymentに“環境変数”として渡す🌱🔗
Deploymentの該当コンテナに、これを足します👇
## (Deploymentの spec.template.spec.containers[0] あたり)
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: DB_PASSWORD
反映👇
kubectl -n demo apply -f .\k8s\deployment.yaml
kubectl -n demo rollout status deploy/<あなたのDeployment名>
値を表示せずに「入ったかだけ」確認するのが安全です🧯 (例:長さだけ見る)
kubectl -n demo exec deploy/<あなたのDeployment名> -- node -e "console.log((process.env.DB_PASSWORD||'').length)"
4-3) 次に“ファイル(volume)”で渡す📁🔐(こっちが更新に強い)
Deploymentに追記👇
## containers[0]
volumeMounts:
- name: secret-vol
mountPath: /run/secrets
readOnly: true
## spec.template.spec
volumes:
- name: secret-vol
secret:
secretName: app-secrets
反映👇
kubectl -n demo apply -f .\k8s\deployment.yaml
kubectl -n demo rollout status deploy/<あなたのDeployment名>
ファイルができたか確認👇(値は見ない!)
kubectl -n demo exec deploy/<あなたのDeployment名> -- node -e "const fs=require('fs'); console.log(fs.existsSync('/run/secrets/DB_PASSWORD'))"
5) Secret更新(ローテーション)を体感する🔄🧪
5-1) Secretを更新する✍️
kubectl -n demo create secret generic app-secrets --from-literal=DB_PASSWORD="rotated-456" --dry-run=client -o yaml | kubectl apply -f -
5-2) env版の挙動:自動では変わらない😵💫
環境変数に入ったSecretは、Podを再起動しないと反映されません。(Kubernetes) なので運用では、Secret更新したら rollout restart とセットにするのが分かりやすいです🔁
kubectl -n demo rollout restart deploy/<あなたのDeployment名>
kubectl -n demo rollout status deploy/<あなたのDeployment名>
5-3) file版の挙動:遅れて反映されうる⏳
volumeのSecretは、Secret更新後に eventually-consistent で中身が更新されます。(Kubernetes) ただし subPath を使ってると自動更新されません⚠️(Kubernetes)
6) “本番っぽさ”を少しだけ足すなら🧯🏗️
A) at-rest暗号化(クラスタ側の守り)🔐🗄️
APIデータ(Secret含む)を etcd に保存する時点で暗号化する仕組みがあります。(Kubernetes) そして公式のベストプラクティスでも、Secretはデフォルト未暗号化だから設定しようと書かれています。(Kubernetes)
さらに進むと、鍵管理にKMSを使う構成もあります。Kubernetes 1.35 では KMS v2が推奨で、KMS v1はdeprecatedかつデフォルト無効です。(Kubernetes)
B) 外部の秘密管理(クラスタ外に置く)🏦🔑
「Secretをクラスタ外に置きたい」なら、外部ストアから取得してPodにマウントする方式があります。公式のベストプラクティスでも、Secrets Store CSI Driver を例に挙げています。(Kubernetes) (例えば Amazon Web Services / Microsoft Azure / Google Cloud の秘密管理サービスと組み合わせる、みたいなイメージです☁️🔐)
7) よくある事故あるある(先に潰す)💣🧯
console.log(process.env.DB_PASSWORD)しちゃった📣 → ログから漏れる(最悪)(Kubernetes)- Secretをbase64にしてGitに置いた📦 → 誰でも復元できる(暗号化じゃない)(Kubernetes)
- subPathでマウントして「更新されない…」😇 → 仕様です⚠️(Kubernetes)
- envで渡して「更新されない…」😇 → Pod再起動が必要です🔁(Kubernetes)
8) ミニ課題🎯📝
- Secretを env版 と file版 の両方で注入して、違いを説明してみてください🗣️
- Secret更新後、env版は「再起動しないと反映されない」を自分の目で確認👀(Kubernetes)
- file版は「遅れて反映される」を体感(更新直後に見にいって、ちょっと待って再確認)⏳(Kubernetes)
9) AIで楽するポイント🤖✨
- YAML貼って「Secretが漏れる設計になってない?(ログ/Repo/権限/更新)」をチェックさせる✅
- 「envとfile、どっちで渡すべき?」を 理由つき で出させる🧠
- Secret更新時の運用手順(restart含む)を チェックリスト化 させる📝
まとめ🎉
- Secretは base64であって暗号ではない。まずこの現実が重要。(Kubernetes)
- 渡し方は env(簡単) と file(更新に強い)。ただし癖あり。(Kubernetes)
- “やりすぎない安全”は、Gitに置かない / ログに出さない / 更新の挙動を理解するの3点セットでOKです🔐✨
(次章のProbeに行く前に、ここを押さえると運用っぽさが一気に増しますよ〜😎☸️)
※ 本章の参照:Kubernetes 公式ドキュメント、セキュリティのベストプラクティス、at-rest暗号化/KMSの管理者向け手順、およびSecret更新時の挙動。(Kubernetes)