Edited at
Z LabDay 5

helm template: Helm Chart をマニフェストファイルとして展開する

More than 1 year has passed since last update.


概要

Helm はマニフェストファイルの集まりをパッケージとしてバージョンニングし管理できる Kubernetes のパッケージマネージャです。Helm は helm クライアントと tiller サーバの二つのコンポーネントから構成されており、Kubernetes クラスタ内で実行される tiller サーバが Helm のパッケージである Chart の管理、リリースを行ないます。

helm template は、Helm 1.7 で実装された helm クライアントのサブコマンドです。対象の Chart をマニフェスト形式で展開することができます。

$ helm template --help

Render chart templates locally and display the output.

This does not require Tiller. However, any values that would normally be
looked up or retrieved in-cluster will be faked locally. Additionally, none
of the server-side testing of chart validity (e.g. whether an API is supported)
is done.

To render just one template in a chart, use '-x':

$ helm template mychart -x templates/deployment.yaml

Usage:
helm template [flags] CHART

Flags:
-x, --execute stringArray only execute the given templates
--kube-version string override the Kubernetes version used as Capabilities.KubeVersion.Major/Minor (e.g. 1.7)
-n, --name string release name (default "RELEASE-NAME")
--name-template string specify template used to name the release
--namespace string namespace to install the release into
--notes show the computed NOTES.txt file as well
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
-f, --values valueFiles specify values in a YAML file (can specify multiple) (default [])

Global Flags:
--debug enable verbose output
--home string location of your Helm config. Overrides $HELM_HOME (default "$HOME/.helm")
--host string address of Tiller. Overrides $HELM_HOST
--kube-context string name of the kubeconfig context to use
--tiller-namespace string namespace of Tiller (default "kube-system")

NOTE: helm template は Helm のプラグインとして提供されていた technosophos/helm-template を helm クライアント本体にビルトインしたものです。ビルトインされたことでプラグインの方はメンテナンスされなくなっているため、ビルトインの template サブコマンドを利用することを推奨します。


モチベーション

Chart のリリース管理を行う tiller サーバは、ServiceAccount の権限で Kubernetes apiserver にアクセスするため、"ユーザとしての" 権限でリリースを行うことができません。これはユーザの権限を RBAC で管理していたとしても、その権限を tiller サーバで利用することができないため、セキュリティ上の理由から tiller サーバによるリリースは利用できないケースがあります。しかし Helm 自体は利用したいモチベーションが存在します。例えば複数のサービスにおいて共通で利用されるミドルウェアなどは、マニフェストファイルを一箇所で管理したいが、ConfigMap などで変更できない pod.spec.resources などの設定項目を動的に変更したい場合に、マニフェストファイルを何かしらのテンプレーティングを行う必要があります。また複数バージョンの Kubernetes クラスタを管理する場合、クラスタ共通のアドオンのマニフェストファイルはバージョンにより apiVersion 等の設定が異なる場合がありここでもテンプレーティングが必要になってくるでしょう。

helm template は tiller サーバを一切利用せずに Chart からマニフェストファイルを展開することができる helm クライアントのサブコマンドです。テンプレーティングには他の選択肢もありますが、Helm のテンプレーティングを利用しておくことで将来的に上記の問題が解消された際は Helm によるリリースを利用することができますし、また Helm はデファクトになりつつあるため、コミュニティが活発であり多くのノウハウを利用することができます。


helm template の使い方

Homebrew を利用している場合、下記のコマンドでインストールできます。利用していなければリリースページからダウンロードしてください。

$ brew install kubernetes-helm

次に Chart リポジトリの情報などをインストールするために下記のコマンドを実行します。今回 helm template のみの利用で tiller サーバは利用しないため、--client-only オプションを指定します。

$ helm init --client-only

次に利用する Chart をローカルに取得します。公式として提供されている Chart は https://kubeapps.com/ から探すことができます。今回は https://kubeapps.com/charts/stable/redis を利用します。

$ helm fetch stable/redis --version 1.0.2

$ file redis-1.0.2.tgz

最後に helm template でこの tgz ファイルを指定するとマニフェストファイルとして標準出力に展開されます。今回はアーカイブされたファイルを指定していますが、Chart が格納されたディレクトリでも問題ありません。

$ helm template redis-1.0.2.tgz

Helm はインストールするマニフェストの設定を動的に変更することができます。helm template でも install サブコマンドと同様に --set オプションを利用して設定することができます。また設定できる項目は helm inspect で確認することができます。

$ helm template redis-1.0.2.tgz --set imagePullPolicy=Always

$ helm inspect redis-1.0.2.tgz


Kubernetes バージョンを明示的に指定する

Chart のマニフェストファイルでは .Capabilities.KubeVersion 変数に Kubernetes のバージョンが設定されており、テンプレーティングに利用することができます。通常 Kubernetes バージョンは tiller サーバがデプロイされているクラスタのバージョンを設定するため helm-template プラグインではこの値を利用できませんでしたが、ゼットラボ社内の要件で必要となったため、helm template で対象の Kubernetes バージョンを指定するための --kube-version オプションを実装し、Helm 1.7 から利用できるようになりました。

$ helm template redis-1.0.2.tgz --kube-version 1.8.3

このオプションを利用することで、Deployment の apiVersion を 1.8 向けには apps/v1beta2、それ未満なら extensions/v1beta1 を使うようなことが実現できます。

# _helpers.tpl

{{/*
Return the appropriate apiVersion for deployment.
*/}}
{{- define "deployment.apiVersion" -}}
{{- if ge .Capabilities.KubeVersion.Minor "8" -}}
{{- print "apps/v1beta2" -}}
{{- else -}}
{{- print "extensions/v1beta1" -}}
{{- end -}}
{{- end -}}

# deployment.yaml

apiVersion: {{ template "deployment.apiVersion" .}}
kind: Deployment
metadata:
name: heapster
labels:
...


まとめ

Helm は Kubernetes のパッケージマネージャとしてデファクトになりつつあり、セキュリティ上の理由から tiller サーバが利用できない場合においても、helm template を利用することでコミュニティの恩恵を得ることができます。--kube-version オプションも是非利用してみてください。


おわりに

このエントリは、弊社 Z Lab のメンバーによる Z Lab Advent Calendar 2017 の五日目として業務時間中に書きました。六日目は @summerwind による Prometheus のアラート管理についてです。