Carpe Diem

備忘録

Helm の基本的な使い方

概要

Kubernetesの問題の1つに、マニフェストファイルがたくさんできるYAMLの壁と呼ばれるものがあります。

  • image
  • mountするファイル
  • label
  • リソース割当

といった一部の要素だけ変えたい時、ほとんど構成は同じで似たようなマニフェストファイルが大量に出てしまいます。
そしてそういったファイルは往々にして管理されず負債となっていきます。

それを解決するのがHelmというKubernetesのパッケージマネージャです。
共通部分をテンプレート化し、可変部分を変数で扱えるようになります。

今回はそのHelmの基本的な使い方を説明します。

環境

システム図

Helmをシステムアーキテクチャは以下です。

f:id:quoll00:20190806154207p:plain

ref: Simplifying App Deployment in Kubernetes with Helm Charts

図からわかるようにTillerと呼ばれるサーバがKubernetes Cluster内で起動し、api-serverをコールしてデプロイを行います。

用語

覚えておいた方がよい単語は以下です。

用語 説明
Chart Helmで利用するパッケージのテンプレート
Tiller Kubernetes Cluster上で稼働するHelmサーバ
Release Chartをデプロイした単位

使い方

RBAC

前回の

christina04.hatenablog.com

でRBACについて書きましたが、helmのtillerがapi-serverを叩くので権限が必要になります。

Namespaceの用意

今回は専用のNamespaceを用意しておきます。

$ kubectl create namespace helm

ServiceAccount作成

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: helm

ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: tiller
  namespace: helm

Tillerの起動

先ほどのServiceAccountを使い、helm initでTiller Serverを起動します。

$ helm init --tiller-namespace helm --service-account tiller

確認します。

$ helm version --tiller-namespace helm
Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"}

helmでprometheusをインストール

Release名をtest-prometheusとしてデプロイします。

$ helm install --tiller-namespace helm \
  --name test-prometheus stable/prometheus

問題なく作成できます。

$ kubectl get po
NAME                                                 READY   STATUS    RESTARTS   AGE
test-prometheus-alertmanager-6fb8c4d7f-6l77z         2/2     Running   0          84s
test-prometheus-kube-state-metrics-948cdb5f6-xvlll   1/1     Running   0          84s
test-prometheus-node-exporter-5xwx6                  1/1     Running   0          84s
test-prometheus-pushgateway-6c4f8f8d6-rwjbf          1/1     Running   0          84s
test-prometheus-server-7c9c9f7b9f-22v8g              2/2     Running   0          84s

各コマンド

簡単のためtiller-namespaceを環境変数で設定しておきます。

$ export TILLER_NAMESPACE=helm

一覧

$ helm list
NAME            REVISION        UPDATED                         STATUS          CHART                   APP VERSION     NAMESPACE
test-prometheus 1               Tue Aug  6 20:31:14 2019        DEPLOYED        prometheus-8.11.4       2.9.2           default

このREVISIONはupgradeやrollbackする際に繰り上がっていきます。

ステータス確認

$ helm status test-prometheus
LAST DEPLOYED: Tue Aug  6 23:26:25 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                          DATA  AGE
test-prometheus-alertmanager  1     17s
test-prometheus-server        3     17s
...

削除

deleteで削除しますが、

$ helm delete test-prometheus
release "test-prometheus" deleted

実はReleaseのステータスがDELETEDになるだけで残っています。

$ helm status test-prometheus
LAST DEPLOYED: Tue Aug  6 20:31:14 2019
NAMESPACE: default
STATUS: DELETED

podなどのリソースは削除されてます。

ロールバック

REVISIONを指定してロールバックします。

$ helm rollback test-prometheus 1
Rollback was a success.

ロールバックしたのでREVISIONが上がってます。

$ helm list
NAME            REVISION        UPDATED                         STATUS          CHART                   APP VERSION     NAMESPACE
test-prometheus 2               Tue Aug  6 23:26:25 2019        DEPLOYED        prometheus-8.11.4       2.9.2           default

upgrade

fetchでChartをダウンロードして

$ helm fetch stable/prometheus

展開してファイルをいじってからupgradeします。

$ helm upgrade test-prometheus prometheus/
Release "test-prometheus" has been upgraded.
LAST DEPLOYED: Tue Aug  6 23:42:23 2019
NAMESPACE: default
STATUS: DEPLOYED

完全削除

--purgeをつけると完全に消えます。

$ helm delete --purge test-prometheus

その他

通常RBACのエラーはどんなの?

RBACが有効な環境の場合、正しいServiceAccountを用意しないと以下のエラーが出ます。

$ helm install --name test-prometheus stable/prometheus
Error: release test-prometheus failed: namespaces "default" is forbidden: User "system:serviceaccount:kube-system:default" cannot get resource "namespaces" in API group "" in the namespace "default"

--tiller-namespaceが面倒くさい

helmのTiller Serverのデフォルトのnamespaceは

Helm will look for Tiller in the kube-system namespace unless --tiller-namespace or TILLER_NAMESPACE is set.

ref: Helm |

とあるように、kube-systemになっています。

なのでkube-system:defaultのServiceAccountにClusterRoleBindingを設定すれば不要になります。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

もちろん先程のように環境変数TILLER_NAMESPACEで設定するのも1つです。

minikubeの場合RBACのServiceAccount不要

minikubeの場合、helmが扱いやすいようminikube-rbacというClusterRoleBindingが存在します。

$ kubectl get clusterrolebinding minikube-rbac -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: "2019-08-06T10:57:51Z"
  name: minikube-rbac
  resourceVersion: "237"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/minikube-rbac
  uid: a7210a35-4d6a-4c18-bd6d-15e72f5fbb8a
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

これはkube-sysmte:defaultcluster-admin権限を付与してるので特に設定しなくてもhelmが自由に使えます。

Docker for Macの場合もRBAC設定不要

Kubernetes のRBACを理解する - Carpe Diem

で書いたようにdefault:default含む全てのServiceAccountにcluster-admin権限があるので不要です。

サンプルコード

今回使用したコードはこちら

github.com