Helm v3のすゝめ

## はじめに

本記事は「[Helm v2のすゝめ](https://qiita.com/loftkun/items/853bbaabd4bf0fa96e9c)」を元に、Helm v3向けに内容を刷新したものです。

## Helmとは

### 今北産業形式で説明

- [Helm](https://helm.sh/)はKubernetes向けパッケージマネージャで、[CNCF](https://www.cncf.io/)がホストするOSSです(成熟度レベル=[graduate](https://www.cncf.io/announcement/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/))。
- パッケージはChartという形式で[Artifact Hub](https://artifacthub.io/)や各OSSのリポジトリ等で公開されており、自作も可能です。
- `helm install Chart名`でkubernetesクラスタ(以下"k8sクラスタ")にChartをデプロイできます。

### 主なChartリポジトリ ( selected by 独断 & 偏見 . )

- [helm/charts](https://github.com/helm/charts/)
  - 2020/11/13にサポート終了。( [Deprecation Timeline](https://github.com/helm/charts#deprecation-timeline)を参照 )
- [Artifact Hub](https://artifacthub.io/)
- [prometheus-community](https://github.com/prometheus-community/helm-charts)
- [gitlab.com](https://docs.gitlab.com/charts/)
- [istio.io](https://istio.io/pt-br/docs/setup/install/helm/)
- [Istio / Install with Helm](https://istio.io/latest/docs/setup/install/helm/)
- 等々

## k8sクラスタの準備

お好きな環境をご用意下さい。以下がおすすめです。

パブリッククラウド派

- [Google Kubernetes Engine ( GKE )](https://cloud.google.com/kubernetes-engine/?hl=ja)
  - 会員登録後、数ステップで**無料枠**で利用可！

オンプレ派

- [Minikube](https://knowledge.sakura.ad.jp/15320/)
  - 手軽にシングルノードクラスタを構築できます。
- [Docker for Mac](https://docs.docker.com/docker-for-mac/#kubernetes) / [Docker for Windows](https://docs.docker.com/docker-for-windows/)
  - dockerだけでなく、シングルノードのk8sクラスタと`kubectl`が同梱されています！
    - 設定画面で`Enable Kubernetes`にチェックを入れるとすぐに使えます。

### 本記事の作業環境

`Ubuntu 18.04`のマシンに以下をインストールしています。

- kubectl ( `v1.18.3` )
- minikube ( `v1.11.0` )

```sh
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.3", GitCommit:"2e7996e3e2712684bc73f0dec0200d64eec7fe40", GitTreeState:"clean", BuildDate:"2020-05-20T12:52:00Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.3", GitCommit:"2e7996e3e2712684bc73f0dec0200d64eec7fe40", GitTreeState:"clean", BuildDate:"2020-05-20T12:43:34Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.100:8443
KubeDNS is running at https://192.168.99.100:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ kubectl get node
NAME       STATUS   ROLES    AGE   VERSION
minikube   Ready    master   67s   v1.18.3
$
```

## Helmをインストールする
さっそくHelmを使えるようにしましょう。

### helmコマンドをインストールする
`helm`コマンドを`kubectl`コマンドが使えるマシンにインストールします。
[Installing Helm](https://helm.sh/docs/intro/install/)を参照し、お好きな方法でインストールして下さい。

例えばcurlでインストールスクリプトを入手してインストールする場合、以下のようなコマンドになります。

```
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
```

### バージョンを確認する

`helm version`コマンドで確認できます。

```bash
$ helm version
version.BuildInfo{Version:"v3.2.2", GitCommit:"a6ea66349ae3015618da4f547677a14b9ecc09b3", GitTreeState:"clean", GoVersion:"go1.13.12"}
$
```

これでhelmコマンドでアプリケーションをデプロイできる準備が整いました。

### 備考) アンインストールするには

アンインストールしたくなった場合は、helmコマンドを削除します。

```bash
$ which helm
/usr/local/bin/helm
$ sudo rm /usr/local/bin/helm
```

### ヘルプを確認する

commandの一覧を確認しておくとよいです。

```sh
$ helm help
The Kubernetes package manager

Common actions for Helm:

- helm search:    search for charts
- helm pull:      download a chart to your local directory to view
- helm install:   upload the chart to Kubernetes
- helm list:      list releases of charts

Environment variables:

+------------------+--------------------------------------------------------------------------------------------------------+
| Name                                  | Description                                                                       |
+------------------+--------------------------------------------------------------------------------------------------------+
| $XDG_CACHE_HOME                       | set an alternative location for storing cached files.                             |
| $XDG_CONFIG_HOME                      | set an alternative location for storing Helm configuration.                       |
| $XDG_DATA_HOME                        | set an alternative location for storing Helm data.                                |
| $HELM_DRIVER                          | set the backend storage driver. Values are: configmap, secret, memory, postgres   |
| $HELM_DRIVER_SQL_CONNECTION_STRING    | set the connection string the SQL storage driver should use.                      |
| $HELM_NO_PLUGINS                      | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.                        |
| $KUBECONFIG                           | set an alternative Kubernetes configuration file (default "~/.kube/config")       |
+------------------+--------------------------------------------------------------------------------------------------------+

Helm stores configuration based on the XDG base directory specification, so

- cached files are stored in $XDG_CACHE_HOME/helm
- configuration is stored in $XDG_CONFIG_HOME/helm
- data is stored in $XDG_DATA_HOME/helm

By default, the default directories depend on the Operating System. The defaults are listed below:

+------------------+---------------------------+--------------------------------+-------------------------+
| Operating System | Cache Path                | Configuration Path             | Data Path               |
+------------------+---------------------------+--------------------------------+-------------------------+
| Linux            | $HOME/.cache/helm         | $HOME/.config/helm             | $HOME/.local/share/helm |
| macOS            | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm      |
| Windows          | %TEMP%\helm               | %APPDATA%\helm                 | %APPDATA%\helm          |
+------------------+---------------------------+--------------------------------+-------------------------+

Usage:
  helm [command]

Available Commands:
  completion  generate autocompletions script for the specified shell (bash or zsh)
  create      create a new chart with the given name
  dependency  manage a chart's dependencies
  env         helm client environment information
  get         download extended information of a named release
  help        Help about any command
  history     fetch release history
  install     install a chart
  lint        examines a chart for possible issues
  list        list releases
  package     package a chart directory into a chart archive
  plugin      install, list, or uninstall Helm plugins
  pull        download a chart from a repository and (optionally) unpack it in local directory
  repo        add, list, remove, update, and index chart repositories
  rollback    roll back a release to a previous revision
  search      search for a keyword in charts
  show        show information of a chart
  status      displays the status of the named release
  template    locally render templates
  test        run tests for a release
  uninstall   uninstall a release
  upgrade     upgrade a release
  verify      verify that a chart at the given path has been signed and is valid
  version     print the client version information

Flags:
      --add-dir-header                   If true, adds the file directory to the header
      --alsologtostderr                  log to standard error as well as files
      --debug                            enable verbose output
  -h, --help                             help for helm
      --kube-apiserver string            the address and the port for the Kubernetes API server
      --kube-context string              name of the kubeconfig context to use
      --kube-token string                bearer token used for authentication
      --kubeconfig string                path to the kubeconfig file
      --log-backtrace-at traceLocation   when logging hits line file:N, emit a stack trace (default :0)
      --log-dir string                   If non-empty, write log files in this directory
      --log-file string                  If non-empty, use this log file
      --log-file-max-size uint           Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
      --logtostderr                      log to standard error instead of files (default true)
  -n, --namespace string                 namespace scope for this request
      --registry-config string           path to the registry config file (default "/home/loft/.config/helm/registry.json")
      --repository-cache string          path to the file containing cached repository indexes (default "/home/loft/.cache/helm/repository")
      --repository-config string         path to the file containing repository names and URLs (default "/home/loft/.config/helm/repositories.yaml")
      --skip-headers                     If true, avoid header prefixes in the log messages
      --skip-log-headers                 If true, avoid headers when opening log files
      --stderrthreshold severity         logs at or above this threshold go to stderr (default 2)
  -v, --v Level                          number for the log level verbosity
      --vmodule moduleSpec               comma-separated list of pattern=N settings for file-filtered logging

Use "helm [command] --help" for more information about a command.
$
```

## 主なhelmコマンド

本記事で紹介するコマンドの一覧です。
`yum`や`apt`等のパッケージマネージャと同じようなコマンド体系であることがお分かり頂けると思います。

コマンド | 説明
--- | ---
helm repo list   | リポジトリ一覧を表示する
helm repo add    | リポジトリを追加する
helm search      | デプロイ可能なChartを表示する
helm pull        | Chartをダウンロードする
helm install     | アプリケーションをインストールする(k8sクラスタにデプロイする)
helm list        | インストール済みのアプリケーションを表示する
helm uninstall   | アプリケーションをアンデプロイする

## Artifact HubのChartを検索する

どのようなChartが公開されているか検索してみましょう。
`helm search hub`で[Artifact Hub](https://artifacthub.io/)のChartを検索できます。
また、後述の手順で追加するリポジトリのChartは`helm search repo`コマンドで検索できます。

以下は`prometheus`で検索した例です。prometheusに関する各種OSSのChartが用意されていることがわかります。

```bash
$ helm search hub prometheus
URL                                                     CHART VERSION   APP VERSION     DESCRIPTION
https://artifacthub.io/packages/helm/prometheus...      13.4.0          2.24.0          Prometheus is a monitoring system and time seri...
https://artifacthub.io/packages/helm/prometheus...      13.0.0          2.22.1          Prometheus is a monitoring system and time seri...
https://artifacthub.io/packages/helm/cloudposse...      0.2.1                           Prometheus instance created by the CoreOS Prome...
https://artifacthub.io/packages/helm/nexclipper...      11.16.7         2.21.0          Prometheus is a monitoring system and time seri...
https://artifacthub.io/packages/helm/edu/promet...      11.6.0          2.19.0          Prometheus is a monitoring system and time seri...
https://artifacthub.io/packages/helm/banzaiclou...      7.3.4-thanos.4  2.4.3           Prometheus is a monitoring system and time seri...
https://artifacthub.io/packages/helm/prometheus...      2.12.1          v0.8.3          A Helm chart for k8s prometheus adapter
https://artifacthub.io/packages/helm/prometheus...      1.7.1           1.3.0           A Helm chart for prometheus pushgateway
https://artifacthub.io/packages/helm/wener/kube...      4.1.2           0.46.0          kube-prometheus collects Kubernetes manifests t...
https://artifacthub.io/packages/helm/bitnami/ku...      4.1.2           0.46.0          kube-prometheus collects Kubernetes manifests t...
( 略 )
$
```

### リポジトリを確認する

Artifact Hub以外にもChartを提供しているリポジトリが存在し、個別に追加することができます。

#### リポジトリ一覧を表示する

利用可能なリポジトリを`helm repo list`コマンドで確認できます。
初期状態では以下のようにリポジトリはありません。

```bash
$ helm repo list
Error: no repositories to show
$
```

#### リポジトリを追加する

Helm公式のチャートリポジトリ ( [helm/charts](https://github.com/helm/charts/) ) があり、以下表の`現URL`にarchiveとして残されていまが、現在はサポート終了となっています。

|   リポジトリ名    |                            旧URL                             |               現URL                |
| --------- | ---------------------------------------------------------- | -------------------------------- |
| stable    | https://kubernetes-charts.storage.googleapis.com           | https://charts.helm.sh/stable    |
| incubator | https://kubernetes-charts-incubator.storage.googleapis.com | https://charts.helm.sh/incubator |

本記事ではこのチャートを利用する手順を紹介しますが、目的のOSSの最新のチャートを提供するリポジトリをそのOSSの公式ドキュメントや、[Artifact Hub](https://artifacthub.io/)などで探し、そのリポジトリURLを追加することをおすすめします。

試しに、Helm公式のチャート ( [helm/charts](https://github.com/helm/charts/) ) の`stable`のリポジトリを追加してみましょう。
[charts/stable](https://github.com/helm/charts/tree/master/stable)のChartをデプロイできるようになります。

```bash
$ helm repo add stable https://charts.helm.sh/stable
"stable" has been added to your repositories
$
$ helm repo list
NAME    URL
stable  https://charts.helm.sh/stable
$
```

### リポジトリ内のChartを検索する

追加したリポジトリ内のChartを`helm search repo`コマンドで検索できます。

以下はリポジトリを`prometheus`で検索した例です。prometheusに関する各種OSSのChartが用意されていることがわかります。
`stable/prometheus`のChartのバージョンは`11.0.4`で、アプリケーション(今回は`prometheus`)のバージョンは`2.16.0`が利用可能なことが分かります。
このように、Chartのバージョンと、そのバージョンのChartでデプロイされるアプリケーションのバージョンを確認できます。

```bash
$ helm search repo prometheus
NAME                           	CHART VERSION	APP VERSION	DESCRIPTION
( 略 )
stable/prometheus              	11.0.4       	2.16.0     	Prometheus is a monitoring system and time seri...
stable/prometheus-adapter      	2.2.0        	v0.6.0     	A Helm chart for k8s prometheus adapter
( 略 )
stable/prometheus-node-exporter	1.9.1        	0.18.1     	A Helm chart for prometheus node-exporter
stable/prometheus-operator     	8.12.4       	0.37.0     	Provides easy monitoring definitions for Kubern...
( 略 )
stable/prometheus-pushgateway  	1.3.0        	1.2.0      	A Helm chart for prometheus pushgateway
( 略 )
$
```

また、`helm search hub`で[Artifact Hub](https://artifacthub.io/)のChartを検索できます。

なお、`helm install` コマンドの`--version`引数にChartのバージョンを指定できますので、任意のバージョンのChartをデプロイすることも可能です。

また、`helm pull`コマンドでChartをローカルにダウンロードできます。
ダウンロードしたChartはお好きに書き換えてデプロイできるので、Chartに用意されているパラメタで変更できないような設定も変更できます。
機会があれば別の記事で紹介したいと思います。

## アプリケーションをデプロイする
Chartの確認ができたところで早速、k8sクラスタにデプロイしましょう。

namespace`helm-test`配下に`stable/prometheus`をデプロイしてみます。
release nameは`test`としています。
( release nameは`helm list`で一覧表示されます。また、各リソース名のprefixとして使われます。 )

```bash
$ # namespaceを作成
$ kubectl create namespace helm-test
$ # dry-run
$ helm install test stable/prometheus --namespace helm-test --dry-run
$ # デプロイ
$ helm install stable/prometheus --name test --namespace helm-test
$ # 確認
$ helm list -n helm-test
$ kubectl get po -n helm-test
```

### アプリケーションのデプロイ結果を確認する

#### helm installコマンド結果を確認する。

少し長いですが`stable/prometheus`のChartをデプロイした際のコマンド出力を記載します。
`NOTES`の部分に基本的な使い方が記載されていることが多いです。

```bash
$ helm install test stable/prometheus --namespace helm-test
NAME: test
LAST DEPLOYED: Mon Jun  8 19:41:46 2020
NAMESPACE: helm-test
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster:
test-prometheus-server.helm-test.svc.cluster.local


Get the Prometheus server URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace helm-test -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace helm-test port-forward $POD_NAME 9090


The Prometheus alertmanager can be accessed via port 80 on the following DNS name from within your cluster:
test-prometheus-alertmanager.helm-test.svc.cluster.local


Get the Alertmanager URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace helm-test -l "app=prometheus,component=alertmanager" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace helm-test port-forward $POD_NAME 9093
#################################################################################
######   WARNING: Pod Security Policy has been moved to a global property.  #####
######            use .Values.podSecurityPolicy.enabled with pod-based      #####
######            annotations                                               #####
######            (e.g. .Values.nodeExporter.podSecurityPolicy.annotations) #####
#################################################################################


The Prometheus PushGateway can be accessed via port 9091 on the following DNS name from within your cluster:
test-prometheus-pushgateway.helm-test.svc.cluster.local


Get the PushGateway URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace helm-test -l "app=prometheus,component=pushgateway" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace helm-test port-forward $POD_NAME 9091

For more information on running Prometheus, visit:
https://prometheus.io/
$
```

#### リソースを確認する

Deployment、Service、Configmapがよく使用されますので確認しておきます。

``` bash
$ kubectl get deployment -n helm-test
$ kubectl get pod -n helm-test
$ kubectl get service -n helm-test
$ kubectl get configmap -n helm-test
```

#### インストール済みのChartを表示する

`helm list`コマンドで確認できます。

```sh

$ helm list -n helm-test
NAME	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART            	APP VERSION
test	helm-test	1       	2020-06-08 19:41:46.220696724 +0900 JST	deployed	prometheus-11.0.4	2.16.0
$
```

## アプリケーションの動作を確認する

NOTESを読んで利用方法を確認でき、k8sクラスタにデプロイされたリソースも確認できたところで、早速アプリケーションを活用していきましょう。

### Prometheus

`NOTES`の手順を実行します。

```bash
$ export POD_NAME=$(kubectl get pods --namespace helm-test -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")
$ kubectl --namespace helm-test port-forward $POD_NAME 9090
```
http://localhost:9090/graph をブラウザで開きます。
PrometheusのWebUIが確認できます。
![Prometheus.png](https://qiita-image-store.s3.amazonaws.com/0/21106/1d8bcd90-f555-360b-de6d-cf8920a6a603.png)

### Alertmanager 

`NOTES`の手順を実行します。

```bash
$ export POD_NAME=$(kubectl get pods --namespace helm-test -l "app=prometheus,component=alertmanager" -o jsonpath="{.items[0].metadata.name}")
$ kubectl --namespace helm-test port-forward $POD_NAME 9093
```
http://localhost:9093/#/alerts をブラウザで開きます。
AlertmanagerのWebUIが確認できます。
![Alertmanager.png](https://qiita-image-store.s3.amazonaws.com/0/21106/50712bdc-8d8f-4236-3a8b-b2097b6d99bd.png)

### PushGateway 

`NOTES`の手順を実行します。

```
$ export POD_NAME=$(kubectl get pods --namespace helm-test -l "app=prometheus,component=pushgateway" -o jsonpath="{.items[0].metadata.name}")
$ kubectl --namespace helm-test port-forward $POD_NAME 9091
```
http://localhost:9091/ をブラウザで開きます。
PushGatewayのWebUIが確認できます。
![Pushgateway.png](https://qiita-image-store.s3.amazonaws.com/0/21106/b75c580b-efeb-ba2c-7731-436a0d9828ec.png)

### 各アプリケーションの連携を確認する

Helmご紹介の趣旨から外れますので、別記事にしています。こちらも是非御覧下さい。
[Pushgateway->Prometheus->Alertmanager->Webhook](https://qiita.com/loftkun/items/28cdf77ea9269e255a53)

## アプリケーションをアンデプロイする

`helm uninstall`コマンドでアンデプロイできます。

```sh
$ helm list -n helm-test
NAME	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART            	APP VERSION
test	helm-test	1       	2020-06-08 19:41:46.220696724 +0900 JST	deployed	prometheus-11.0.4	2.16.0
$ helm uninstall test -n helm-test
release "test" uninstalled
$ helm list -n helm-test
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION
$
```

## まとめ

Helm v3の導入方法と、`stable/prometheus`を題材としたChartのデプロイ方法を紹介しました。

改めてHelmおすすめポイントを記載します。

- Chartが豊富
  - Prometheusを始めとして使用頻度の高いメジャーなOSSが豊富に公開されている
- Chartに複数アプリケーションを連携設定済みで含めることができる
  - `stable/prometheus`の場合、Prometheus, Alertmanager, Pushgateway が含まれている
  - まとめてデプロイ、アンデプロイできる
  - 連携設定
    - `stable/prometheus`の場合、Service Discoveryが設定済み
      - そのためアプリケーションをデプロイする側の負担が減っている
- Chartはダウンロード＆編集が可能な透明性とカスタマイズ性がある
  - 何かの時にも安心

Helmを使うとアプリケーション群を簡単にデプロイできます。
また、用意されているChartのテンプレ通りにしか使えないといったこともなく、カスタマイズ性もあります。
環境構築よりもアプリケーションの活用の方に注力したい(かつ何かの時に柔軟に構成や設定を改造したい)あなたにおすすめです。


## 備考

本記事を執筆するにあたって気づいた、[Helm v2のすゝめ](https://qiita.com/loftkun/items/853bbaabd4bf0fa96e9c)との差分を以下のnoteに記載しています。よろしければご覧ください。
[Helm v3のすゝめ」を書いて気づいたこと](https://note.com/loftkun/n/nfd2cbb3ab8b1)