Featured image of post kindで作ったKubernetesクラスタでHelmを試した

kindで作ったKubernetesクラスタでHelmを試した

めっちゃべんり

kindで作成したKubernetesクラスタを使ってHelmクイックスタートの内容を試した.


やったことのまとめ

  • HelmのCLIをMacにインストールした
  • サンプルChartKubernetesクラスタにインストールした
# Chartリポジトリの追加
$ helm repo add <リポジトリ名> <リポジトリURL>

# Chartリポジトリの更新
$ helm repo update

# 利用可能なChartの一覧を確認
$ helm search repo <キーワード>

# Chartの簡易情報
$ helm show chart <Chart名>

# Chartのインストール
$ helm install <Chart名> --generate-name

# リリースの確認
$ helm ls

# Chartのアンインストール
$ helm uninstall <リリース名>

つかうもの

  • macOS Mojave 10.14
  • Docker Desktop for Mac
    • Version 2.5.0.0
    • Docker version 19.03.13
    • インストール済み
  • kind v0.9.0 go1.15.5 darwin/amd64
    • インストール済み
  • Kubernetes v1.19.1
    • kindで作成
  • kubectl Client Version: v1.19.3
    • インストール済み
  • Helm v3.4.2+g23dd3af
    • 今回インストールする

やったこと

Helmについて

Helm1Kubernetes用のパッケージマネージャー.

アプリケーションを動かすために必要な各種Kubernetesリソース(Pod, Service, ConfigMapなど)の定義や依存関係, 設定をまとめたChartを使うことでアプリケーションのデプロイを簡単にしてくれる. らしい.
(Ubuntuでいうapt, CentOSでいうyumみたいなもの)

以前はChartを解釈するためのTillerというHelm専用のコンポーネントをKubernetesクラスタにデプロイする必要があって面倒そうだったのでちょっと敬遠してたんだけど,
いつの間にか(Helm v3.0以降)Tillerが不要になった2らしいので試してみた.

Kubernetesクラスタの準備

まずはHelmでアプリを動かすためのKubernetesクラスタをkindで作成する.

今回は一応Ingressが使えるよう設定したけど, それも省けばかなりかんたんにクラスタを作成できる.

やっぱりkindはすごい.

# kindでクラスタを作成
$ cat <<EOF | kind create cluster --name helm-practice --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
EOF
Creating cluster "helm-practice" ...
 ✓ Ensuring node image (kindest/node:v1.19.1) 🖼
 ✓ Preparing nodes 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Set kubectl context to "kind-helm-practice"
You can now use your cluster with:

kubectl cluster-info --context kind-helm-practice

Thanks for using kind! 😊

# contextは自動で切り替わるけど念の為明示的に変えておく
$ kubectl config use-context kind-helm-practice
Switched to context "kind-helm-practice".

# Ingress Controllerのデプロイ
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
$ kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=90s
pod/ingress-nginx-controller-6df69bd4f7-brc52 condition met

MacにHelmをインストール

以降はクイックスタート3の内容をなぞっていく.

Helmを使うにはまずChartKubernetesクラスタに投下するためのCLIが必要になる.

…が, Macの場合はbrewで入るのでらくちん.

# helmをインストール
$ brew install helm
$ which helm
/usr/local/bin/helm

# 動作確認
$ helm version --short
v3.4.2+g23dd3af

# completionを効かせておくと楽
$ source <(helm completion zsh)

CLIがインストールできたら, Chartを取得するためのリポジトリを追加する.

# Chartリポジトリの追加
$ helm repo add stable https://charts.helm.sh/stable
"stable" has been added to your repositories

# Chartリポジトリを更新する
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈

これでHelmの準備はOK.

Chartのインストール

いよいよChartKubernetesクラスタにインストールする.

今回は例としてMySQLChartを使う.

HelmのCLIはkubectlcontextを参照してKubernetes APIへ操作を行うので,
contextが所望の設定になっているか注意する.

# Chartをインストールする前の状態
$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   10m

# Chart(stable/mysql)の簡易情報を確認
$ helm show chart stable/mysql
apiVersion: v1
appVersion: 5.7.30
deprecated: true
description: DEPRECATED - Fast, reliable, scalable, and easy to use open-source relational
  database system.
home: https://www.mysql.com/
icon: https://www.mysql.com/common/logos/logo-mysql-170x115.png
keywords:
- mysql
- database
- sql
name: mysql
sources:
- https://github.com/kubernetes/charts
- https://github.com/docker-library/mysql
version: 1.6.9

# Chartをインストール
$ helm install stable/mysql --generate-name
WARNING: This chart is deprecated
NAME: mysql-1608125461
LAST DEPLOYED: Wed Dec 16 22:31:04 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-1608125461.default.svc.cluster.local

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default mysql-1608125461 -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)

To connect to your database:

1. Run an Ubuntu pod that you can use as a client:

    kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il

2. Install the mysql client:

    $ apt-get update && apt-get install mysql-client -y

3. Connect using the mysql cli, then provide your password:
    $ mysql -h mysql-1608125461 -p

To connect to your database directly from outside the K8s cluster:
    MYSQL_HOST=127.0.0.1
    MYSQL_PORT=3306

    # Execute the following command to route the connection:
    kubectl port-forward svc/mysql-1608125461 3306

    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}

# DeploymentとServiceが作成されている
$ kubectl get all
NAME                                   READY   STATUS    RESTARTS   AGE
pod/mysql-1608125461-bfdcccddb-h97b8   1/1     Running   0          66s

NAME                       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
service/kubernetes         ClusterIP   10.96.0.1     <none>        443/TCP    11m
service/mysql-1608125461   ClusterIP   10.96.6.222   <none>        3306/TCP   66s

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mysql-1608125461   1/1     1            1           66s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/mysql-1608125461-bfdcccddb   1         1         1       66s

# Helmでデプロイされたリリースの確認
$ helm ls
NAME            	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART      	APP VERSION
mysql-1608125461	default  	1       	2020-12-16 22:31:04.174492 +0900 JST	deployed	mysql-1.6.9	5.7.30

MySQLDeploymentとそれに対応したServiceが作成されている.

あとはChartインストール時のメッセージに従って動作確認してみる.

# Macからクラスタ内のServiceにポート転送する(別のシェルで実行)
$ kubectl port-forward svc/mysql-1608125461 3306
Forwarding from 127.0.0.1:3306 -> 3306
Forwarding from [::1]:3306 -> 3306

# Chartで自動生成されたSecretからDBのパスワードを取得
$ MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace default mysql-1608125461 -o jsonpath="{.data.mysql-root-password}" | base64 --decode; echo)

# クラスタ外(Mac)からクラスタ内のMySQLに接続
$ MYSQL_HOST=127.0.0.1
$ MYSQL_PORT=3306
$ mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 167
Server version: 5.7.30 MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

mysql> ^DBye

ChartでインストールしたMySQLがちゃんと動いていることを確認できた.

やったぜ.

Chartのアンインストール

最後にChartをアンインストールしてみる.

これもコマンド1発.

# Chartをアンインストール
$ helm uninstall mysql-1608125461
release "mysql-1608125461" uninstalled

# リリースが消えている
$ helm ls
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION

# KubernetesもChartをインストールする前の状態に戻っている
$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   33m

あっさり消えた.

おわり

Helmを使ってChartKubernetesにインストールしてみた.

なんとYAMLを1度も書かずに, CentOSyum installするような感覚でKubernetes上でアプリを動かせてしまった. すごい.

どうして今まで使ってこなかったんだろうというくらい便利.

helmは神.

おまけ

本棚に隠れていたねこ