最近の砂場活動その21: helmを使ってKubernetesアプリケーションのデプロイを行なう

背景

  • yamlを使ったマニフェストでKubernetesのデプロイの管理をずっとやっているのはしんどい
    • 繰り返し出てくる変数、環境毎(dev/stage/prod)の差分管理
  • もっといい感じにやって欲しい
    • helmKustomizeなどいくつか選択肢がある
    • 業務でhelmを使うので、いい機会だからhelmで機械学習アプリを管理してみる
    • 自分の用途の範囲だと、結構簡単に書けるので気にいってきてる
  • 以下の本が自分にはとても分かりやすかったです

Kubernetesで実践するクラウドネイティブDevOps

Kubernetesで実践するクラウドネイティブDevOps

設定例

values.yaml

設定値や変数を定義する。ここでは、アプリケーションの名前を変数化してみる。

app:
  name: recommend-related-examples

開発環境毎に変数を切り分けたい場合、env/dev.yamlenv/prod.yamlにそれぞれ書いておいて、最後のhelm upgradeするときに指定して適用する、といった形。

helmテンプレート

アプリケーション名を元に、サービスアカウントやnamespaceを組み立てたりするのはこういう感じ。見たまま。

# ref: https://github.com/argoproj/argo-workflows/blob/7abead2a564876a695201cf7539bd20d1fc67888/docs/workflow-rbac.md
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: workflow-role
  namespace: {{ .Release.Namespace }}
rules:
  # pod get/watch is used to identify the container IDs of the current pod
  # pod patch is used to annotate the step's outputs back to controller (e.g. artifact location)
  - apiGroups:
    - ""
    resources:
    - pods
    verbs:
    - get
    - watch
    - patch
  # logs get/watch are used to get the pods logs for script outputs, and for log archival
  - apiGroups:
    - ""
    resources:
    - pods/log
    verbs:
    - get
    - watch
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ .Values.app.name }}-sa
  namespace: {{ .Release.Namespace }}
  annotations:
    iam.gke.io/gcp-service-account: {{ .Values.app.name }}@my-project.iam.gserviceaccount.com
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: workflow-rolebinding
subjects:
  - kind: ServiceAccount
    name: {{ .Values.app.name }}-sa
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: workflow-role

反映方法

helm-diffというプラグインを入れると、terraform planのように反映前に修正差分を目視で確認できる。helm upgradeすると、実際に反映できる。各変更が、バージョンと紐付けられていて、まずかったらrollbackサブコマンドで戻すことができるらしい(まだ使ったことがない)。

コマンドが覚えきれないので、Makefileで包んで使っている。

RELEASE=recommend-related-examples
NAMESPACE=recommend-related-examples-ns

diff:
    helm diff upgrade $(RELEASE) helm --install -f ./helm/values.yaml --namespace=$(NAMESPACE)

upgrade:
    helm upgrade $(RELEASE) helm --install -f ./helm/values.yaml --namespace=$(NAMESPACE)

手元からの確認したい場合を除いて、Cloud Buildの自動化でPull Requestがマージされる度に反映されるようになっていて、コードと実環境の差を作らないようにしている。人の手もなるべく入れないことが重要。