実際に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}
するしかなくなる。
一つの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 -}}