最小構成のhelmを自作して公開するまでのメモ

2022/05/17に公開

やりたいこと

最小構成のhelmを自作して公開します。参考にしたサイトは以下の通り。

事前準備

$ helm version
version.BuildInfo{Version:"v3.8.2", GitCommit:"6e3701edea09e5d55a8ca2aae03a68917630e91b", GitTreeState:"clean", GoVersion:"go1.18.1"}

$ helm create helloworld
$ tree
.
└── helloworld
    ├── Chart.yaml
    ├── charts
    ├── templates
    │             ├── NOTES.txt
    │             ├── _helpers.tpl
    │             ├── deployment.yaml
    │             ├── hpa.yaml
    │             ├── ingress.yaml
    │             ├── service.yaml
    │             ├── serviceaccount.yaml
    │             └── tests
    │                 └── test-connection.yaml
    └── values.yaml

4 directories, 10 files

作成手順

公式helmの手順に従い、基本的なお作法を学ぶ。

templates/配下の概要

  • NOTES.txt: helm install時に表示されるヘルプテキスト
  • deployment.yaml: k8s deployment用の基本的なマニフェスト
  • service.yaml: k8s service用の基本的なマニフェスト
  • _helpers.tpl: Chart内で再利用したいヘルパーテンプレート置き場

そして使い方を覚えるためにtemplates配下のもの全てを削除!!します。

$ rm -rf helloworld/templates/*

最初のテンプレート

$ vim helloworld/templates/configmap.yaml

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

拡張子は.yamlまたは.tpl(ヘルパーの場合)が推奨されている。

  • 上記の最小限の状態で、以下のコマンドで展開可能。
$ helm install mychart ./helloworld
NAME: mychart
LAST DEPLOYED: Tue May 17 14:32:04 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
  • 展開されたマニフェストを取得
$ helm get manifest mychart
---
# Source: helloworld/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"
  • 一旦削します。
$ helm ls
NAME   	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART           	APP VERSION
mychart	default  	1       	2022-05-17 14:32:04.086107 +0900 JST	deployed	helloworld-0.1.0	1.16.0

$ helm uninstall mychart
release "mychart" uninstalled

$ helm ls
NAME	NAMESPACE	REVISION	UPDATED	STATUS	CHART	APP VERSION

少し一手間

  • mychart部分を{{ .Release.Name }}に置換。
# helloworld/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  • リリース名を変えて再度展開。
$ helm install hogefuga ./helloworld
NAME: hogefuga
LAST DEPLOYED: Tue May 17 14:42:44 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

$ helm get manifest hogefuga
---
# Source: helloworld/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hogefuga-configmap
data:
  myvalue: "Hello World"

リリース名の通りのconfigmapが生成されました。再度削除しておきます: helm uninstall hogefuga

オプションをつけて展開される内容を細かに表示することも可能。

$ helm install --debug --dry-run goodly-guppy ./helloworld
install.go:178: [debug] Original chart version: ""
install.go:195: [debug] CHART PATH: /Users/amezou/helloworld

NAME: goodly-guppy
LAST DEPLOYED: Tue May 17 14:44:31 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
autoscaling:
  enabled: false
  maxReplicas: 100
  minReplicas: 1
  targetCPUUtilizationPercentage: 80
fullnameOverride: ""
image:
  pullPolicy: IfNotPresent
  repository: nginx
  tag: ""
imagePullSecrets: []
ingress:
  annotations: {}
  className: ""
  enabled: false
  hosts:
  - host: chart-example.local
    paths:
    - path: /
      pathType: ImplementationSpecific
  tls: []
nameOverride: ""
nodeSelector: {}
podAnnotations: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
  port: 80
  type: ClusterIP
serviceAccount:
  annotations: {}
  create: true
  name: ""
tolerations: []

HOOKS:
MANIFEST:
---
# Source: helloworld/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: goodly-guppy-configmap
data:
  myvalue: "Hello World"

公開手順

  • 形式チェック
$ helm lint ./helloworld
==> Linting ./helloworld
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed
  • パッケージング
$ helm package ./helloworld
Successfully packaged chart and saved it to: /Users/amezou/helloworld-0.1.0.tgz
  • パッケージからインストール
$ helm install test helloworld-0.1.0.tgz
NAME: test
LAST DEPLOYED: Tue May 17 14:52:04 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

$ helm ls
NAME	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART           	APP VERSION
test	default  	1       	2022-05-17 14:52:04.887337 +0900 JST	deployed	helloworld-0.1.0	1.16.0

$ helm get manifest test
---
# Source: helloworld/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  myvalue: "Hello World"
  • お掃除: helm uninstall test

公開作業

helloworld-helm (main*)$ git checkout -b gh-pages
Switched to a new branch 'gh-pages'
helloworld-helm (main*)$ mkdir stable
helloworld-helm (main*)$ cd stable
helloworld-helm/stable (gh-pages*)$

# 先程作ったファイル群を移動させる
helloworld-helm/stable (gh-pages*)$ mv /User/amezou/helloworld/helloworld* .
helloworld-helm/stable (gh-pages*)$ ls
helloworld		helloworld-0.1.0.tgz

# index.yamlを生成
helloworld-helm/stable (gh-pages*)$ helm repo index . && cat index.yaml
apiVersion: v1
entries:
  helloworld:
  - apiVersion: v2
    appVersion: 1.16.0
    created: "2022-05-17T15:13:52.93078+09:00"
    description: A Helm chart for Kubernetes
    digest: 8919e22b50f84eb72d5ed2d64d5ed93e81682aaccc5f44efe027da53991d2bd1
    name: helloworld
    type: application
    urls:
    - helloworld-0.1.0.tgz
    version: 0.1.0
generated: "2022-05-17T15:13:52.930399+09:00"

# フォルダ構成
helloworld-helm/stable (gh-pages*)$ tree .
.
├── helloworld
│   ├── Chart.yaml
│   ├── charts
│   ├── templates
│   │   └── configmap.yaml
│   └── values.yaml
├── helloworld-0.1.0.tgz
└── index.yaml
  • コミットする
$ git add .
$ git commit -m "example 0.1.0"
$ git push --set-upstream origin gh-pages
  • gh-pagesブランチの内容が公開されてる事を確認
$ curl https://amezousan.github.io/helloworld-helm/stable/index.yaml
apiVersion: v1
entries:
  helloworld:
  - apiVersion: v2
    appVersion: 1.16.0
    created: "2022-05-17T15:13:52.93078+09:00"
    description: A Helm chart for Kubernetes
    digest: 8919e22b50f84eb72d5ed2d64d5ed93e81682aaccc5f44efe027da53991d2bd1
    name: helloworld
    type: application
    urls:
    - helloworld-0.1.0.tgz
    version: 0.1.0
generated: "2022-05-17T15:13:52.930399+09:00"
  • Chartレポジトリとして追加、確認、展開する。
$ helm repo add amezou-stable https://amezousan.github.io/helloworld-helm/stable
"amezou-stable" has been added to your repositories

$ helm repo list
NAME              	URL
amezou-stable     	https://amezousan.github.io/helloworld-helm/stable

$ helm search repo amezou
NAME                    	CHART VERSION	APP VERSION	DESCRIPTION
amezou-stable/helloworld	0.1.0        	1.16.0     	A Helm chart for Kubernetes

# 念の為アプデ
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "amezou-stable" chart repository

$ helm install test amezou-stable/helloworld
NAME: test
LAST DEPLOYED: Tue May 17 15:23:56 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

$ helm ls
NAME	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART           	APP VERSION
test	default  	1       	2022-05-17 15:23:56.896455 +0900 JST	deployed	helloworld-0.1.0	1.16.0

$ helm get manifest test
---
# Source: helloworld/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  myvalue: "Hello World"

以上で完了です。

まとめ

helmは、Kubernetesに展開するyamlファイル群を「DRY原則(無駄な重複をなくす)」に従ってうまく管理することが可能です。

展開するchartにおいては、いろいろな応用技が存在するので、先にご紹介した下記サイトを参考に楽しいk8sライフを送れるように学習していきましょう!

Discussion