ライフサイクルフックとチャートテスト
インストールやアップグレードの前後で一度だけ実行する処理と、リリースが実際に動作することを検証するテストの書き方。
チャートがすることの大半は、実行し続けるリソースを宣言することです。ときには、特定の瞬間に一度だけ実行されるものが必要になります。アップグレード前のデータベースマイグレーション、アンインストール後のクリーンアップジョブ、あるいはリリースが起動した後で、実際に動作していることのチェックなどです。Helm は、フックとチャートテストの両方でこれをカバーしています。
フックとは
フックは通常の Kubernetes リソースで、多くの場合 Job です。インストール、アップグレード、ロールバック、アンインストールに対して、いつ実行するかを Helm に伝えるアノテーションが付いています。
# templates/hooks/pre-install-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Values.appName }}-pre-install
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: myorg/webapp-migrate:1.0
command: ["./run-migrations.sh"]
helm.sh/hook アノテーションが、これをリリースの一部として Helm が追跡する通常のリソースではなく、フックにするものです。一般的なフックポイントは、pre-install、post-install、pre-upgrade、post-upgrade、pre-rollback、post-rollback、pre-delete、post-delete です。テスト関連のものを含む完全な一覧は、Helm フックのドキュメントにあります。
Helm がフックを順序付ける方法
pre-install フックの場合:
- Helm はフックのリソースをレンダリングし、チャートの他のどれよりも先に、クラスターに作成します。
- Helm は、それが準備完了または完了状態になるのを待ちます(完了まで実行された
Jobはこれに該当します)。 - その後はじめて、Helm はチャートの残りのリソースをレンダリングして適用します。
post-install は手順 1 と 3 を逆にします。チャートの通常のリソースが先に入り、その後にフックが実行されます。失敗した pre-upgrade フックはアップグレードを停止します。まさにこれが、マイグレーションを、後で成功することを願うのではなく、ここで実行する理由です。
フックの重みと削除ポリシー
helm.sh/hook-weight は、同じポイントにある複数のフックの順序を決めます。小さい数字が先に実行され、"0"、"5" のような文字列で指定します。重みのないフックのデフォルトは 0 です。helm.sh/hook-delete-policy はクリーンアップを制御します。完了した Job は、そうしないとクラスターに無期限に残るためです。
before-hook-creation(デフォルト):新しいものを作成する前に、以前のフックリソースを削除します。そのため、リトライが同じ名前の残った Job と衝突しません。hook-succeeded:正常に完了したら、リソースを削除します。hook-failed:失敗した場合に削除します。失敗した Job を残して調べるより、クリーンアップしたいときに便利です。削除される前に失敗をkubectl logsで確認したい場合は、省略します。
たとえば pre-install,hook-succeeded の組み合わせは、フックが 1 度実行されて成功し、自分でクリーンアップして、Job 自体の出力以外の痕跡を残さないことを意味します。失敗した試行も残したくないなら、hook-failed も追加します。
試してみる
kubectl get jobs -w
別のターミナルで:
helm install web ./webapp
最初のターミナルを見ていると、フックの Job が現れ、実行され、完了し、(削除ポリシーによっては)消えるのが見えるはずです。これらはすべて、チャートの Deployment が現れる前です。順序を鵜呑みにするのではなく、実際に確認する最も簡単な方法です。
チャートテスト:起動後にリリースを検証する
チャートテストは、リリースが存在した後、実際に動作していることを確認するために、オンデマンドで実行される Job です。
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Values.appName }}-test-connection"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox:1.36
command: ["wget", "-qO-", "{{ .Values.appName }}"]
restartPolicy: Never
helm install web ./webapp
helm test web
helm test は、リリース内の helm.sh/hook: test でアノテーションされたすべてのリソースを実行し、各 Pod の終了ステータスに基づいて合否を報告します。応答を取得した wget は 0 で終了し、接続できなかったものは 0 で終了しません。インストールやアップグレードのフックとは異なり、テストのリソースはデフォルトでは自動的に削除されません。helm test --logs を実行して出力をインラインで確認するか、実行の合間に自分でクリーンアップしてください。
それぞれをいつ使うか
- 何かを、リリースのライフサイクルの特定のポイントでちょうど 1 度だけ行う必要があり、デプロイの残りがそれを待つか、それに反応すべき場合は、フックを使います。アップグレード前のスキーママイグレーション、インストール後の外部システムへの通知、アンインストール前の外部リソースのクリーンアップなどです。
- すでに稼働しているリリースに対して、オンデマンドで再実行したいものには、チャートテストを使います。最も一般的には、デプロイの手順自体の一部にすることなく、CI パイプラインでの
helm installやhelm upgradeの後のスモークテストとして使います。
どちらも、アノテーションの下では通常の Kubernetes リソースなので、Job や Pod のデバッグについてすでに知っていること、つまり kubectl describe や kubectl logs が、そのまま当てはまります。
人気のガイド
-
Helm チャートの構造:チャート、values、テンプレート、リリース すべてのチャートに共通するフォルダー構造と、Helm を単なる YAML のバンドラー以上のものにする 3 つの概念。 -
既存のマニフェストから最初の Helm チャートを作成する Deployment、Service、ConfigMap をテンプレート化したチャートに変換し、インストールしてアップグレードします。 -
1 つのチャート、複数の環境:dev、staging、prod 用の values ファイル 環境間で異なる部分だけを上書きし、values がマージされる順序を理解します。 -
リリースを管理する:インストール、アップグレード、ロールバック、アンインストール リリースのライフサイクル全体をカバーするコマンドと、リビジョン履歴がどのようにロールバックを可能にするか。