#kubernetes
#helm
#helmfile

Helmを運用した知見

実際にhelmを使ってみて得た知見です。

ひとつのmanifestファイルにつき1リソース書く

serviceaccountのtemplate作成を下記のようにloopで作成していた。yamlファイルは --- で分割することにより複数の記述を行うことができる。

いざ helm upgrade --install してみると

生manifest管理からの移行時は名前が衝突しないようにする

rbac系のmanifestを生で管理していたが、chart化することにした。とりあえずyamlをそのまま移動してreleaseしようとしたら既存のリソースと名前が衝突してreleaseに失敗した。

下記のようにrelease名をprefixにつけるなどして衝突を回避する。serviceaccount tokenによるAPI認証を行っている場合tokenが変わってしまうので、こういったものは既存のものはchartに移行しないという選択するのも手です。

metadata:
  name: {{ .Release.Name }}-clusterrole

リリースは小さくする

infraというchartのrequirements.yamlに依存を書いてまとめてリリースしていた。後述する helm upgrade --install の仕様で helm delete --purge をせざるを得なくなり、その際にprometheusやgrafana、namerdのデータが飛んでしまった。

dependencies:
  - name: l5d
    version: 0.7.0-dev
    condition: l5d.enabled
  - name: prometheus
    version: 4.6.12
    condition: prometheus.enabled
  - name: grafana
    version: 0.4.4-b.0
    condition: grafana.enabled
  - name: nginx-ingress
    version: 0.11.1-b.0
    condition: nginx-ingress.enabled
  - name: mysql
    version: 0.3.0-b.1
    alias: grafana-mysql
    condition: grafana.enabled
  - name: stackdriver-trace
    version: 0.1.1
    condition: stackdriver-trace.enabled
  - name: fluentd-gcp
    version: 0.3.0-dev
    condition: fluentd-gcp.enabled

適切な単位でリリースしよう。上記のchartは下記のようにリリースを分割できるでしょう。

  • namerd
  • prometheus
  • linkerd
  • grafana
  • stackdriver-trace
  • fluentd-gcp

そしてこのようなリリースを行うときはHelmfileという便利なツールがあるので、それを使って管理するのがいいと思います。

TILLER_HISTORY_MAX は大きく

(helm v2.8.2時点です。将来は修正されるかもしれません)

helm v2.6.2からv2.8.2に移行した。その際historyのconfigmapが大量にあることが気になった。helmはリリースの履歴をconfigmapとしてkube-systemに格納している。2.6では恐らく無制限になっている。

2.7か2.8から tiller init --max-history でこの履歴をどの程度保持するか指定可能になった。移行の際は tiller init --upgrade でtillerのバージョンを上げるが、 --max-history は併用できないので手動で tiller-deploy configmapにenvを注入するといい。

とりあえず5世代くらい管理でいいよね。と思って設定したところ、下記のissueの通りreleaseのfailがこの数を上回ると全てのreleaseがfailになる。すると、 helm upgrade --install が使えなくなってしまう。この状態を解除するには helm delete --purge {release} するしかなくなる。

https://github.com/kubernetes/helm/issues/3275

一つのreleaseにたくさんのchartを詰め込んでいたので致命的な結果となった。TILLER_HISTORY_MAX は十分大きく取ろう。

エラーがでたときは helm template で出力されるyamlを確認しよう

wip

Kubernetes API Versionの切り分けには gt ではなく semverCompare を使おう

異なるKubernetes Versionをサポートするために、 _helper.yaml に下記の定義をして切り分けていました。Kubernetes v1.10.0 で実行したとき、なんと batch/v2alpha1 に設定され、デプロイできないという事象が発生しました。

{{/*
Return the appropriate apiVersion for Curactor cron job.
*/}}
{{- define "curator.cronJob.apiVersion" -}}
{{- if ge .Capabilities.KubeVersion.Minor "8" -}}
"batch/v1beta1"
{{- else -}}
"batch/v2alpha1"
{{- end -}}
{{- end -}}

Issueにあるとおり、 .Capabilities.KuberVersion.Minor で取れる値はString型で、このような挙動をしました。

バージョン(semver)の比較するときは下記のように semverCompare functionを使うのが適切なようです。

{{/*
Return the appropriate apiVersion for Curactor cron job.
*/}}
{{- define "curator.cronJob.apiVersion" -}}
{{- if semverCompare ">=1.8.0" .Capabilities.KubeVersion.GitVersion -}}
"batch/v1beta1"
{{- else -}}
"batch/v2alpha1"
{{- end -}}
{{- end -}}