zaki work log

作業ログやら生活ログやらなんやら

Helm chartの設定値のカスタマイズと確認

helm installでchartをカスタマイズするには、helm show valuesの出力をベースにYAMLを作成する。

helm.sh

ちなみにこのYAMLファイルの名称ってあるのかな。。
(K8sのリソースのYAMLファイルなら「マニフェスト」とか、Ansibleなら「プレイブック」みたいな。。)

環境

$ kubectl version --short
Client Version: v1.19.2
Server Version: v1.18.2
$ helm version --short
v3.3.4+ga61ce56

Helm chartを普通にデプロイ

[zaki@cloud-dev helm-sample]$ helm install mysql-sample stable/mysql --create-namespace -n db
NAME: mysql-sample
LAST DEPLOYED: Sat Oct 24 10:49:03 2020
NAMESPACE: db
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-sample.db.svc.cluster.local

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace db mysql-sample -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-sample -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-sample 3306

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

実は--create-namespaceって知らなかった。便利ね。

[zaki@cloud-dev helm-sample]$ kubectl get ns db
NAME   STATUS   AGE
db     Active   29s
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS    RESTARTS   AGE
mysql-sample-7d54bdc95f-dvrnx   1/1     Running   0          32s
[zaki@cloud-dev helm-sample]$ helm ls -n db
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
mysql-sample    db              1               2020-10-24 10:49:03.009404136 +0900 JST deployed        mysql-1.6.7     5.7.30     

この通り、podがデプロイされた。

chartのカスタマイズ

helm show values <chart name>で、デフォルト値を参照できるので、ファイルに出力する。

$ helm show values stable/mysql > mysql-conf/values.yaml

YAMLファイルの修正

metrics用のexporterがdisableになってるのでenableにしてみよう。

$ diff -u values.yaml.org values.yaml
--- values.yaml.org     2020-10-23 09:43:57.874016590 +0900
+++ values.yaml 2020-10-23 09:45:34.736721985 +0900
@@ -162,7 +162,7 @@
     enabled: false
 
 metrics:
-  enabled: false
+  enabled: true
   image: prom/mysqld-exporter
   imageTag: v0.10.0
   imagePullPolicy: IfNotPresent

helm upgradeで更新

[zaki@cloud-dev helm-sample]$ helm upgrade mysql-sample stable/mysql -n db -f mysql-conf/values.yaml
Release "mysql-sample" has been upgraded. Happy Helming!
NAME: mysql-sample
LAST DEPLOYED: Sat Oct 24 11:00:17 2020
NAMESPACE: db
STATUS: deployed
REVISION: 2
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-sample.db.svc.cluster.local

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace db mysql-sample -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-sample -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-sample 3306

    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
[zaki@cloud-dev helm-sample]$ helm ls -n db
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
mysql-sample    db              2               2020-10-24 11:00:17.611382551 +0900 JST deployed        mysql-1.6.7     5.7.30     
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS    RESTARTS   AGE
mysql-sample-78889784cb-pdn7z   0/2     Running   0          3s
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS    RESTARTS   AGE
mysql-sample-78889784cb-pdn7z   2/2     Running   0          17s

podは再起動されて設定反映され、exporter分のコンテナが追加され2/2となっている。
コンテナ一覧は以下の通り

[zaki@cloud-dev helm-sample]$ kubectl get pod -n db mysql-sample-78889784cb-pdn7z -o jsonpath='{.spec.containers[*].image}{"\n"}'
mysql:5.7.30 prom/mysqld-exporter:v0.10.0

最小限のカスタマイズ

上記のvalues.yamlは「全ての設定情報が記載されてるファイルに必要な個所だけ変更」した状態だったが、「必要な設定のみ記載」したvalues.yamlでお試し。

分かりやすくするため、一旦まっさらな状態にする。

[zaki@cloud-dev helm-sample]$ helm uninstall -n db mysql-sample 
release "mysql-sample" uninstalled
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS        RESTARTS   AGE
mysql-sample-78889784cb-pdn7z   2/2     Terminating   0          23m

前述と同じ状態にするために以下のファイルを作成

[zaki@cloud-dev helm-sample]$ cat mysql-conf/values-metrics.yaml 
metrics:
  enabled: true
  image: prom/mysqld-exporter
  imageTag: v0.10.0
  imagePullPolicy: IfNotPresent
  resources: {}
  annotations: {}
    # prometheus.io/scrape: "true"
    # prometheus.io/port: "9104"
  livenessProbe:
    initialDelaySeconds: 15
    timeoutSeconds: 5
  readinessProbe:
    initialDelaySeconds: 5
    timeoutSeconds: 1
  flags: []
  serviceMonitor:
    enabled: false
    additionalLabels: {}
[zaki@cloud-dev helm-sample]$ helm install mysql-sample --create-namespace -n db stable/mysql -f mysql-conf/values-metrics.yaml 
NAME: mysql-sample
LAST DEPLOYED: Sat Oct 24 11:43:15 2020
NAMESPACE: db
STATUS: deployed
REVISION: 1
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-sample.db.svc.cluster.local

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace db mysql-sample -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-sample -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-sample 3306

    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
[zaki@cloud-dev helm-sample]$ helm ls -n db
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
mysql-sample    db              1               2020-10-24 11:43:15.082173471 +0900 JST deployed        mysql-1.6.7     5.7.30     
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS    RESTARTS   AGE
mysql-sample-78889784cb-vm296   0/2     Running   0          5s

設定追加

さらに、元のvalues.yamlをベースに以下のファイル 追加で作成する。
(2か所あるfailureThresholdの値をどちらも3から10に変更している)

[zaki@cloud-dev helm-sample]$ cat mysql-conf/values-probe.yaml
livenessProbe:
  initialDelaySeconds: 30
  periodSeconds: 10
  timeoutSeconds: 5
  successThreshold: 1
  failureThreshold: 10

readinessProbe:
  initialDelaySeconds: 5
  periodSeconds: 10
  timeoutSeconds: 1
  successThreshold: 1
  failureThreshold: 10

metrics設定のvalues-metrics.yamlと、ヘルスチェック設定のvalues-probe.yamlの二つのYAMLを指定してhelm upgradeする。

[zaki@cloud-dev helm-sample]$ helm upgrade mysql-sample -n db stable/mysql -f mysql-conf/values-metrics.yaml -f mysql-conf/values-probe.yaml
Release "mysql-sample" has been upgraded. Happy Helming!
NAME: mysql-sample
LAST DEPLOYED: Sat Oct 24 11:50:21 2020
NAMESPACE: db
STATUS: deployed
REVISION: 2
NOTES:
MySQL can be accessed via port 3306 on the following DNS name from within your cluster:
mysql-sample.db.svc.cluster.local

To get your root password run:

    MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace db mysql-sample -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-sample -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-sample 3306

    mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
[zaki@cloud-dev helm-sample]$ 
[zaki@cloud-dev helm-sample]$ 
[zaki@cloud-dev helm-sample]$ helm ls -n db
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
mysql-sample    db              2               2020-10-24 11:50:21.850677504 +0900 JST deployed        mysql-1.6.7     5.7.30     
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS        RESTARTS   AGE
mysql-sample-78889784cb-vm296   2/2     Terminating   0          7m15s
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS        RESTARTS   AGE
mysql-sample-78889784cb-vm296   0/2     Terminating   0          7m43s
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS            RESTARTS   AGE
mysql-sample-656fd547d4-4vddn   0/2     PodInitializing   0          2s
[zaki@cloud-dev helm-sample]$ kubectl get pod -n db
NAME                            READY   STATUS    RESTARTS   AGE
mysql-sample-656fd547d4-4vddn   2/2     Running   0          16s

-o yamlするとこんな感じにアップデートされる。

    livenessProbe:
      exec:
        command:
        - sh
        - -c
        - mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}
      failureThreshold: 10
      initialDelaySeconds: 30
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 5

    # ...

    readinessProbe:
      exec:
        command:
        - sh
        - -c
        - mysqladmin ping -u root -p${MYSQL_ROOT_PASSWORD}
      failureThreshold: 10
      initialDelaySeconds: 5
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 1

さらにファイルを追加。

## Configure the service
## ref: http://kubernetes.io/docs/user-guide/services/
service:
  annotations: {}
  ## Specify a service type
  ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services---service-types
  type: NodePort
  port: 3306
  # nodePort: 32000
  # loadBalancerIP:

Serviceのtype定義があるので、NodePortに設定してみる。

[zaki@cloud-dev helm-sample]$ helm upgrade mysql-sample -n db stable/mysql -f mysql-conf/values-metrics.yaml -f mysql-conf/values-probe.yaml -f mysql-conf/values-service.yaml 
Release "mysql-sample" has been upgraded. Happy Helming!
NAME: mysql-sample
LAST DEPLOYED: Sat Oct 24 13:26:14 2020
NAMESPACE: db
STATUS: deployed
REVISION: 3

...
[zaki@cloud-dev helm-sample]$ kc get svc -n db
NAME           TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                         AGE
mysql-sample   NodePort   10.103.97.209   <none>        3306:31559/TCP,9104:32084/TCP   103m

Serviceがtype:NodePortでデプロイされた。

ちなみにこのとき、probeの変更を行っているYAMLの指定を忘れると、元に戻される(デフォルトの設定でデプロイされる)ので注意。

[zaki@cloud-dev helm-sample]$ helm upgrade mysql-sample -n db stable/mysql -f mysql-conf/values-metrics.yaml -f mysql-conf/values-service.yaml Release "mysql-sample" has been upgraded. Happy Helming!
NAME: mysql-sample
LAST DEPLOYED: Sat Oct 24 13:27:31 2020
NAMESPACE: db
STATUS: deployed
REVISION: 4
NOTES:

...
[zaki@cloud-dev helm-sample]$ kc get pod -n db
NAME                            READY   STATUS        RESTARTS   AGE
mysql-sample-656fd547d4-4vddn   2/2     Terminating   0          96m
[zaki@cloud-dev helm-sample]$ kc get pod -n db
NAME                            READY   STATUS    RESTARTS   AGE
mysql-sample-78889784cb-mht58   2/2     Running   0          20s

現在の設定値を取得

chartをデプロイして実行中のreleaseから設定値を取得もできる。
(10/28 追記: -f values.yamlでデフォルトから変更している場合のみ。デフォルトでインストールしている場合はnullと出力される)

[zaki@cloud-dev helm-sample]$ helm ls -n db
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS  CHART           APP VERSION
mysql-sample    db              5               2020-10-24 13:29:18.169378549 +0900 JST failed  mysql-1.6.7     5.7.30     
[zaki@cloud-dev helm-sample]$ helm get values -n db mysql-sample
USER-SUPPLIED VALUES:
livenessProbe:
  failureThreshold: 10
  initialDelaySeconds: 30
  periodSeconds: 10
  successThreshold: 1
  timeoutSeconds: 5
metrics:
  annotations: {}
  enabled: true
  flags: []
  image: prom/mysqld-exporter
  imagePullPolicy: IfNotPresent
  imageTag: v0.10.0
  livenessProbe:
    initialDelaySeconds: 15
    timeoutSeconds: 5
  readinessProbe:
    initialDelaySeconds: 5
    timeoutSeconds: 1
  resources: {}
  serviceMonitor:
    additionalLabels: {}
    enabled: false
readinessProbe:
  failureThreshold: 10
  initialDelaySeconds: 5
  periodSeconds: 10
  successThreshold: 1
  timeoutSeconds: 1
service:
  annotations: {}
  port: 3306
  type: NodePort

ヘッダ行(USER-SUPPLIED VALUES:の部分)が入ってるので、設定ファイル用にYAMLで取得するなら-o yamlを付与すると無難。

ちなみにデフォルト値含めた全設定値は-aを付与すればダンプされる。