helmfileでKubernetesのSecretを管理する

helm
kubernetes
helmfile

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で開いてください。

Open in Cloud Shell

helmfileの構成については、下記の記事が参考になると思います。

参考: 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をする際にも便利なので、ミスも少なくなり作業が捗ると思います。