SOPS と age で Git のシークレットを管理する
commit する前に Kubernetes の Secret を暗号化し、クラスター内で Flux に復号させます。
GitOps は、クラスターの設定を Git に置き、それには Secret も含まれます。プレーンな Kubernetes の Secret を commit すると、Secret のデータは base64 でエンコードされているだけなので、リポジトリを読める人全員にその値が露出します。Flux の kustomize-controller は、Mozilla SOPS で暗号化されたファイルを復号できるため、暗号化された Secret を commit して、システム全体を Git に保つことができます。このガイドでは、最もシンプルな選択肢である age の鍵を使います。
ツールをインストールして鍵を作成する
age と sops をインストールし(たとえば brew install age sops)、鍵のペアを生成します。
age-keygen -o age.agekey
出力ファイルには秘密鍵が入り、コマンドは公開鍵(age1 で始まります)を出力します。秘密鍵を Git に入れないでください。安全な場所にバックアップしてください。失うと、シークレットを復号できなくなります。Flux 2.9 は、ポリシーが必要とする場合のために、age のポスト量子暗号のサポートも追加しています。
クラスターに秘密鍵を渡す
秘密鍵を、それを使う Flux の Kustomization と同じ namespace の Secret として保存します。
kubectl create secret generic sops-age \
--namespace=flux-system \
--from-file=age.agekey=/dev/stdin < age.agekey
Secret の中のキーは、.agekey で終わる必要があります。ローカルの age.agekey ファイルは、別の場所に安全に保存した後で、削除するか、パスワードマネージャーに移動します。
リポジトリで SOPS を設定する
リポジトリのルートに .sops.yaml を作成して、全員が同じ方法で暗号化するようにします。キーを、自分の公開鍵に置き換えます。
creation_rules:
- path_regex: .*\.yaml
encrypted_regex: ^(data|stringData)$
age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
encrypted_regex は data と stringData のフィールドだけを暗号化するため、マニフェストの他の部分は、レビューや Flux による処理のために、読める状態のままになります。複数の age の受信者(カンマ区切り)を列挙して、チームメイトとクラスターの鍵が、すべて復号できるようにできます。
Secret を暗号化する
Secret のマニフェストをローカルで書きます。たとえば apps/webapp/db-credentials.yaml です。
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: webapp
stringData:
username: webapp
password: s3cr3t-value
その場で暗号化します。
sops --encrypt --in-place apps/webapp/db-credentials.yaml
ファイルを開くと、username と password の値は暗号文になり、メタデータを含む sops: ブロックが追加されています。commit しても安全です。後で編集するには、sops apps/webapp/db-credentials.yaml を実行します。エディターで復号され、保存時に再暗号化されます。commit しようとしているものを確認するには、値がもう読めないことを確かめてください。
復号するよう Flux に伝える
フォルダーを適用する Flux の Kustomization に、decryption ブロックを追加します。
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: webapp
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: flux-system
path: ./apps/webapp
prune: true
decryption:
provider: sops
secretRef:
name: sops-age
commit して push します。調整の間に、kustomize-controller はメモリ内でファイルを復号し、通常の Secret をクラスターに適用します。確認します。
flux reconcile kustomization webapp --with-source
kubectl get secret db-credentials -n webapp
トラブルシューティングと良い習慣
Kustomization が復号エラーを報告する場合は、sops-age の Secret が Kustomization と同じ namespace に存在すること、そのキー名が .agekey で終わること、ファイルが対応する公開鍵で暗号化されたことを確認してください。kubectl describe kustomization webapp -n flux-system がエラーを表示します。
- 環境ごとに異なる鍵を使い、dev の鍵が本番のシークレットを読めないようにします。
- 鍵をローテーションするには、新しい受信者を追加し、再暗号化し(
sops updatekeys)、その後で古いものを削除します。 - クラウドの KMS キー(AWS KMS、Azure Key Vault、Google Cloud KMS)や、HashiCorp Vault、OpenBao も機能し、鍵ファイルの配布を避けられます。workload identity で設定し、プラットフォームが認証情報を提供する場合は
secretRefを省略します。 - シークレットを Git の外に完全に置きたい場合は、External Secrets Operator を使って、シークレットを vault から同期し、Flux には
ExternalSecretオブジェクトだけを管理させます。
人気のガイド
-
Push と Pull:Flux が Kubernetes にデリバリーする仕組み Git 主導の pull 型デリバリーが、デプロイ、セキュリティ、復旧の方法をどう変えるか。 -
GitRepository と Kustomization で最初のアプリケーションをデプロイする Kustomization リソースを使って Flux を Git のマニフェストに向け、同期の様子を確認します。 -
同期動作を制御する:間隔、prune、ドリフトの修正、ロールバック Flux がいつ変更を適用するか、何を削除するか、どう一時停止するか、失敗したデプロイをどう元に戻すかを決めます。 -
Flux Image Automation でイメージの更新を自動化する 新しいコンテナイメージのタグを Flux に検出させ、Git に commit させます。 -
Flux でマルチクラスターを構成する 共有インフラとクラスターごとの違いを持たせて、1 つのリポジトリから複数のクラスターを管理します。 -
Flux CD と Argo CD:GitOps ツールの選び方 アーキテクチャ、UI、Helm、シークレット、テナンシー、イメージの自動化を比較して、適切なツールを選びます。