helmfileでKubernetesのSecretを管理する
2024-09-28
#はじめに
Kubernetesにおいて、機密情報の管理は常に重要な課題です。本記事では、helmfileを使用してKubernetesのSecretを管理する方法について解説します。
#目次
#helmfileとは
helmfileは、Kubernetes用のパッケージマネージャであるHelmのデプロイメントを宣言的に管理するためのツールです。複数のHelmチャートの依存関係やリリース管理を簡単に行うことができます。
この記事で紹介するhelm secrets pluginやsops、ageなどのツールと組み合わせることで、秘密情報を暗号化してGitリポジトリに保存することができます。
#helm secrets
helm-secrets is a Helm plugin to decrypt encrypted Helm value files on the fly.
- Use sops to encrypt value files and store them in git.
- Store your secrets in a cloud native secret manager like AWS SecretManager, Azure KeyVault or HashiCorp Vault and inject them inside value files or templates.
- Use helm-secret in your favorite deployment tool or GitOps Operator like ArgoCD
GitOps
出典:helm secrets
以下、日本語訳です。
helm-secrets は、暗号化された Helm の値ファイルをその場で復号するための Helm プラグインです。
- sops を使って値ファイルを暗号化し、git に保存します。
- AWS SecretManager、Azure KeyVault、HashiCorp Vault のようなクラウドネイティブのシークレットマネージャにシークレットを保存し、値ファイルやテンプレートに注入します。
- お気に入りのデプロイツールやArgoCD GitOpsのようなGitOps Operatorでhelm-secretを使用する。
gitで秘密情報を暗号化して管理できるので、チーム内で共有したり、GitOpsをする際にも便利です。
helm secretsでは、次の章で説明するSOPS
というツールをvalues.yamlを暗号化・復号化するために使用します。
#SOPS
SOPS is an editor of encrypted files that supports YAML, JSON, ENV, INI and BINARY formats and encrypts with AWS KMS, GCP KMS, Azure Key Vault, age, and PGP.
出典:sops
以下、日本語訳です。
SOPSは暗号化ファイルのエディタで、YAML、JSON、ENV、INI、BINARY形式をサポートし、AWS KMS、GCP KMS、Azure Key Vault、age、PGPで暗号化する。
helmのvaluesはYAML形式で記述されるため、SOPSを使って暗号化・復号化することができます。
SOPSは、次の章で説明するage
というツールを使って暗号化・復号化を行います。
#age
age is a simple, modern and secure file encryption tool, format, and Go library.
It features small explicit keys, no config options, and UNIX-style composability.
出典:age
以下、日本語訳です。
ageはシンプルでモダンで安全なファイル暗号化ツール、フォーマット、Goライブラリです。
小さな明示的な鍵、設定オプションなし、UNIXスタイルの合成可能性が特徴です。
age
は、ファイル暗号化ツールです。鍵の生成と暗号化・復号化ができます。UNIX-style composability
というのを日本語に訳すのが難しいですが、UNIXの哲学に則って、小さなプログラムを組み合わせて使うことができるということです。例では、UNIXパイプを使って、tar
で圧縮したファイルをage
で暗号化する例が紹介されています。
#helmfileでSecretを管理する
この記事のベースとなるhelmfileのexampleリポジトリをcloneします。
git clone https://github.com/cloudandbuild/helmfile-example.git
cd helmfile-example
まっさらな環境で始める場合は、下記のボタンをクリックして、Cloud Shellで開いてください。
helmfileの構成については、下記の記事が参考になると思います。
#ツールをインストールする
mise を使って、.tool-versions
に記載されている関連ツールをインストールします。mise がインストールされていない場合は、こちらからインストールしましょう。
mise install
helmfileの初期化をします。このプロセスのなかでhelm pluginのhelm diff
, helm secrets
もインストールされます。
helmfile init
#demo用のk3dクラスタを作成する(optional)
今回のhelm chartを適用させるためのk3dクラスタを作成します。
k3d cluster create demo
#ageで鍵を生成する
下記のコマンドで鍵を生成する。
❯ age-keygen -o keys.txt
Public key: age1ys3l39zsvag8rvx86kpw409vx035svnv5z5qj2a7e83trp6z2apsu7jqzp
keys.txt
に秘密鍵が書き込まれますので、このファイルを安全な場所に保管してください。
コマンドラインの出力には、公開鍵が表示されます。これは、後述の.sops.yaml
ファイルに記述するために必要です。
keyファイルを配置する。
ubuntuの場合は、下記のパスに配置するとsopsで暗号化・復号化するとき、デフォルトでこの鍵が利用される。
mv keys.txt ~/.config/sops/age/keys.txt
または、環境変数で指定することで、任意の場所に配置することもできます。複数の鍵を管理する場合は、こちらのほうが安全だと思います。
export SOPS_AGE_KEY_FILE=$(pwd)/keys.txt
helmfileの管理レポジトリに.sops.yaml
を配置して下記のようにage-keygen
で出力された公開鍵を設定する。path_regexで復号化するファイルを指定する。
- .sops.yaml
creation_rules:
- path_regex: .*/config/.*secrets\.yaml
age: "age1ys3l39zsvag8rvx86kpw409vx035svnv5z5qj2a7e83trp6z2apsu7jqzp"
ここでは、環境に関係なく鍵設定していますが、実用的には環境ごとに異なる鍵を使用することでしょう。
また、ローカル環境ではage
、 本番環境では、AWS KMS
など使い分けることもできます。
セキュリティを考慮して、本番環境ではクラウドのKMSを利用することをお勧めします。鍵自体を出力せず、IAMで鍵を使った暗号化・復号化の権限制御をすることができるので、鍵流出のリスクを軽減できます。
#valuesの暗号化
この記事では、exampleレポジトリのmeilisearch
チャートを例に説明します。
暗号化前のvaluesは下記のようになっています。
- releases/meilisearch/config/default-secrets.yaml
secret:
masterKey: putYourSecureMasterKey
暗号化します。
helm secrets encrypt -i releases/meilisearch/config/default-secrets.yaml
暗号化されたファイルが作成されます。
secret:
masterKey: ENC[AES256_GCM,data:AM/yOA4Csq+oIZ/UBuoonqRjamM68Q==,iv:EF4wWpnrYGydD472FlxehWpHpzNP+iqw2en/KAep06A=,tag:2WdNamVwJK8+VGH2IlFkvQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1evst7w6xpuc6krhm9gvrff9pm62dta3zdz86nt2s0nswfmwq64as5x5mez
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0V0plVitzTHRNTWdXVU5l
Vm5meVo4VUErSU0zUHFPRHlRTXhrWkdOQVFJCmNuRVVseUNJSkU1R3Y0SUJ1NWt0
MHRzNkhOcG9wQlZMRzI1M29Qc1ZpRjAKLS0tIFFKYnZOL256YVFsWHBEd2VnblVn
bW83aVhrZXhORG9pdFdjMERTVnFxbGMKl+sIkw+nzo1ckumz1aLqU/6Kd6SPd0BV
4AqI4+0PdW5TPjFDjgdbBnaFq4QFh1H5WWpQnEh3Q0ZiKPgsKBAxrA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-09-27T23:01:06Z"
mac: ENC[AES256_GCM,data:LxJpKzuDEM/n77B/KofFBAdYC4P6KQg+430rKwuNvpDi3goa8bTJlpHExTAlx3Bbh7GFPjwDYL9rpd5B1tI0+gCGuqlZ7YbSyKhcnmcfLy5yxSKamPgsvYYtO+Mp6me6UFw7Xma/0ZzNDe7KJ3hFvrxMO6bdODfN1Zy9aq4+3dg=,iv:93jFCH3VxwTxVzHxcXIGpNKF4kBtJq8ir2MOhWdD3Gc=,tag:hVSAGnOkVf6Fzot+chn2mg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1
編集したいときは、下記のコマンドで編集できます。
helm secrets edit releases/meilisearch/config/default-secrets.yaml
#動作確認
デモ用のk3dクラスタにmeilisearchをデプロイします。
helmfile sync
meilisearchのサービスをport-forwardします。
# port-forward
kubectl port-forward svc/meilisearch -n database 7700
別のシェルを開いて、下記のコマンドでMASTER_KEYを指定して、curlでアクセスしてみます。
# get keys
MASTER_KEY=putYourSecureMasterKey
curl 'http://localhost:7700/keys' \
-H "Authorization: Bearer $MASTER_KEY"
#クリーンアップ
不要になったk3dクラスタを削除します。
k3d cluster delete demo
#参考リンク
#まとめ
今回は、helmfileでKubernetesのSecretを管理する方法について解説しました。
helm secretsで秘匿情報を暗号化してGitで管理することで、チーム内で共有したり、GitOpsをする際にも便利なので、ミスも少なくなり作業が捗ると思います。