GitOpsで秘匿情報を扱う方法を紹介する資料です。SealedSecretというツールを中心に紹介しますが、それ以外のkamus, Hashicorp Vault, kubesealといった多くのツールも紹介します。 @Kubernetes Meetup Tokyo #21 - Cloud Native CI/CD
GitOpsでも秘匿情報をバッチリ扱う⽅法、SealedSecretとは?Ryuichi Ito (@amaya382)@Kubernetes Meetup Tokyo #21
View Slide
GitOpsでも秘匿情報をバッチリ扱う⽅法、SealedSecretとは?Ryuichi Ito (@amaya382)@Kubernetes Meetup Tokyo #21 刺客現る!?
⾃⼰紹介• 伊藤 ⻯⼀ ( @amaya382)• さくらインターネット株式会社 技術本部• k8s使ってます• 新規サービスのバックエンド環境として• Tellusの衛星データ処理基盤として• 好きなk8sツール: telepresence• 最近作ってるk8sツール: GitOpsでCIがPullReq作るためのアレ• 技術書典7で、「kubectlが使えるようになったところから本番運⽤するために必要なことまとめ」の本書きます!!!3
対象者とゴール前提• k8s・CI/CDの基本的な概念をある程度理解している対象者• GitOpsを本格的に利⽤するために必要なことを知りたい⼈ゴール• SealedSecretを使うことでGitOpsでも秘匿情報を適切に扱えることを知る• どのような仕組みで実現されているか• どうすれば利⽤できるか• 類似ツールとの⽐較・使い分け4⾊々あります
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)5DockerRegistryアプリの更新デプロイ要求(PR作成)Hookアプリイメージ更新開発者(Dev)デプロイ実⾏(PR承認)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)6DockerRegistryアプリの更新開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール1. コードをPush (PR)
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)7DockerRegistryHook開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール2. CI動作開始
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)8DockerRegistryHook開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール2. CI動作開始2.1. テストやビルド
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)9DockerRegistryHookアプリイメージ更新開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール2. CI動作開始2.1. テストやビルド2.2. ビルド成果物をPush
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)10DockerRegistryデプロイ要求(PR作成)Hookアプリイメージ更新開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール2. CI動作開始2.1. テストやビルド2.2. ビルド成果物をPush2.3. 更新を反映するPRを作成
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)11DockerRegistry開発者(Dev)デプロイ実⾏(PR承認)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール3. 更新(PR)を確認・承認
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)12DockerRegistry開発者(Dev)デプロイ実⾏(PR承認)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール3. 更新(PR)を確認・承認3.1. SSoTのCIでe2eテスト
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)13DockerRegistry開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール4. SSoTの更新
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)14DockerRegistry開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール5. CDが更新を検知
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)15DockerRegistry開発者(Dev)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール5. CDが更新を検知5.1. 更新を反映
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)16DockerRegistryアプリの更新デプロイ要求(PR作成)Hookアプリイメージ更新開発者(Dev)デプロイ実⾏(PR承認)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)17DockerRegistryアプリの更新デプロイ要求(PR作成)Hookアプリイメージ更新開発者(Dev)デプロイ実⾏(PR承認)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール• アプリAを2つ• データベースAを使う• アプリBを4つ• GET /users はアプリAへ• POST /comments はアプリBへ• ロードバランサが必要
GitOpsのおさらいGitを中⼼とした、k8sに特化したCI/CDの仕組み• Single Source of Truthとして、サービスの状況を1つのGitリポジトリに集約• 関⼼の分離 (CIとCD)18DockerRegistryアプリの更新デプロイ要求(PR作成)Hookアプリイメージ更新開発者(Dev)デプロイ実⾏(PR承認)運⽤者(Ops)アプリケーションGitリポジトリCIツールSSoT Gitリポジトリ(Manifestファイル群) CDツール• アプリAを2つ• データベースAを使う• アプリBを4つ• GET /users はアプリAへ• POST /comments はアプリBへ• ロードバランサが必要• DB_HOST=db-a-host• DB_USER=karen• DB_PASSWORD=secret-abc
19お気づきいただけただろうか…
20Gitリポジトリ上に秘匿情報が公開されてしまうことに…!
⽤語の共有• Secret: kind: Secret のManifest• 完全な○○: 特にテンプレートではなく実際の値を含むManifest• 秘匿情報: ⼀例として、パスワードの⽂字列• SSoT: Single Source of Truth21
SealedSecretとは?bitnami-labs/sealed-secrets• GitOpsにて、Manifestファイルのうち、Secretを暗号化してGitリポジトリで管理するための仕組み• Secretの代わりにSealedSecretというリソースを利⽤• 秘匿情報は公開鍵で暗号化• apiVersion: v1 → apiVersion: bitnami.com/v1alpha• kind: Secret → kind: SealedSecret• data.{key}: base64{val} → spec.encryptedData.{key}: enc{val}•昨⽇(7/24)v0.8.0がリリース22
23使い⽅
使い⽅ 24Secretskey:secretSealedSecretsSSoT/┣ deployment.yaml┣ service.yaml┗ secret.yamlファイルツリー
使い⽅ 25Secretskey:secretSealedSecretskey:aKelVk暗号化SSoT/┣ deployment.yaml┣ service.yaml┗ secret.yamlSSoT/┣ deployment.yaml┣ service.yaml┗ sealedsecret.yamlファイルツリー暗号化1. kubesealで暗号化
使い⽅ 26Secretskey:secretSealedSecretskey:aKelVk暗号化SSoT/┣ deployment.yaml┣ service.yaml┗ secret.yamlSSoT/┣ deployment.yaml┣ service.yaml┗ sealedsecret.yamlファイルツリー暗号化1. kubesealで暗号化apiVersion: v1kind: Secretmetadata:name: my-secretdata:user: YXlhpassword: c2VjcmV0LXh5eg==Secret
使い⽅ 27Secretskey:secretSealedSecretskey:aKelVk暗号化SSoT/┣ deployment.yaml┣ service.yaml┗ secret.yamlSSoT/┣ deployment.yaml┣ service.yaml┗ sealedsecret.yamlファイルツリー暗号化1. kubesealで暗号化apiVersion: bitnami.com/v1alphakind: SealedSecretmetadata:name: my-secretspec:encryptedData:user: AgCZxTv...password: AgCe0PJ...Secret SealedSecretapiVersion: v1kind: Secretmetadata:name: my-secretdata:user: YXlhpassword: c2VjcmV0LXh5eg==
使い⽅ 28Secretskey:secretローカルSSoTSealedSecretskey:aKelVkCommitSSoT/┣ deployment.yaml┣ service.yaml┗ secret.yamlSSoT/┣ deployment.yaml┣ service.yaml┗ sealedsecret.yamlファイルツリー2. 暗号化されたSealedSecretをGitリポジトリへ
使い⽅ 29Secretskey:secretローカルSSoTSealedSecretskey:aKelVkSSoT Gitリポジトリ(Manifestファイル群)CDツールPush(PR)3. 暗号化されたSealedSecretをSSoTにPushSealedSecretsSecrets
使い⽅ 30CDツールSecretsSealedSecretskey:aKelVk4. CDツールがSSoTの変更を検知。SealedSecretを作成SSoT Gitリポジトリ(Manifestファイル群)
使い⽅ 31CDツールSecretsSealedSecretskey:aKelVk復号key:secret5. ⾃動的にSealedSecretがSecretに復号・展開されるSSoT Gitリポジトリ(Manifestファイル群)
使い⽅ 32CDツールSecretsSealedSecretskey:aKelVkkey:secret6. Podから普通に利⽤!SSoT Gitリポジトリ(Manifestファイル群)
ポイント• Pros• とにかくシンプル!• 暗号化に使う鍵を⼀切意識しなくて良い• ⾃動的な復号• Pod等からは普通のSecretとして利⽤可能• CDツールに依存しない• k8s上で完結• Cons• 暗号化は⼿動• テンプレートエンジンとの相性がやや悪い (詳細後述)33バックアップ⽤に取得は可能
34インストール
インストール 35CDツールSecretsSecrets(system)実際にはapplyするだけ
インストール 36CDツールSecretsSealedSecretsSecrets(system)CustomResourceDefinitionのSealedSecret実際にはapplyするだけ
インストール 37CDツールSecretsSealedSecretsSecrets(system)sealed-secrets-controllerCustomResourceDefinitionのSealedSecretsealed-secrets-controller実際にはapplyするだけ
インストール 38CDツールSecretsSealedSecretsSecrets(system)Publickey Privatekeysealed-secrets-controllerCustomResourceDefinitionのSealedSecretsealed-secrets-controller ⾃動的に⽣成実際にはapplyするだけ
39仕組み
仕組み 40Secretskey:secretSealedSecretsCDツールSealedSecretsSecretsSecrets(system)Publickey Privatekeysealed-secrets-controller
仕組み 41Secretskey:secretSealedSecrets1. kubesealで暗号化CDツールSealedSecretsSecretsSecrets(system)Publickey Privatekey取得して暗号化に利⽤sealed-secrets-controller
仕組み 42Secretskey:secretSealedSecrets1. kubesealで暗号化CDツールSealedSecretsSecretsSecrets(system)Publickey Privatekey取得して暗号化に利⽤kubeconfigの権限を利⽤sealed-secrets-controller
仕組み 43Secretskey:secretSealedSecretskey:aKelVk暗号化1. kubesealで暗号化CDツールSealedSecretsSecretsSecrets(system)Publickey Privatekey取得して暗号化に利⽤kubeconfigの権限を利⽤sealed-secrets-controller
仕組み 44Secretskey:secretローカルSSoTSealedSecretskey:aKelVkCommitSSoT/┣ deployment.yaml┣ service.yaml┗ secret.yamlSSoT/┣ deployment.yaml┣ service.yaml┗ sealedsecret.yamlファイルツリー2. 暗号化されたSealedSecretをGitリポジトリへ
仕組み 45Secretskey:secretローカルSSoTSealedSecretskey:aKelVkSSoT Gitリポジトリ(Manifestファイル群)CDツールPush(PR)3. 暗号化されたSealedSecretをSSoTにPushSealedSecretsSecretsSecrets(system)Publickey Privatekeysealed-secrets-controller
仕組み 46CDツールSecrets4. CDツールがSSoTの変更を検知。SealedSecretを作成SSoT Gitリポジトリ(Manifestファイル群)Secrets(system)Publickey Privatekeysealed-secrets-controllerSealedSecretskey:aKelVk
仕組み 47CDツールSSoT Gitリポジトリ(Manifestファイル群)SecretsSealedSecretskey:aKelVkSecrets(system)Publickey Privatekeysealed-secrets-controller5. sealed-secrets-controllerがSealedSecretをSecretに復号・展開 取得して復号に利⽤
仕組み 48CDツールSSoT Gitリポジトリ(Manifestファイル群)SecretsSealedSecretskey:aKelVkSecrets(system)Publickey Privatekeykey:secretsealed-secrets-controller5. sealed-secrets-controllerがSealedSecretをSecretに復号・展開 取得して復号に利⽤復号
仕組み 49CDツールSSoT Gitリポジトリ(Manifestファイル群)SecretsSealedSecretskey:aKelVkSecrets(system)Publickey Privatekeykey:secretsealed-secrets-controller6. Podから普通に利⽤!
補⾜• SealedSecretは、GitOpsでGitリポジトリに公開されてしまうSecretのManifestファイルを暗号化するための技術• k8s上 (、etcd上)での暗号化を提供する技術ではない• k8s上で復号されたSecretは平⽂• base64でエンコードされているだけ (可逆)• つまり、対象のSecretへのアクセス権限があれば⽣の秘匿情報を取得可能• RBACで制限が必要• Secretの実体があるetcdもデフォルトでは平⽂• etcdをケアするには別途EncryptionConfiguration等が必要50重要!
実はちょっとつらい話もあります…k8sでよく使われるテンプレートエンジン• Helm• Kustomize• (R.I.P. Ksonnet)51
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• GitOpsでのテンプレートエンジン• 汎⽤的な「Manifestのテンプレート」と「環境別の設定ファイル」から成る• 秘匿情報は「環境別の設定ファイル」に保持• CDツールは、これらをCD側で組み合わせて完全なManifestを作成・適⽤• SealedSecret振り返り• 完全なSecretを完全なSealedSecretに暗号化してGitリポジトリへ52
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• GitOpsでのテンプレートエンジン• 汎⽤的な「Manifestのテンプレート」と「環境別の設定ファイル」から成る• 秘匿情報は「環境別の設定ファイル」に保持• CDツールは、これらをCD側で組み合わせて完全なManifestを作成・適⽤• SealedSecret振り返り• 完全なSecretを完全なSealedSecretに暗号化してGitリポジトリへ53user: karenpassword: secret-abcapiVersion: v1kind: Secretmetadata:name: my-secretdata:user: {{ .Values.user | b64enc }}password: {{ .Values.password | b64enc }}ManifestTemplate 環境別設定user: ayapassword: secret-xyz開発環境⽤本番環境⽤
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• GitOpsでのテンプレートエンジン• 汎⽤的な「Manifestのテンプレート」と「環境別の設定ファイル」から成る• 秘匿情報は「環境別の設定ファイル」に保持• CDツールは、これらをCD側で組み合わせて完全なManifestを作成・適⽤• SealedSecret振り返り• 完全なSecretを完全なSealedSecretに暗号化してGitリポジトリへ54完全なManifestapiVersion: v1kind: Secretmetadata:name: my-secretdata:user: YXlhpassword: c2VjcmV0LXh5eg==
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• GitOpsでのテンプレートエンジン• 汎⽤的な「Manifestのテンプレート」と「環境別の設定ファイル」から成る• 秘匿情報は「環境別の設定ファイル」に保持• CDツールは、これらをCD側で組み合わせて完全なManifestを作成・適⽤• SealedSecret振り返り• 完全なSecretを完全なSealedSecretに暗号化してGitリポジトリへ55
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• GitOpsでのテンプレートエンジン• 汎⽤的な「Manifestのテンプレート」と「環境別の設定ファイル」から成る• 秘匿情報は「環境別の設定ファイル」に保持• CDツールは、これらをCD側で組み合わせて完全なManifestを作成・適⽤• SealedSecret振り返り• 完全なSecretを完全なSealedSecretに暗号化してGitリポジトリへ56apiVersion: bitnami.com/v1alphakind: SealedSecretmetadata:name: my-secretspec:encryptedData:user: AgCZxTv...password: AgCe0PJ...完全なSecret 完全なSealedSecretapiVersion: v1kind: Secretmetadata:name: my-secretdata:user: YXlhpassword: c2VjcmV0LXh5eg==
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• GitOpsでのテンプレートエンジン• 汎⽤的な「Manifestのテンプレート」と「環境別の設定ファイル」から成る• 秘匿情報は「環境別の設定ファイル」に保持• CDツールは、これらをCD側で組み合わせて完全なManifestを作成・適⽤• SealedSecret振り返り• 完全なSecretを完全なSealedSecretに暗号化してGitリポジトリへ57
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• GitOpsでのテンプレートエンジン• 汎⽤的な「Manifestのテンプレート」と「環境別の設定ファイル」から成る• 秘匿情報は「環境別の設定ファイル」に保持• CDツールは、これらをCD側で組み合わせて完全なManifestを作成・適⽤• SealedSecret振り返り• 完全なSecretを完全なSealedSecretに暗号化してGitリポジトリへ58ミスマッチ
実はちょっとつらい話もあります…SealedSecretとテンプレートエンジン• Workarounds• 1.完全なSealedSecretをSSoTに含めてしまう• 2. がんばる• テンプレートに設定を適⽤して完全なSecretを⽣成→kubesealで暗号化→⽣成されたSealedSecretのうち、暗号化された秘匿情報だけ抽出→設定ファイルの秘匿情報の部分を暗号化されたもので上書き→SSoTへCommit• 3. 対応するor待つ• bitnami-labs/sealed-secrets#9559
60類似ツール
類似ツールkamus• 概要• SealedSecretに近い挙動でGitOpsに特化したツール• Secretを作らず、init-containerで復号して利⽤可能• Pros• SealedSecretの利点の多くを継承• CloudKMSを利⽤可能• CDツールに依存しない• Cons• SealedSecretと⽐較して、鍵を意識する必要がある• 公開鍵暗号に⾮対応• テンプレートエンジンとの相性がやや悪い (SealedSecretと同様)61Soluto/kamus
類似ツールkubesec• 概要• Secretの暗号化に特化したCLIツール• Push型向き• Pros• CloudKMSを利⽤可能• Cons• CDツールが未対応 (Argo CDは⼀応対応可能)• テンプレートエンジンとの相性がやや悪い (SealedSecretと同様)62shyiko/kubesec
類似ツールHelmSecrets (sops)• 概要• 暗号化機能を提供するHelmプラグイン• Pros• テンプレートエンジンとシームレスに動作• 暗号化した状態のファイルを直接編集可能• CloudKMSを利⽤可能• Cons• テンプレートエンジンがHelmに限定• CDツールが未対応 (ArgoCDは⼀応対応可能)63futuresimple/helm-secrets
類似ツールKustomize SecretGeneratorPlugins• 概要• 暗号化機能を提供するKustomizeプラグイン• (廃⽌されかけたが復活)• Pros• テンプレートエンジンとシームレスに動作• Cons• CDツールの対応がWIP• e.g., argoprd/argo-cd#1789• テンプレートエンジンがKustomizeに限定64kubernetes-sig/kustomize
類似ツールHashicorp Vault• 概要• k8s-nativeに動作する秘匿情報集中管理ツール (GitOpsとは無関係)• Secretを作らず、init-containerで復号して利⽤可能• Pros• k8sに閉じない、秘匿情報の集中管理が可能• CloudKMSを利⽤可能• CDツールに依存しない• Cons• GitOpsとの相性• Manifestファイルと秘匿情報がバラバラに =SSoTとならない• k8sで完結せず、Vaultサーバを管理することが必要65hashicorp/vault
類似ツールgit-crypt• 概要• GitPush時に特定ファイルを暗号化• Pros• 暗号化・復号は⾃動的• k8sに追加モジュールが不要• Pod等からは普通のSecretとして利⽤可能• Cons• CDツールが未対応(ArgoCDは⼀応対応可能)• テンプレートエンジンとの相性が悪い• 完全なSecretをリポジトリに含めることが必須• 暗号化・復号⽤の鍵の共有⽅法が提供されていない• クライアントごとにgit-cryptの設定が必要• 暗号化されたファイルはキーすら読めない66AGWA/git-crypt
67まとめ
まとめ• SealedSecretとは、「GitOpsにて、Manifestファイルのうち、Secretを暗号化してGitリポジトリで管理するための仕組み」• 他のツールよりシンプルに実現可能• k8s上での暗号化はスコープ外• 今回はSealedSecretを中⼼に紹介したが、拘る必要はない• 要件に合わせて選択しましょう• kamusも流⾏りそう…?ご清聴ありがとうございました68