Helm の基本的な使い方#
Kubernetesの問題の1つに、マニフェストファイルがたくさんできるYAMLの壁と呼ばれるものがあります。
- image
 - mountするファイル
 - label
 - リソース割当
 
といった一部の要素だけ変えたい時、ほとんど構成は同じで似たようなマニフェストファイルが大量に出てしまいます。
 そしてそういったファイルは往々にして管理されず負債となっていきます。
それを解決するのがHelmというKubernetesのパッケージマネージャです。
 共通部分をテンプレート化し、可変部分を変数で扱えるようになります。
今回はそのHelmの基本的な使い方を説明します。
Helmをシステムアーキテクチャは以下です。

ref: Simplifying App Deployment in Kubernetes with Helm Charts
図からわかるようにTillerと呼ばれるサーバがKubernetes Cluster内で起動し、api-serverをコールしてデプロイを行います。
覚えておいた方がよい単語は以下です。
| 用語 | 説明 | 
|---|---|
| Chart | Helmで利用するパッケージのテンプレート | 
| Tiller | Kubernetes Cluster上で稼働するHelmサーバ | 
| Release | Chartをデプロイした単位 | 
RBAC#
前回の
で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-systemnamespace unless\--tiller-namespaceorTILLER_NAMESPACEis 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:defaultにcluster-admin権限を付与してるので特に設定しなくてもhelmが自由に使えます。
Docker for Macの場合もRBAC設定不要#
Kubernetes のRBACを理解する - Carpe Diem
で書いたようにdefault:default含む全てのServiceAccountにcluster-admin権限があるので不要です。
今回使用したコードはこちら