Quick start: 5分で最初のシークレットを暗号化する
百聞は一見に如かず。4つのシンプルなステップで、実際にシークレットを暗号化してクラスターへ適用してみましょう。
ステップ 1: Sealed Secrets Controllerのインストール
コントローラーはクラスター内でバックグラウンド実行され、復号処理を担当します。以下の2つのコマンドでv0.24.5をデプロイします。
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.5/controller.yaml
kubectl rollout status deployment sealed-secrets-controller -n kube-system
10〜20秒ほど待ちます。PodがRunning状態になると、コントローラーは初回用の4096-bit RSAキーペアを自動生成します。
ステップ 2: ローカル環境へのkubeseal CLIのインストール
kubesealはクライアント側のツールです。コードをコミットする前にシークレットを暗号化することが唯一の役割です。
Linuxの場合:
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.5/kubeseal-0.24.5-linux-amd64.tar.gz
tar -xvzf kubeseal-0.24.5-linux-amd64.tar.gz
sudo install -m 755 kubeseal /usr/local/bin/kubeseal
macOSの場合は、brew install kubesealを実行するだけです。
ステップ 3: シークレットの作成と暗号化(Seal)
例として、ユーザー名と16文字のパスワードを含むPostgreSQLの認証情報を作成してみましょう。
# 1. dry-runモードで未暗号化のシークレットマニフェストを作成
kubectl create secret generic db-credentials \
--from-literal=username=postgres \
--from-literal=password='kX9#mP2$vL8@qR5!' \
--dry-run=client -o yaml > secret-raw.yaml
# 2. kubesealを使用してSealedSecretへ暗号化
kubeseal -f secret-raw.yaml -o yaml > sealedsecret.yaml
# 3. 誤コミットを防ぐため、元のrawファイルを即座に削除
rm -f secret-raw.yaml
ステップ 4: クラスターへの適用と動作検証
暗号化されたファイルをクラスターに適用します。
kubectl apply -f sealedsecret.yaml
# コントローラーによって生成された通常のSecretを確認
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d
復号されたパスワードが元の値と完全に一致することが確認できます。これでsealedsecret.yamlはGitHubやGitLabへ安全にプッシュできるようになりました。あわせてCI/CDパイプラインのシークレット管理も見直すことで、リポジトリ全体のセキュリティをより強固に保てます。
問題の本質:標準のKubernetes Secretはなぜ脆弱なのか?
Kubernetesセキュリティの初学者の多くは、Secretがセキュアであると誤解しがちです。しかし、現実は異なります。
Kubernetes Secretのデータは、単にBase64でエンコードされているに過ぎません。Base64はバイナリデータを文字列に変換するためのフォーマット変換であり、暗号化やセキュリティ保護の機能はありません。マニフェストファイルを開けば、誰でも1秒以内に平文へデコードできてしまいます。このようなリスクを排除するには、Kyvernoによるセキュリティ自動化でマニフェストの適用ポリシーを厳格化するのも効果的です。
GitOpsが抱える難題
GitOpsを採用する場合、すべてのマニフェストをGitリポジトリで管理する必要があります。Gitこそがシステム全体の状態に対する「信頼できる唯一の情報源(Single Source of Truth)」となるためです。
ここで大きなジレンマが生じます。平文のシークレットをGitにコミットするのは極めて危険です。一方で、クラスター外でシークレットを手動設定すると、GitOpsの一貫性が崩れてしまいます。HashiCorp Vaultの導入を選択するチームも多いですが、Vaultは強力である反面、リソース消費量が多く運用も複雑なため、中小規模のシステムではオーバーヘッドが大きくなりがちです。
Sealed Secretsによるアプローチ
Bitnami Sealed Secretsは、非対称暗号(公開鍵暗号方式)を採用し、明確な役割分担を実現しています。
- Public Key(公開鍵): コントローラーが自動生成し、すべての開発者に公開されます。この鍵をローカルに取得してシークレットをカスタムリソース
SealedSecretに暗号化します。この鍵は「施錠」専用であり、逆方向に復号することはできません。 - Private Key(秘密鍵):
kube-system名前空間内に安全に保管され、コントローラーのみがアクセス権限限を持ちます。Git経由でSealedSecretがデプロイされると、コントローラーがそれを検知して自動復号し、Podが利用可能なネイティブのK8s Secretを生成します。
万が一Gitリポジトリ全体が攻撃者に漏洩しても、暗号化された無意味な文字列(暗号文)しか見えません。
実践運用:スコープ制御と秘密鍵のバックアップ戦略
1. スコープ(Scope)による暗号化制御
デフォルトでは、kubesealはstrictスコープを使用します。これは、シークレットが最初に指定されたリソース名と名前空間に厳密にバインドされることを意味します。仮にYAMLファイル内の名前空間が改ざんされた場合、コントローラーは即座に復号を拒否します。
設計要件に応じて、以下の3つのスコープから選択できます。
- Strict(デフォルト): シークレット名と名前空間の完全一致を要求します。本番環境(プロダクション)に最適です。
- Namespace-wide: 同一名前空間へのデプロイであれば、シークレット名の変更を許可します:
kubeseal --scope namespace-wide -f secret-raw.yaml -o yaml > sealedsecret.yaml - Cluster-wide: クラスター内のあらゆる名前空間で復号を許可します。Docker Registryの共通認証情報などに適しています:
kubeseal --scope cluster-wide -f secret-raw.yaml -o yaml > sealedsecret.yaml
2. ディザスタリカバリ計画:秘密鍵を絶対に失わないために
秘密鍵の喪失は、すべてのシークレットの喪失を意味します。クラスター障害が発生してゼロから再構築する場合、Git上にある何百ものSealedSecretファイルを二度と復号できなくなってしまいます。
インストール直後に、必ずコントローラーの鍵をバックアップしてください。
kubectl get secret -n kube-system \
-l sealedsecrets.bitnami.com/sealed-secrets-key \
-o yaml > master-sealed-secrets-key.yaml
このバックアップファイルをチームのパスワード管理ツール(1PasswordやBitwarden Vaultなど)に安全に保管します。クラスター復旧時は、先にこのシークレットを適用するだけで済みます。
kubectl apply -f master-sealed-secrets-key.yaml
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.5/controller.yaml
コントローラーが既存の鍵を自動認識し、Git上の全データを通常通り復号します。ファイルを再暗号化する必要は一切ありません。
本番運用における3つの重要ポイント
- 鍵のローテーション(Key Rotation)の把握: デフォルトでは30日ごとに新しいキーペアが自動生成されます。過去の鍵も保持されるため既存のシークレットは引き続き復号可能ですが、ローテーションが行われるたびにバックアップスクリプトを再実行し、有効な秘密鍵をすべて網羅しておくことが推奨されます。
- Gitleaksによるシークレット漏洩防止:
gitleaksやtrufflehogをpre-commit hookに導入します。開発者が誤って未暗号化のsecret-raw.yamlをリモートリポジトリへコミットする事故を未然に防止できます。 - ArgoCD / FluxCDとの統合:
SealedSecretは標準的なKubernetes CRDです。ArgoCDは追加プラグインなしでネイティブに検知・同期します。Sealed Secretsコントローラーとのリソース所有権の競合を防ぐため、生成される通常のSecretを同期対象外(ignore)に設定しておくだけで問題ありません。

