1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

コンテナ型仮想化技術 Study09 / Helm

Last updated at Posted at 2020-01-06

はじめに

今回は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.

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?