# 2026年版 Kubernetesシークレット管理完全ガイド:External Secrets、Vault、面接対策 > Kubernetesのシークレット管理について、External Secrets Operator、HashiCorp Vaultとの連携、本番環境でのベストプラクティス、および技術面接での頻出質問を解説します。 - Published: 2026-09-02 - Updated: 2026-09-02 - Author: Anthony Fillion-Maillet - Tags: kubernetes, secrets, vault, devops, security - Reading time: 12 min --- Kubernetesのシークレット管理は、コンテナオーケストレーションにおいて最も重要なセキュリティ課題の一つです。ネイティブのKubernetes Secretは機密データをbase64エンコードで保存しますが、デフォルトでは保存時の暗号化が提供されません。この脆弱性は、DevOps採用面接で頻繁に問われるセキュリティリスクを生み出します。 > **面接での即答ポイント** > > Kubernetesシークレットのセキュリティについて質問された場合:ネイティブSecretはbase64エンコードであり、暗号化ではありません。本番環境では、HashiCorp VaultやAWS Secrets Managerなどの外部シークレットマネージャーが必要で、External Secrets Operator(ESO)を介して同期します。この分離により、シークレットがGitリポジトリに存在することを防ぎます。 ## ネイティブKubernetes Secretの限界 組み込みのSecretリソースは、etcdにbase64エンコードでデータを保存します。このエンコードは単一コマンドで元に戻すことができます: ```bash # decoding-secret.sh # Kubernetesシークレット値を即座にデコード kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d ``` base64は暗号化ではありません。クラスターアクセス権を持つ者であれば、シークレット値を読み取ることができます。[Kubernetesドキュメント](https://kubernetes.io/docs/concepts/configuration/secret/)では、Secretは「デフォルトでは暗号化されていない」と明記されており、保存時の暗号化を有効にすることを推奨しています。 本番デプロイメントに影響する3つの主要な制限があります: 1. **監査証跡がない**:ネイティブSecretは、誰がいつどの値にアクセスしたかのログを提供しません 2. **ローテーション機構がない**:シークレットの変更には手動介入とPodの再起動が必要です 3. **GitOpsとの非互換性**:暗号化されたシークレットをGitに保存しても、暗号化キー管理の問題が残ります ## External Secrets Operatorのアーキテクチャ External Secrets Operator(ESO)は、Kubernetesと外部シークレット管理システムを橋渡しします。2023年にCNCF Sandboxプロジェクトとしてリリースされ、2026年にはv0.10に到達しました。ESOは、AWS Secrets Manager、HashiCorp Vault、Google Secret Manager、Azure Key Vault、その他15以上のバックエンドをサポートしています。 アーキテクチャは3つのカスタムリソースで構成されます: ```yaml # secret-store.yaml # ClusterSecretStoreはVaultへの接続を定義 apiVersion: external-secrets.io/v1beta1 kind: ClusterSecretStore metadata: name: vault-backend spec: provider: vault: server: "https://vault.internal:8200" path: "secret" version: "v2" auth: kubernetes: mountPath: "kubernetes" role: "external-secrets" serviceAccountRef: name: "external-secrets" namespace: "external-secrets" ``` このClusterSecretStoreは、Kubernetesサービスアカウントトークンを使用してVaultで認証するようESOを設定します。`kubernetes`認証メソッドは、クラスターのTokenReview APIに対してサービスアカウントJWTを検証します。 ```yaml # external-secret.yaml # ExternalSecretは実際のシークレットデータを取得して同期 apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: database-credentials namespace: production spec: refreshInterval: 1h secretStoreRef: name: vault-backend kind: ClusterSecretStore target: name: db-secret creationPolicy: Owner data: - secretKey: username remoteRef: key: secret/data/production/database property: username - secretKey: password remoteRef: key: secret/data/production/database property: password ``` ESOは1時間ごとにVaultをポーリングし(`refreshInterval: 1h`)、Kubernetes Secretを自動的に更新します。`creationPolicy: Owner`は、ExternalSecretが削除されたときにSecretも削除されることを保証します。 ## HashiCorp Vault連携パターン Vaultは、動的シークレット、自動ローテーション、包括的な監査ログを提供します。[Vault Kubernetes認証ドキュメント](https://developer.hashicorp.com/vault/docs/auth/kubernetes)に記載されているKubernetes認証メソッドにより、長期間有効な認証情報を配布せずにPodが認証できます。 Vault認証のセットアップには3つのステップが必要です: ```bash # vault-k8s-auth.sh # VaultでKubernetes認証メソッドを有効化 vault auth enable kubernetes # Kubernetes APIに対してトークンを検証するようVaultを設定 vault write auth/kubernetes/config \ kubernetes_host="https://kubernetes.default.svc:443" \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt # サービスアカウントをポリシーにバインドするロールを作成 vault write auth/kubernetes/role/external-secrets \ bound_service_account_names=external-secrets \ bound_service_account_namespaces=external-secrets \ policies=readonly-secrets \ ttl=1h ``` この設定は、`external-secrets`サービスアカウントをVaultポリシーにバインドします。TTLはトークンの有効期限を制限し、再認証を強制することで、侵害されたトークンの影響範囲を縮小します。 本番デプロイメントでは、最小権限の原則に従ったポリシーが必要です: ```hcl # readonly-secrets.hcl # 特定パスへの読み取り専用アクセスを付与するVaultポリシー path "secret/data/production/*" { capabilities = ["read"] } path "secret/metadata/production/*" { capabilities = ["list"] } ``` このポリシーは、本番シークレットパスへの読み取りアクセスのみを付与します。異なる環境を管理するチームは、対応するパス制限を持つ別々のポリシーを受け取ります。 ## ダウンタイムなしのシークレットローテーション 自動ローテーションは、シークレットが陳腐化した攻撃ベクトルになることを防ぎます。ESOはKubernetes側を処理しますが、アプリケーションは再起動なしでシークレットをリロードする必要があります。 ゼロダウンタイムローテーションには2つのアプローチがあります: **ファイル監視付きボリュームマウントシークレット:** ```yaml # deployment-volume-secrets.yaml # 自動更新されるファイルとしてシークレットをマウント apiVersion: apps/v1 kind: Deployment metadata: name: api-server spec: template: spec: containers: - name: api image: api:v2.1.0 volumeMounts: - name: secrets mountPath: /etc/secrets readOnly: true volumes: - name: secrets secret: secretName: db-secret ``` Kubernetesは、kubelet同期期間内(デフォルト1分)にマウントされたシークレットファイルを更新します。アプリケーションは各データベース接続時に`/etc/secrets/password`から認証情報を読み取り、再起動なしで新しい値を取得します。 **環境変数シークレット用のReloader:** 環境変数を使用するアプリケーションにはPodの再起動が必要です。[Stakater Reloader](https://github.com/stakater/Reloader)はこれを自動化します: ```yaml # deployment-with-reloader.yaml # アノテーションはシークレット変更時にローリング再起動をトリガー apiVersion: apps/v1 kind: Deployment metadata: name: api-server annotations: reloader.stakater.com/auto: "true" spec: template: spec: containers: - name: api envFrom: - secretRef: name: db-secret ``` ReloaderはSecret更新を監視し、ローリング再起動を実行して、ローテーション中の可用性を維持します。 ## Kubernetesシークレットに関する面接質問 DevOps面接では、シークレット管理の理解を一貫してテストします。これらの質問は、ジュニアからシニアレベルまで出題されます: **Q: Kubernetes Secretが使用するエンコーディングは何ですか?なぜこれはセキュリティに不十分ですか?** Secretはbase64エンコーディングを使用しますが、これは可逆変換であり、暗号化ではありません。Secretに対する`get`権限を持つユーザーは誰でも値をデコードできます。セキュリティには、保存時の暗号化(etcd暗号化の有効化)とRBAC権限の制限が必要です。より深いKubernetesの概念については、[Kubernetes面接の基礎](/technologies/devops/interview-questions/kubernetes-basics)を参照してください。 **Q: GitOpsを使用する際、シークレットがGitリポジトリに表示されないようにするにはどうしますか?** External Secrets Operatorは、値そのものではなく、シークレットへの参照のみをGitに保存します。ExternalSecretマニフェストにはVaultまたはAWS Secrets Manager内のシークレットへのパスが含まれており、実際のシークレットがリポジトリに触れることはありません。BitnamiのSealed Secretsは、非対称暗号化を使用した代替アプローチを提供します。 **Q: SecretStoreとClusterSecretStoreの違いを説明してください。** SecretStoreは名前空間スコープです:同じ名前空間内のExternalSecretsがそれを参照できます。ClusterSecretStoreはクラスター全体のスコープです:任意の名前空間から参照できます。複数のチームが単一のVaultインスタンスを共有する場合はClusterSecretStoreを使用し、各名前空間が分離されたシークレットバックエンドを持つ場合はSecretStoreを使用します。 **Q: デプロイ後にPodがシークレットにアクセスできません。どのようにトラブルシュートしますか?** ExternalSecretのステータスから始めます: ```bash # troubleshoot-secrets.sh # ExternalSecretの同期ステータスと条件を確認 kubectl get externalsecret database-credentials -o yaml # Secretが作成されたことを確認 kubectl get secret db-secret -o yaml # 認証エラーについてESOコントローラーログを確認 kubectl logs -n external-secrets deployment/external-secrets ``` 一般的な障害には、期限切れのVaultトークン、不正なシークレットパス、ClusterSecretStoreのRBAC設定ミスがあります。 **Q: 本番環境でデータベース認証情報のシークレットローテーションをどのように処理しますか?** Vaultのデータベースシークレットエンジンは、動的で短命な認証情報を生成します。認証情報のTTLよりも短い`refreshInterval`でESOを設定します。ローテーションが必要な静的認証情報の場合、VaultのローテーションAPIとReloaderを組み合わせて、更新後にPodを再起動します。アプリケーションは、ローテーションウィンドウ中の接続失敗を適切に処理する必要があります。 ## AWS Secrets ManagerとESO AWS Secrets Manager連携には、サービスアカウント用のIAMロール(IRSA)が必要です。このパターンは静的認証情報を完全に排除します: ```yaml # aws-secret-store.yaml # IRSAを使用したAWS Secrets Manager用ClusterSecretStore apiVersion: external-secrets.io/v1beta1 kind: ClusterSecretStore metadata: name: aws-secrets spec: provider: aws: service: SecretsManager region: ap-northeast-1 auth: jwt: serviceAccountRef: name: external-secrets-sa namespace: external-secrets ``` サービスアカウントのアノテーションはIAMロールにリンクします: ```yaml # service-account-irsa.yaml # IAMロールアノテーション付きサービスアカウント apiVersion: v1 kind: ServiceAccount metadata: name: external-secrets-sa namespace: external-secrets annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/external-secrets ``` AWSは、Lambda関数を使用してSecrets Managerで作成されたシークレットを自動的にローテーションします。ESOのリフレッシュ間隔と組み合わせることで、設定されたポーリング期間内にシークレットがKubernetesに伝播します。 ## マルチクラスターシークレット同期 複数のクラスターを運用する組織には、一貫したシークレット配布が必要です。この要件に対応する2つのパターンがあります: **ClusterSecretStoreを使用したハブアンドスポーク:** すべてのクラスターが中央のVaultインスタンスに接続します。各クラスターのESOインストールは同じシークレットを参照し、Vaultが名前空間ベースのポリシーを通じてアクセス制御を処理します。 **Vault Enterpriseによるレプリケーション:** Vault Enterpriseはリージョン間のパフォーマンスレプリケーションをサポートします。各クラスターはローカルのVaultレプリカに接続し、一貫性を維持しながらレイテンシを削減します。[Vaultレプリケーションドキュメント](https://developer.hashicorp.com/vault/docs/enterprise/replication)では、ディザスタリカバリとパフォーマンスレプリケーションモードについて説明しています。 ArgoCDを使用するチームの場合、[GitOpsデプロイメントパターン](/blog/devops/argocd-gitops-kubernetes-continuous-deployment-interview-questions)の記事では、複数のクラスターにExternalSecretsをデプロイするApplicationSetsについて説明しています。 ## シークレットアクセスのためのRBAC強化 デフォルトのクラスターロールは、過度なシークレットアクセスを付与します。最小限のロールを作成してRBACを強化します: ```yaml # restricted-role.yaml # 特定の名前空間でのみシークレットアクセスを許可するロール apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: secret-reader namespace: production rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get"] resourceNames: ["db-secret", "api-key"] ``` `resourceNames`フィールドは、明示的にリストされたシークレットへのアクセスを制限します。このフィールドがないと、ロールは名前空間内のすべてのシークレットへのアクセスを付与します。 ## 結論 Kubernetesシークレット管理は、base64エンコーディングの制限を理解することから始まります。本番環境では、External Secrets Operatorを介したHashiCorp VaultまたはAWS Secrets Managerなどの外部シークレットマネージャーが必要です。 重要なポイントは次のとおりです:ネイティブSecretは暗号化を提供しない、ESOは外部バックエンドとの同期を自動化する、Vaultは動的シークレットと監査ログを提供する、そしてRBACは最小権限の原則に従って強化する必要があります。これらの概念は、DevOps面接で定期的にテストされ、クラウドネイティブ環境でのシークレット管理のベストプラクティスを形成します。 --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/ja/blog/devops/kubernetes-secrets-management-2026-external-secrets-vault-interview