コンテンツにスキップ

Helmfile@Helm

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. Helmfileの仕組み

helmコマンドを宣言的に実行できる。

ただし、ArgoCDのApplicationの.spec.source.helmキーでもhelmコマンドを宣言的に実行しつつ、実行を自動化できる。

そのため、できるだけArgoCDを使用した方が良い。


02. 設計規約

ディレクトリ構成規約

▼ マイクロサービス別

マイクロサービスをチャートの単位とみなし、マイクロサービスごとに別にディレクトリを作成する。

各マイクロサービスのディレクトリには、helmfile.dディレクトリを置き、ここにHelmリリース単位のhelmfile.dファイルを置く。

repository/
├── foo/ # fooサービス
│   ├── helmfile.d/
│   │   └── helmfile.yaml # helmfile.dファイル
│   │
│   ├── chart/ # チャート (外部チャートを使用する場合は不要)
│   └── values/ # 環境別のvaluesファイル

├── bar/ # barサービス
└── baz/ # bazサービス

Helmリリース単位は、Kubernetesリソースとすると良い。

repository/
├── foo/ # fooサービス
│   ├── helmfile.d/
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   ├── persistent-volume.yaml
│   │   └── persistent-volume-claim.yaml
│   │
│   ├── chart/ # ローカルのチャート (リモートのチャートをインストールする場合は不要)
│   └── values/ # 環境別のvaluesファイル

├── bar/ # barサービス
└── baz/ # bazサービス


03. helmfile.dファイル

helmfile.dファイルとは

helmコマンドを宣言的に定義する。

チャートをインストールする時、ほとんどのチャートで以下のコマンドを実行することになる。

$ helm repo add <チャートリポジトリ名> <URL>

$ helm repo update

$ kubectl create namespace <Namespace名>

$ helm install <Helmリリース名> <チャートリポジトリ名>/<チャート名> -n <Namespace名> --version <バージョンタグ>

これをhelmfile.dファイルで定義すると、以下のようになる。

repositories:
  - name: <チャートリポジトリ名>
    url: <URL>

releases:
  - name: <Helmリリース名>
    namespace: <Namespace名>
    chart: <チャートリポジトリ名>/<チャート名>
    version: <バージョンタグ>

補足として、helmfile.dファイル内でもHelmの関数を使用できる。

environments:
  {{ .Environment.Name }}:

repositories:
  - name: <チャートリポジトリ名>
    url: <URL>

releases:
  - name: <Helmリリース名>
    namespace: <Namespace名>
    chart: <チャートリポジトリ名>/<チャート名>
    version: <バージョンタグ>
    # 実行環境ごとに、読み込むvalues.yaml.gotmplファイルを切り替える。
    values:
      {{- if or (eq .Environment.Name "tes") (eq .Environment.Name "stg") }}
      - values-nonprd.yaml.gotmpl
      {{- end }}
      {{- if eq .Environment.Name "prd" }}
      - values-prd.yaml.gotmpl
      {{- end }}


helmfile.dファイルで使える変数

.Environment.Name

helmfileコマンドの-eオプションに渡した値は、helmfile.dファイル内の.Environment.Nameに出力できる。

$ helmfile -e prd -f helmfile.yaml
{{.Environment.Name}}

.Values

helmfileコマンドの--state-values-setオプションに渡した値は、helmfile.dファイル内の.Valuesに出力できる。

$ helmfile -e prd -f helmfile.yaml --state-values-set region=tokyo
{{.Values.region}}


environments

▼ environments

helmfileコマンド時にhelmfile.dファイル内に環境名を渡せる。

▼ 実行環境名を渡したいだけの場合

実行環境名を渡したいだけの場合、environmentsキー配下のキー自体を{{ .Environment.Name }}のように変数化する。

environments:
  {{.Environment.Name}}:
    values:
      - values-{{ .Environment.Name }}.yaml
    secrets:
      - secrets-{{ .Environment.Name }}.yaml

repositories:
  - name: foo-repository
    url: https://github.com/hiroki-hasegawa/foo-repository

releases:
  - name: foo
    chart: foo-repository/foo-chart
    version: <バージョンタグ>
# 環境名を渡す。
$ helmfile -e prd apply

▼ 実行環境名を渡す以外こともやりたい場合

実行環境名を渡す以外こともやりたい場合、environmentsキー配下のキー自体に実行環境名を設定する。

あまりユースケースがないかもしれない。

environments:
  dev:
    values:
      - values-foo.yaml
    secrets:
      - secrets-foo.yaml
  prd:
    values:
      - values-bar.yaml
    secrets:
      - secrets-bar.yaml

repositories:
  - name: foo-repository
    url: https://github.com/hiroki-hasegawa/foo-repository

releases:
  - name: foo
    chart: foo-repository/foo-chart
    version: <バージョンタグ>
# 環境名を渡す。
$ helmfile -e prd apply


helmfiles

helmfileコマンド時に-fオプションを省略できるように、helmfileファイルを宣言的に指定する。

helmfiles:
  - path: ./helmfile.d/foo.yaml
  - path: ./helmfile.d/bar.yaml
  - path: ./helmfile.d/baz.yaml


releases

▼ atomic

helmfile applyコマンドが正常に完了しなかった場合に、自動的にロールバックする。

ただし、Helmfileの自動作成機能でNamespaceは削除されずそのまま残る。

releases:
  - atomic: "true"

▼ chart

Helmリリース対象のチャートへのパスを設定する。

releases:
  - chart: <チャートリポジトリ名>/foo-chart

▼ createNamespace

helm installコマンド時にNamespaceが存在しない場合、これの作成を有効化するか否かを設定する。

デフォルトでtrueになっており、Helmリリース前にNamespaceを自動的に作成するようになっている。

ただし、Namespaceので出どころがわからなくなるため、HelmfileのcreateNamespaceオプションは無効化し、Namespaceのマニフェストを定義しておく方が良い。

releases:
  - createNamespace: "false"

▼ dependencies

依存先のチャートを設定する。

公式チャートに追加してマニフェストを作成したい場合、valuesファイルのextraTemplatesキーやextraTemplatesキーを使用することになる。

しかし、公式チャートでこれらを用意していないことがある。

その場合、自前でサブチャートを作成し、依存先のチャートとしてインストールする必要がある。

releases:
  - chart: <チャートリポジトリ名>/foo-chart
    # 依存先の設定値は同じvaluesファイルで一括して管理する
    values:
      - foo-values.yaml
    dependencies:
      - chart: extra
        version: 1.0

依存先チャートでvaluesファイルの指定はいらないが、extraチャート側でデフォルト値を設定しておく必要がある

# extraチャートのデフォルト値

foo: ""
bar: ""

リリースを別にしてサブチャートをインストールすることもできるが、別のリリースを設定しなければならない。

releases:
  - chart: <チャートリポジトリ名>/foo-chart
    name: foo-release
    version: 1.0
    values:
      - foo-values.yaml
  - chart: extra
    name: extra-release
    version: 1.0
    values:
      - extra-values.yaml

▼ set

Helmの実行時に出力するvaluesの値を設定する。

キー名にドットを含む場合、エスケープする必要がある。

releases:
  - set:
      - name: foo
        value: FOO
      - name: bar\.enabled
        value: "true"

▼ name

Helmリリース名を設定する。

releases:
  - name: foo

▼ needs

Helmリリースのインストール/アンインストールの順番を明示的に設定する。

releases:
  - name: foo
    chart: <チャートリポジトリ名>/foo-chart
  - name: bar
    chart: <チャートリポジトリ名>/bar-chart
    needs:
      # fooリリースの次にインストールする
      - foo
  - name: baz
    chart: <チャートリポジトリ名>/baz-chart
    needs:
      # barリリースの次にインストールする
      - bar

▼ namespace

チャートをインストールするNamespaceを設定する。

各マニフェストで定義できるが、実装し忘れがよく起こるため、Helmfileでまとめて指定しまうと良い。

ただし、マニフェスト側だけしか見ていないと、Namespaceが指定されていないように見えるため、注意が必要である。

releases:
  - namespace: foo-namespace

▼ values

Helmの実行時に復号化するvaluesファイルを設定する。

releases:
  - values:
      - ./foo-values.yaml

もし{{ .Environment.Name }}を使用したい場合は、environmentsキーの方でvaluesファイルを読み込ませるようにする。

environments:
  {{.Environment.Name}}:
    values:
      - values-{{ .Environment.Name }}.yaml

releases: ...

▼ version

Helmリリースのバージョンを設定する。

releases:
  - version: <バージョンタグ>


repositories

▼ name

チャートリポジトリ名を設定する。ここで設定したリポジトリ名は、releases[*].chartキーでも使用する。

repositories:
  - name: foo-repository

releases:
  - name: foo
    chart: <チャートリポジトリ名>/foo-chart
    version: <バージョンタグ>
    values:
      - foo-values.yaml

▼ oci

OCIリポジトリをチャートリポジトリとして使用する場合に、これを有効化する。

repositories:
  - name: karpenter
    url: public.ecr.aws/karpenter
    oci: "true"

releases:
  - name: karpenter
    namespace: karpenter
    chart: karpenter/karpenter
    version: v0.31.0
    atomic: "true"
    values:
      - foo-values.yaml

▼ url

Helmリリース対象のチャートリポジトリのURLを設定する。

repositories:
  - url: https://kubernetes.github.io/ingress-nginx

releases:
  - name: foo
    chart: ingress-nginx/foo-chart
    version: <バージョンタグ>
    values:
      - foo-values.yaml


secrets

Helmの実行時に復号化するSecretのファイルを設定する。

secrets:
  - ./foo-secrets.yaml


04. Helmfile固有の関数

readFile

▼ readFileとは

テキストファイルを想定パスで読み込み、レンダリングする。

readFile関数の前で改行する、1行目に空行が入ったり、関数処理時に発生した不要な文字 (体験談:2) が混入することに注意する。

apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-configmap
data:
  policy.csv: |
    {{ readFile ./policy.csv | nindent 4 }}

# apiVersion: v1
# kind: ConfigMap
# metadata:
#   name: foo-configmap
# data:
#   policy.csv: |
#
#     foo, bar, baz

▼ 空行を挿入したくない

空行を挿入したくない場合、readFile関数で出力できないようにする。

apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-configmap
data:
  policy.csv: | {{ readFile ./policy.csv | nindent 4 }}

# apiVersion: v1
# kind: ConfigMap
# metadata:
#   name: foo-configmap
# data:
#   policy.csv: |
#     foo, bar, baz

▼ JSONファイルを読み込める

Helmには.Files.Get関数や.Files.Glob関数がある。

これらの関数でJSONファイルを読み込もうとすると、 (なぜか) エラーになる。

HelmfileのreadFile関数ではエラーが起こらない。

apiVersion: v1
kind: ConfigMap
metadata:
  name: foo-configmap
data:
  foo.json: | {{ readFile foo.json | nindent 4 }}


05. values.gotmplファイル

values.gotmplファイルとは

Helmではvaluesファイルをテンプレート化できないが、Helmfileではこれが可能である。

valuesファイルに、Helmfileの変数や他のvaluesファイルの値を出力する。

特に、公式チャートに実行環境別のvaluesファイルを渡したい場合に役立つ。

注意点として、environmentsキーの後にreleasesキーが読み込まれる。

そのため、values.yaml.gotmplファイルに値を渡すためのvaluesファイルは、Helmfileのenvironmentsキー配下で読み込まなければならない。

environments:
  {{.Environment.Name}}:
    values:
      # values.yaml.gotmplファイルに値を渡すvaluesファイル
      - values-{{ .Environment.Name }}.yaml

repositories:
  - name: foo-repository
    url: https://github.com/hiroki-hasegawa/foo-repository

releases:
  - name: foo
    chart: foo-repository/foo-chart
    version: <バージョンタグ>
    values:
      # 実行環境間で共有するvaluesファイル
      - foo-values.yaml.gotmpl