はじめに
今回はHelmです。
##関連記事
コンテナ型仮想化技術 Study01 / Docker基礎
コンテナ型仮想化技術 Study02 / Docker レジストリ
コンテナ型仮想化技術 Study03 / Docker Compose
コンテナ型仮想化技術 Study04 / Minikube & kubectl簡易操作
コンテナ型仮想化技術 Study05 / Pod操作
コンテナ型仮想化技術 Study06 / ReplicaSet, Deployment, Service
コンテナ型仮想化技術 Study06' / Kubernetesネットワーク問題判別
コンテナ型仮想化技術 Study07 / ストレージ
コンテナ型仮想化技術 Study08 / Statefulset, Ingress
コンテナ型仮想化技術 Study09 / Helm
参考情報
Helmの概要とChart(チャート)の作り方
Helm Documentation(V3)
Helm Documentation(V2)
Helm 3.0 のお試しレポート
Get Started with Kubernetes using Minikube
chartを作りながらhelmの概要を理解する
Helm Templateについて色々説明してみる
[Helm入門] Templateで使える関数の実行例 ~ 文字列操作編 ~
※Helmの全体像を理解するには、上の一番目の記事が秀逸で分かりやすい。
HelmはGo言語で実装されているらしく、Helm ChartのテンプレートもGo言語の作法に準拠している所があるようです。Go言語にはあまり馴染みがないせいか、出来合いのHelm Chart見ても、結構直感的に分かりにくい! Helm Chartを読んで理解するためには、公式ドキュメントの以下の章を一通り目を通すべし。
The Chart Template Developer’s Guide
用語の整理
- Chart(Helm Chart): Kubernetesクラスター上に作成する一連のリソース定義のテンプレートをパッケージングしたもの
- Repository: Helm Chartを管理する場所/サービス (Dockerイメージを管理するDockerレジストリとは全く別物)
- Release: Kubernetesクラスター上にデプロイされたHelm Charのインスタンス
※Helmのリポジトリは必ずしも必要では無いようです。Helm Chartは最終的にはテンプレート等のファイル群を.tgzとしてまとめたアーカイブファイルとして作成されることになりますが、そのファイルを直接指定してkubernetesクラスターに適用させることも可能ですし、アーカイブ前のディレクトリを指定することも可能です。限定的な利用とかテスト中はこれで充分な場合もありそうです。
Helmセットアップ
参考: Installing Helm
直近でHelmV3がリリースされたようですが、結構変更が入っていそうなのと情報が少ないので、一旦Helm V2.16.1を使うことにします。
Kubernetesクラスターとしては、Windows VirtualBox上のUbuntu上にあるminikubeを使います。
kubectlが実行できる環境にHelm本体(クライアント)をインストールし、Kubernetesクラスター側にはhelmからの指示を受けて各種操作を行うサーバー側のモジュール(Tiller)をセットアップすることになります。(ちなみにHelm V3ではTillerのセットアップは不要らしい)
ここではminikubeが乗っているUbuntu上にインストールします。
Helm本体のインストール
以下からV2.16.1のLinux amd64版のバイナリを入手します。
https://github.com/helm/helm/releases
vagrant@minikube:~/helm$ wget https://get.helm.sh/helm-v2.16.1-linux-amd64.tar.gz
--2019-11-30 23:45:56-- https://get.helm.sh/helm-v2.16.1-linux-amd64.tar.gz
Resolving get.helm.sh (get.helm.sh)... 152.199.39.108, 2606:2800:247:1cb7:261b:1f9c:2074:3c
Connecting to get.helm.sh (get.helm.sh)|152.199.39.108|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25262108 (24M) [application/x-tar]
Saving to: ‘helm-v2.16.1-linux-amd64.tar.gz’
helm-v2.16.1-linux-amd64.tar.gz 100%[============================================================================>] 24.09M 4.65MB/s in 5.3s
2019-11-30 23:46:01 (4.55 MB/s) - ‘helm-v2.16.1-linux-amd64.tar.gz’ saved [25262108/25262108]
解凍してhelmのモジュールをPATHが通っているディレクトリ(/usr/local/bin/)に配置
vagrant@minikube:~/helm$ tar -zxvf helm-v2.16.1-linux-amd64.tar.gz
linux-amd64/
linux-amd64/helm
linux-amd64/LICENSE
linux-amd64/tiller
linux-amd64/README.md
vagrant@minikube:~/helm$ ls -l linux-amd64/
total 79692
-rwxr-xr-x 1 vagrant vagrant 40460288 Nov 12 18:35 helm
-rw-r--r-- 1 vagrant vagrant 11343 Nov 12 18:37 LICENSE
-rw-r--r-- 1 vagrant vagrant 3444 Nov 12 18:37 README.md
-rwxr-xr-x 1 vagrant vagrant 41127936 Nov 12 18:37 tiller
vagrant@minikube:~/helm$ sudo mv linux-amd64/helm /usr/local/bin/
これでhelmコマンドが使えるようになりました。
vagrant@minikube:~$ helm version
Client: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
Error: could not find tiller
Tillerセットアップ
※Helm V3だとこのステップが不要になっている!
次に、Kubernetesクラスター側にTillerというサーバーサイドのモジュールをセットアップしますが、これはHelmをインストールしたノード(=kubectlが入っているノード)からhelm init
コマンドで実施します。
vagrant@minikube:~$ helm init
Creating /home/vagrant/.helm
Creating /home/vagrant/.helm/repository
Creating /home/vagrant/.helm/repository/cache
Creating /home/vagrant/.helm/repository/local
Creating /home/vagrant/.helm/plugins
Creating /home/vagrant/.helm/starters
Creating /home/vagrant/.helm/cache/archive
Creating /home/vagrant/.helm/repository/repositories.yaml
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com
Adding local repo with URL: http://127.0.0.1:8879/charts
$HELM_HOME has been configured at /home/vagrant/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
helm init
では、デフォルトで、その環境のkubectlのデフォルトの接続先kubenetesに対してkube-systemネームスペースに必要なリソースを定義してくれるようです。
確認
むむ?? helm version
コマンドがエラーになる。
vagrant@minikube:~$ helm version
Client: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
E1201 00:06:00.424955 7038 portforward.go:400] an error occurred forwarding 32784 -> 44134: error forwarding port 44134 to pod 335e7345d4361233ebb592cff534be3c9adb2317e436260cbe1917f76a2478a9, uid : unable to do port forwarding: socat not found
E1201 00:06:01.428787 7038 portforward.go:400] an error occurred forwarding 32784 -> 44134: error forwarding port 44134 to pod 335e7345d4361233ebb592cff534be3c9adb2317e436260cbe1917f76a2478a9, uid : unable to do port forwarding: socat not found
E1201 00:06:03.291790 7038 portforward.go:400] an error occurred forwarding 32784 -> 44134: error forwarding port 44134 to pod 335e7345d4361233ebb592cff534be3c9adb2317e436260cbe1917f76a2478a9, uid : unable to do port forwarding: socat not found
E1201 00:06:36.327123 7038 portforward.go:340] error creating error stream for port 32784 -> 44134: Timeout occured
E1201 00:07:00.058581 7038 portforward.go:362] error creating forwarding stream for port 32784 -> 44134: Timeout occured
E1201 00:07:27.722853 7038 portforward.go:362] error creating forwarding stream for port 32784 -> 44134: Timeout occured
E1201 00:07:58.293685 7038 portforward.go:340] error creating error stream for port 32784 -> 44134: Timeout occured
E1201 00:08:37.563451 7038 portforward.go:362] error creating forwarding stream for port 32784 -> 44134: Timeout occured
E1201 00:09:27.977955 7038 portforward.go:362] error creating forwarding stream for port 32784 -> 44134: Timeout occured
E1201 00:10:40.394108 7038 portforward.go:340] error creating error stream for port 32784 -> 44134: Timeout occured
Error: cannot connect to Tiller
ちょっと古いが以下のようなIssueがあったので、これを参考にsudo apt install socat
で socatパッケージをインストールしたら上のエラーは解消しました。
参考: https://github.com/helm/helm/issues/1371
vagrant@minikube:~$ helm version
Client: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
Helm操作例
Helmチャートを使ったインストール例 / redis
参考: Get Started with Kubernetes using Minikube - Step 5: Install an application using a Helm Chart
リポジトリ確認
helm chartを管理するリポジトリ情報を事前に設定しておく必要があります。デフォルトでは以下のリポジトリが設定されています。今回は、この公式のリポジトリ使うので、このままでOK。
vagrant@minikube:~$ helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts
インストール
使用するHelm Chartはこちら。
Kubeapps Hub - Redis
vagrant@minikube:~$ helm install stable/redis
NAME: truculent-buffalo
LAST DEPLOYED: Sun Dec 1 01:21:06 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME AGE
truculent-buffalo-redis 1s
truculent-buffalo-redis-health 1s
==> v1/Pod(related)
NAME AGE
truculent-buffalo-redis-master-0 0s
truculent-buffalo-redis-slave-0 0s
==> v1/Secret
NAME AGE
truculent-buffalo-redis 1s
==> v1/Service
NAME AGE
truculent-buffalo-redis-headless 1s
truculent-buffalo-redis-master 0s
truculent-buffalo-redis-slave 0s
==> v1/StatefulSet
NAME AGE
truculent-buffalo-redis-master 0s
truculent-buffalo-redis-slave 0s
NOTES:
** Please be patient while the chart is being deployed **
Redis can be accessed via port 6379 on the following DNS names from within your cluster:
truculent-buffalo-redis-master.default.svc.cluster.local for read/write operations
truculent-buffalo-redis-slave.default.svc.cluster.local for read-only operations
To get your password run:
export REDIS_PASSWORD=$(kubectl get secret --namespace default truculent-buffalo-redis -o jsonpath="{.data.redis-password}" | base64 --decode)
To connect to your Redis server:
1. Run a Redis pod that you can use as a client:
kubectl run --namespace default truculent-buffalo-redis-client --rm --tty -i --restart='Never' \
--env REDIS_PASSWORD=$REDIS_PASSWORD \
--image docker.io/bitnami/redis:5.0.7-debian-9-r0 -- bash
2. Connect using the Redis CLI:
redis-cli -h truculent-buffalo-redis-master -a $REDIS_PASSWORD
redis-cli -h truculent-buffalo-redis-slave -a $REDIS_PASSWORD
To connect to your database from outside the cluster execute the following commands:
kubectl port-forward --namespace default svc/truculent-buffalo-redis-master 6379:6379 &
redis-cli -h 127.0.0.1 -p 6379 -a $REDIS_PASSWORD
redis関連のpod, service, statefulsetが作成されました!
確認
kubectlで作成されたリソースを確認
vagrant@minikube:~$ kubectl get all -o wide | grep redis
pod/truculent-buffalo-redis-master-0 1/1 Running 0 20m 172.17.0.11 minikube <none> <none>
pod/truculent-buffalo-redis-slave-0 1/1 Running 0 20m 172.17.0.10 minikube <none> <none>
pod/truculent-buffalo-redis-slave-1 1/1 Running 0 19m 172.17.0.12 minikube <none> <none>
service/truculent-buffalo-redis-headless ClusterIP None <none> 6379/TCP 20m app=redis,release=truculent-buffalo
service/truculent-buffalo-redis-master ClusterIP 10.97.52.153 <none> 6379/TCP 20m app=redis,release=truculent-buffalo,role=master
service/truculent-buffalo-redis-slave ClusterIP 10.102.26.9 <none> 6379/TCP 20m app=redis,release=truculent-buffalo,role=slave
statefulset.apps/truculent-buffalo-redis-master 1/1 20m truculent-buffalo-redis docker.io/bitnami/redis:5.0.7-debian-9-r0
statefulset.apps/truculent-buffalo-redis-slave 2/2 20m truculent-buffalo-redis docker.io/bitnami/redis:5.0.7-debian-9-r0
helmコマンドでの状態確認
vagrant@minikube:~$ helm ls
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
truculent-buffalo 1 Sun Dec 1 01:21:06 2019 DEPLOYED redis-10.1.0 5.0.7 default
削除
vagrant@minikube:~$ helm delete truculent-buffalo
release "truculent-buffalo" deleted
リソース一式削除されます。
vagrant@minikube:~$ helm ls
vagrant@minikube:~$ kubectl get all -o wide | grep redis
Helm Chartを作成してみる
参考: The Chart Template Developer’s Guide
雛形作成
helm create
コマンドで、helmチャートとして必要なディレクトリ構造の雛形が出来上がります。
vagrant@minikube:~/helmchart$ helm create mychar01
Creating mychar01
vagrant@minikube:~/helmchart$ tree .
.
`-- mychar01
|-- Chart.yaml
|-- charts
|-- templates
| |-- NOTES.txt
| |-- _helpers.tpl
| |-- deployment.yaml
| |-- ingress.yaml
| |-- service.yaml
| |-- serviceaccount.yaml
| `-- tests
| `-- test-connection.yaml
`-- values.yaml
4 directories, 9 files
Simple Chart / Deployment
templatesディレクトリ下に、雛形となるサンプルファイルが各種できあがっていますが、これらは使わないので一旦削除します。
vagrant@minikube:~/helmchart/mychar01$ rm -rf templates/*
templatesディレクトリ下に、kubernetesクラスタに定義したいマニフェストファイルを配置します。※本当は"テンプレート"なのでマニフェストの中身に変数とか埋め込めますが、まずは単純なケースを試すため、出来合いのマニフェストを配置して試します。
Deploymentのテストで使用した、以下のマニフェストファイルを、上のtemplatesディレクトリ下にそのまま配置します。
https://github.com/takara9/codes_for_lessons/blob/master/step08/deployment1.yml
vagrant@minikube:~/helmchart/mychar01$ tree .
.
|-- Chart.yaml
|-- charts
|-- templates
| `-- deployment1.yml
`-- values.yaml
2 directories, 3 files
helm lint
コマンドで、Chartの文法チェックを行うことができるようです。
vagrant@minikube:~/helmchart$ helm lint mychar01/
==> Linting mychar01/
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, no failures
OKっぽいので、このChartを適用してみます。リポジトリに登録する場合は、helm package
でパッケージングすることになると思いますが、このままでも適用はできるのでそのままやってみます。
helm install
でインストールしますが、この時、--debug --dry-run
で、デプロイ前に確認できます。まぁ今回は変数とか使ってないのであまり関係無いですが。
vagrant@minikube:~/helmchart$ helm install --debug --dry-run --namespace test ./mychar01
[debug] Created tunnel using local port: '44871'
[debug] SERVER: "127.0.0.1:44871"
[debug] Original chart version: ""
[debug] CHART PATH: /home/vagrant/helmchart/mychar01
NAME: foppish-uakari
REVISION: 1
RELEASED: Tue Dec 3 05:19:10 2019
CHART: mychar01-0.1.0
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
pullPolicy: IfNotPresent
repository: nginx
tag: stable
imagePullSecrets: []
ingress:
annotations: {}
enabled: false
hosts:
- host: chart-example.local
paths: []
tls: []
nameOverride: ""
nodeSelector: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
port: 80
type: ClusterIP
serviceAccount:
create: true
name: null
tolerations: []
HOOKS:
MANIFEST:
---
# Source: mychar01/templates/deployment1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deploy
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.16
では適用してみます。
vagrant@minikube:~/helmchart$ helm install --namespace test ./mychar01
NAME: queenly-pig
LAST DEPLOYED: Tue Dec 3 05:21:49 2019
NAMESPACE: test
STATUS: DEPLOYED
RESOURCES:
==> v1/Deployment
NAME AGE
web-deploy 0s
==> v1/Pod(related)
NAME AGE
web-deploy-866f97c649-55vnj 0s
web-deploy-866f97c649-7tv9n 0s
web-deploy-866f97c649-kmjhz 0s
ステータスを確認してみます。
vagrant@minikube:~/helmchart$ helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
queenly-pig 1 Tue Dec 3 05:21:49 2019 DEPLOYED mychar01-0.1.0 1.0 test
vagrant@minikube:~/helmchart$ kubectl -n test get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/web-deploy-866f97c649-55vnj 1/1 Running 0 62s 172.17.0.10 minikube <none> <none>
pod/web-deploy-866f97c649-7tv9n 1/1 Running 0 62s 172.17.0.12 minikube <none> <none>
pod/web-deploy-866f97c649-kmjhz 1/1 Running 0 62s 172.17.0.11 minikube <none> <none>
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/web-deploy 3/3 3 3 62s nginx nginx:1.16 app=web
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/web-deploy-866f97c649 3 3 3 62s nginx nginx:1.16 app=web,pod-template-hash=866f97c649
namespace "test"に、Deployment関連リソース(deployment, replicaset, pod)が意図した通りに作成されました!
削除するには、作成されたhelmリリース名を指定してhelm deleteコマンドを実行します。
vagrant@minikube:~/helmchart$ helm delete queenly-pig
release "queenly-pig" deleted
これで、作成されたリソース一式が削除されます。
#memo
It is okay to add extra files to your Helm chart. These files will be bundled and sent to Tiller. Be careful, though. Charts must be smaller than 1M because of the storage limitations of Kubernetes objects.