zaki work log

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

[Kubernetes / Helm] Helm Chart作成おためし (Getting StartedとNginx Pod作成)

helm.sh

Getting Startedに沿ってやってみる。
ローカル上にあるChartファイルをパス指定してデプロイするまで。
Helm自体のGetting Startedやってから3か月も経っている件…

流れ

  1. helm create <my-chart>でテンプレートを作成する
  2. 不要なテンプレートを削除して必要なテンプレートを作る
  3. helm install <my-release> <my-chart>でデプロイする

ConfigMapのChart作成

テンプレート作成

[zaki@cloud-dev helm-chart]$ helm create mychart
Creating mychart

こんな感じ

[zaki@cloud-dev helm-chart]$ find mychart/
mychart/
mychart/Chart.yaml
mychart/values.yaml
mychart/.helmignore
mychart/templates
mychart/templates/ingress.yaml
mychart/templates/deployment.yaml
mychart/templates/service.yaml
mychart/templates/serviceaccount.yaml
mychart/templates/hpa.yaml
mychart/templates/NOTES.txt
mychart/templates/_helpers.tpl
mychart/templates/tests
mychart/templates/tests/test-connection.yaml
mychart/charts

テンプレート削除

作ったばかりなのに何を言っているんだ感あるけど、チュートリアルとして最小構成にするためいったん削除

[zaki@cloud-dev helm-chart]$ rm -rf mychart/templates/*
[zaki@cloud-dev helm-chart]$ find mychart/
mychart/
mychart/Chart.yaml
mychart/values.yaml
mychart/.helmignore
mychart/templates
mychart/charts

ConfigMapのテンプレートを作成

mychart/templates/configmap.yamlファイルを作成。
内容的にはハードコーディングしてある状態。

apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"

デプロイする

作業用namespaceを作って、そこへデプロイしてみる。

[zaki@cloud-dev helm-chart]$ kc create namespace helm-example
namespace/helm-example created
[zaki@cloud-dev helm-chart]$ helm ls -n helm-example
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION
[zaki@cloud-dev helm-chart]$ helm install sample ./mychart/ -n helm-example
NAME: sample
LAST DEPLOYED: Mon Sep 14 19:49:21 2020
NAMESPACE: helm-example
STATUS: deployed
REVISION: 1
TEST SUITE: None
[zaki@cloud-dev helm-chart]$ helm ls -n helm-example
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
sample  helm-example    1               2020-09-14 19:49:21.04252068 +0900 JST  deployed        mychart-0.1.0   1.16.0
[zaki@cloud-dev helm-chart]$ kubectl get configmap -n helm-example
NAME                 DATA   AGE
istio-ca-root-cert   1      109s
mychart-configmap    1      19s

Istio入れてるので自動で作成されたConfgiMapがあるけどそれは置いておいて、mychart-configmapの作成を確認。

[zaki@cloud-dev helm-chart]$ kubectl get configmap -n helm-example mychart-configmap -o yaml
apiVersion: v1
data:
  myvalue: Hello World
kind: ConfigMap
metadata:
  annotations:
    meta.helm.sh/release-name: sample
    meta.helm.sh/release-namespace: helm-example
  creationTimestamp: "2020-09-14T10:49:22Z"
  labels:
    app.kubernetes.io/managed-by: Helm
  name: mychart-configmap
  namespace: helm-example
  resourceVersion: "4879814"
  selfLink: /api/v1/namespaces/helm-example/configmaps/mychart-configmap
  uid: 011681a6-ffe1-4252-94f4-7a07cb51a2be

Helmで使用されたテンプレートの確認

[zaki@cloud-dev helm-chart]$ helm get manifest sample -n helm-example
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"

変数

テンプレートを以下の内容に変更する。

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"

アップグレードのDry Run

アップグレードするにはhelm upgradeを実行する。
今回は、アップグレードまえにDry Runしてどう変化するか確認する。

[zaki@cloud-dev helm-chart]$ helm upgrade sample ./mychart/ -n helm-example --dry-run
Release "sample" has been upgraded. Happy Helming!
NAME: sample
LAST DEPLOYED: Mon Sep 14 19:52:04 2020
NAMESPACE: helm-example
STATUS: pending-upgrade
REVISION: 2
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: sample-configmap
data:
  myvalue: "Hello World"

[zaki@cloud-dev helm-chart]$

アップグレードする

Dry Runの内容に問題なければアップグレードする。

[zaki@cloud-dev helm-chart]$ helm upgrade sample ./mychart/ -n helm-example
Release "sample" has been upgraded. Happy Helming!
NAME: sample
LAST DEPLOYED: Mon Sep 14 19:53:36 2020
NAMESPACE: helm-example
STATUS: deployed
REVISION: 2
TEST SUITE: None

upgradeすることで、HelmリリースのRevisionも更新された。

[zaki@cloud-dev helm-chart]$ helm ls -n helm-example
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
sample  helm-example    2               2020-09-14 19:53:36.747219418 +0900 JST deployed        mychart-0.1.0   1.16.0
[zaki@cloud-dev helm-chart]$ kubectl get cm -n helm-example
NAME                 DATA   AGE
istio-ca-root-cert   1      6m4s
sample-configmap     1      18s

ConfigMapのオブジェクト名が新しくなっている。

[zaki@cloud-dev helm-chart]$ kubectl get cm -n helm-example sample-configmap -o yaml
apiVersion: v1
data:
  myvalue: Hello World
kind: ConfigMap
metadata:
  annotations:
    meta.helm.sh/release-name: sample
    meta.helm.sh/release-namespace: helm-example
  creationTimestamp: "2020-09-14T10:53:38Z"
  labels:
    app.kubernetes.io/managed-by: Helm
  name: sample-configmap
  namespace: helm-example
  resourceVersion: "4880627"
  selfLink: /api/v1/namespaces/helm-example/configmaps/sample-configmap
  uid: be0a13ec-920c-4c80-9462-a043cda48293

サンプルのNginx PodのChart作成

Chart作成の基本というかコアの部分はわかったので、試しにNginxのテンプレートの最小限の部分を使ってwebサーバーpodを作ってみる。

template

$ helm create sample-web
Creating sample-web

必要なものだけ残して削除。

[zaki@cloud-dev helm-chart]$ find sample-web
sample-web
sample-web/Chart.yaml
sample-web/values.yaml
sample-web/.helmignore
sample-web/templates
sample-web/templates/deployment.yaml
sample-web/templates/service.yaml
sample-web/templates/_helpers.tpl
sample-web/templates/NOTES.txt
sample-web/charts

こんな感じ。

github.com

ちなみにtemplates/_helpers.tplは消しちゃダメ。(後述)

helm install

[zaki@cloud-dev helm-chart]$ kc create ns sample-web
namespace/sample-web created

全部同じ名前だからわかりづらいけど、以下の通り。

  • install sample-webのsample-web: release名
  • ./sample-web/: chartのパス
  • -n sample-web: デプロイ先のnamespace名 (kubectlで指定するのと同じ)
[zaki@cloud-dev helm-chart]$ helm install sample-web ./sample-web/ -n sample-web
NAME: sample-web
LAST DEPLOYED: Mon Sep 14 20:52:02 2020
NAMESPACE: sample-web
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace sample-web -l "app.kubernetes.io/name=sample-web,app.kubernetes.io/instance=sample-web" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace sample-web port-forward $POD_NAME 8080:80

なるほどー、NOTES.txtを用意しておくと、デプロイした時に説明(デプロイした後にどうすればいいのか等)を表示できるのね。

[zaki@cloud-dev helm-chart]$ helm ls -n sample-web
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
sample-web      sample-web      1               2020-09-14 20:52:02.475726571 +0900 JST deployed        sample-web-0.1.0        1.16.0

アクセス確認

[zaki@cloud-dev helm-chart]$ kc get pod,svc -n sample-web
NAME                              READY   STATUS    RESTARTS   AGE
pod/sample-web-5d5dbd4d9c-252wc   1/1     Running   0          33s

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
service/sample-web   ClusterIP   10.96.8.194   <none>        80/TCP    34s

ClusterIPでServiceを作ってるのでkubectl port-forwardでポート転送設定をする。

[zaki@cloud-dev helm-chart]$ export POD_NAME=$(kubectl get pods --namespace sample-web -l "app.kubernetes.io/name=sample-web,app.kubernete
s.io/instance=sample-web" -o jsonpath="{.items[0].metadata.name}")
[zaki@cloud-dev helm-chart]$ echo $POD_NAME
sample-web-5d5dbd4d9c-252wc
[zaki@cloud-dev helm-chart]$ kubectl --namespace sample-web port-forward $POD_NAME 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080

シェルをもう1個起動してcurlする。

[zaki@cloud-dev ~]$ curl http://127.0.0.1:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

うごいた。

error

_helpers.tplを消してしまうと、以下のエラーが出るので注意。

[zaki@cloud-dev helm-chart]$ helm install sample-web ./sample-web/ --dry-run
Error: template: sample-web/templates/tests/test-connection.yaml:4:12: executing "sample-web/templates/tests/test-connection.yaml" at <include "sample-web.fullname" .>: error calling include: template: no template "sample-web.fullname" associated with template "gotpl"

ドキュメント

公式のThe Chart Template Developer's Guideの情報量かなり多そう。

helm.sh


参考

qiita.com