Helm Chart を作成する

簡単な Helm Chart を作成してみます。

Helm Docs

環境

Helm Chart に対する大雑把な理解

Helm Chart 内のファイルは、おおよそ以下の要素により構成されます。

マニフェストファイル内で利用される各パラメーター値は、変数として利用することで動的に管理できるようになります。変数を利用するため、マニフェストファイルは Helm Template Language を用いて記述することになり、その他言語の Template Engine を利用する時と同じように、Helm Template Language においても、if 文や foreach 文のような制御構文や様々な関数を利用することができます。

また Helm Template Language の記法は Helm 独自のものではなく、Go の標準パッケージである template を利用したものとなるため、template パッケージを知っていれば理解の助けになるとあります。ちなみに、僕は template パッケージを利用したことはないです。

While we talk about the "Helm template language" as if it is Helm-specific, it is actually a combination of the Go template language, some extra functions, and a variety of wrappers to expose certain objects to the templates. Many resources on Go templates may be helpful as you learn about templating.

Helm Docs - Template Functions and Pipelines

作成した Chart

以下のリソースを作成できる Helm Chart を作成します。

  • WEB サーバーの Deployment (Pod)
  • 上記 Pod で利用される ServiceAccount
  • 上記 Deployment に紐づく Service

Chart 名を sample として作成しています。作成したものを以下の GitHub リポジトリに push しています。

https://github.com/goodbyegangster/helm_template

なお、利用した Kubernetes 環境は minikube となります。

Helm Chart のファイル構造

今回作成した Helm Chart のファイル構造です。

.
└── sample
    ├── charts                   # 依存関係のある Chart を置くディレクトリ
    ├── templates                # k8s の間にマニフェストファイルを置くディレクトリ
    │   ├── NOTES.txt            # `helm install` を実行時に表示される文言を記述
    │   ├── _helpers.tpl         # template helpers。Chart 内で利用されるグローバル変数等を記述
    │   ├── deployment.yaml      # Deployment を作るマニフェストファイル
    │   ├── service.yaml         # Service を作るマニフェストファイル
    │   ├── serviceaccount.yaml  # ServiceAccount を作るマニフェストファイル
    │   └── tests                # テスト実行時に利用されるマニフェストファイル
    │       └── test.yaml
    ├── .helmignore              # Chart をパッケージ化した際に無視するファイルを記述
    ├── Chart.yaml               # Chart に関するメタ情報を管理するファイル
    ├── README.md
    └── values.yaml              # マニフェスト内で利用される変数のデフォルト値を記述

ファイル構造については、以下のドキュメントが詳しいです。

Helm Docs - The Chart File Structure

helm create コマンドを実行すると、ファイル構造のスケルトンを作成してくれます。今回作成した Chart は、このスケルトンで作成されたファイルを参考にして作っています。

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

helm create

各ファイルたち

幾つかのファイルを、もう少しだけ詳しく確認してしみます。

Chart.yaml

Chart.yaml は、作成した Chart のメタ情報を管理するファイルです。幾つかの必須パラメーターとオプショナルなパラメーターがあり、詳細は公式のドキュメントを参考に。

Helm Docs - The Chart.yaml File

ここで指定したパラメーターは、Helm Template Language を利用し変数として利用できるようになります。

今回作成したファイル内容は下記です。

sample/Chart.yaml

apiVersion: v2 # Helm 3 の場合は v2 を指定
name: sample
type: application # 'application' or 'library'
version: 1.0.0 # The chart version. Versions are expected to follow Semantic Versioning.
appVersion: 2.0.0 # This is the version number of the application being deployed. 補助的なパラメーター。今回利用するコンテナイメージが「gcr.io/google-samples/hello-app:2.0」のため、2.0.0と設定
kubeVersion: ">= 1.25.0"
description: Sample Helm Chart
icon: http://dummy.com/ # 設定しないと linter が注意してくるので、今回は dummy の URL を指定

values.yaml

values.yaml は、Helm Template Language で利用する変数の、デフォルト値を指定したファイルです。

Values Files

今回作成したファイル内容は下記です。

sample/values.yaml

# for deployment.yaml
deployment:
  replicas:
    enabled: false
    replicaCount: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  container:
    image:
      name: gcr.io/google-samples/hello-app
      tag: "2.0"
      pullPolicy: IfNotPresent
    port:
      name: http
      containerPort: 8080
      protocol: TCP
    livenessProbe:
      path: /
    readinessProbe:
      path: /
    resources:
      memory: 128Mi
      cpu: 100m
# for svc.yaml
service:
  type: ClusterIP
  port: 80
# for serviceaccount.yaml
serviceAccount:
  create: false
  name: ""
  annotations: {}

ベストプラクティスに関するドキュメントを公開してくれています。「ネストしすぎるより、なるべくフラットな YAML の方が分かりやすいよ」とか、「デフォルト変数の値を上書きして helm install する時に、リスト形式のパラメーターがあると扱いずらいよ」とか記述されています。(今回は結構ネストさせてしまっていますが。。。)

Helm Docs - Values

.helmignore

Chart をリポジトリ化する際には、作成したファイル一式を helm package コマンドを利用して tar ファイルにするのですが、.helmignore を利用すると、その tar ファイルに含めたくないファイルを指定できるようなります。

The .helmignore file is used to specify files you don't want to include in your helm chart.

If this file exists, the helm package command will ignore all the files that match the pattern specified in the .helmignore file while packaging your application.

The .helmignore file

templates/NOTES.txt

templates/NOTES.txt は、Chart をインストールした際にターミナル上に表示される文言を記述できます。

In this section we are going to look at Helm's tool for providing instructions to your chart users. At the end of a helm install or helm upgrade, Helm can print out a block of helpful information for users. This information is highly customizable using templates.

To add installation notes to your chart, simply create a templates/NOTES.txt file. This file is plain text, but it is processed like as a template, and has all the normal template functions and objects available.

Helm Docs - Creating a NOTES.txt File

今回作成したファイル内容は下記です。

sample/template/NOTES.txt

####  SAMPLE HELM CHART  ####

Chart Name: {{ .Chart.Name }}
Chart Version: {{ .Chart.Version }}
Chart Resource Name: {{ .Release.Name }}

The following resources have been managed.
- Deployment
  - {{ .Values.deployment.container.image.name }}:{{ .Values.deployment.container.image.tag }}
- Service
  - {{ .Values.service.type }}
{{- if .Values.serviceAccount.create }}
- ServiceAccount
  - {{ template "sample.serviceAccountName" . }}
{{- end }}

{{ .Chart.Name }}{{ .Chart.Version }} といった記述がありますが、これが Helm Template Language となります。Helm Template Language の記法については後述。

templates/_helpers.tpl

templates/\_helpers.tpl は、マニフェストファイルではなく、マニフェストファイル内で利用されるグローバル変数というか配列(Helm では Named Template と呼ばれます)を定義したファイルとなります。

公式ドキュメントでの説明はこちら。

Sometimes you want to create some reusable parts in your chart, whether they're blocks or template partials. And often, it's cleaner to keep these in their own files.

In the templates/ directory, any file that begins with an underscore( _ ) is not expected to output a Kubernetes manifest file. So by convention, helper templates and partials are placed in a _helpers.tpl file.

Helm Docs - Using "Partials" and Template Includes

今回作成したファイル内容は下記です。

sample/templates/_helpers.tpl

{{/*
Common labels
*/}}
{{- define "sample.labels" -}}
app.kubernetes.io/name: {{ .Release.Name | quote }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "sample.selectorLabels" -}}
app.kubernetes.io/name: {{ .Release.Name | quote }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "sample.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default .Release.Name .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

以下の Named Template を定義しています。

Named Template 名 利用用途
sample.labels リソースのラベルに利用
sample.selectorLabels 各リソース間の selector で利用されるラベル
sample.serviceAccountName 利用するサービスアカウント名

Helm で作成されたリソースへのラベルには、設定が推奨されている値があり、以下のベストプラクティス資料が詳しいです。

Helm Docs - Labels and Annotations

Helm Template Language の記法や、Named Template の定義方法についてはについては後述。

Helm Template Language の記法

基本的な記法を確認します。

コメント行

コメントは # の他、以下のような記法を利用します。

{{/*
...
*/}}

# を利用したコメントはデバックモードで表示される、という違いがあります。

The comment above (※# を利用したパターンのこと) is visible when the user runs helm install --debug, while comments specified in {{- /* */}} sections are not.

Comments (YAML Comments vs. Template Comments)

Built-in Object (定義した values.yaml の値へのアクセス)

Built-in Object とは、Helm Template Lunguage で利用できるオブジェクトというかインスタンスとなります。values.yaml 等に定義した値を取得するには、Values オブジェクト内のインスタンス変数 なになに にアクセスする、みたいな感じで利用するイメージとなります。

例えば、以下記述の {{ .Release.Name | quote }} は、Release という Built-in Object の Name というパラメーターを取得しているものです。Release オブジェクトは作成されたリソースのメタ情報を取得できるトップレベルオブジェクトとなります。

sample/template/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name | quote }}
...

今回のサンプルでは、Release のほか、ValuesChart といった Built-in Object を利用しています。Values は、values.yaml に定義された値にアクセスできるオブジェクトであり、Chart は、Chart.yaml に定義された値にアクセスできるオブジェクトです。

下記のように記述します。{{ .Chart.Name }} は、Chart.yamlName パラメーターの値を利用するもので、{{ .Values.deployment.container.image.name }} は、values.yamldeployment.container.image.name パラメーターの値を利用するものです。

sample/template/NOTES.txt

...
Chart Name: {{ .Chart.Name }}
Chart Version: {{ .Chart.Version }}
Chart Resource Name: {{ .Release.Name }}

The following resources have been managed.
- Deployment
  - {{ .Values.deployment.container.image.name }}:{{ .Values.deployment.container.image.tag }}
...

その他に用意されているオブジェクトも含め、Built-in Object については、以下が詳しいです。

Helm Docs - Built-in Objects

関数

Helm Template Language 内では、様々な関数がビルトインされています。

Helm has over 60 available functions. Some of them are defined by the Go template language itself. Most of the others are part of the Sprig template library. We'll see many of them as we progress through the examples.

Template Functions and Pipelines

例えば前述の {{ .Release.Name | quote }} という記述ですが、.Release.Name という値に対して、パイプを介し、 quote という引用符を付与する関数を実行しているものになります。こんな感じで、実行したい関数をパイプを介して記述していくことなります。

用意されている関数の一覧が下記です。

Template Function List

制御構文

制御構文は、以下が用意されています。

if/else for creating conditional blocks

with to specify a scope

range, which provides a "for each"-style loop

Flow Control

if/elserange といった構文は、その名前の通りのため公式ドキュメントのサンプルを見れば分かりやすいですが、with はパッと見では利用ケースを想定できないため、メモしておきます。

with 構文は、その構文内で利用される変数のスコープを限定するものです。

例えば、以下のように利用します。

sample/template/deployment.yaml

...
      containers:
      {{- with .Values.deployment.container }}
        - name: {{ $.Release.Name | quote }}
          image: "{{ .image.name }}:{{ .image.tag }}"
          imagePullPolicy: {{ .image.pullPolicy }}
...
  {{- end }}

{{ with }} 構文で .Values.deployment.container を宣言しています。その後に続く {{ .image.name }}.image.name とは、実際には Values.deployment.container.image.name を指すものとなっています。こんな感じでスコープを限定できる訳です。一方で {{ .Release.Name }} といった記述は Values.deployment.container.Release.Name と扱われてしまうため、$ を頭に付与することで、そのスコープをルートスコープから開始されるものと指定することができます。

we can use $ for accessing the object Release.Name from the parent scope. $ is mapped to the root scope when template execution begins and it does not change during template execution.

Helm Docs - Modifying scope using with

Named Templates

Named Templates のことを、上記ではグローバルな配列みたいなと表現しましたが、公式のドキュメントの定義では以下となります。

A named template (sometimes called a partial or a subtemplate) is simply a template defined inside of a file, and given a name. We'll see two ways to create them, and a few different ways to use them.

Named Templates

Named Template は、{{ define }} ... {{ end }} アクションで定義を行い、{{ template }}{{ include }} アクションで、その値を利用することとなります。

下記例では "sample.labels" という Named Template を定義しています。

sample/templates/_helpers.tpl

{{/*
Common labels
*/}}
{{- define "sample.labels" -}}
app.kubernetes.io/name: {{ .Release.Name | quote }}
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
app.kubernetes.io/instance: {{ .Release.Name | quote }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
...

下記例では、 {{ include }} アクションを用いて利用しています。

sample/templates/\developer.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name | quote }}
  labels:
    {{- include "sample.labels" . | nindent 4 }}
...

{{ template }} でなく、 {{ include }} しないと、パイプを介した関数の実行ができないため、{{ include }} が良いよというドキュメント。

Go provides a way of including one template in another using a built-in template directive. However, the built-in function cannot be used in Go template pipelines.

To make it possible to include a template, and then perform an operation on that template's output, Helm has a special include function:

Helm Docs - Using the 'include' Function

空白の管理

{{- xxx }} とか {{ XX -}} とか出てきているハイフンですが、これは Helm Template Lunguate を利用した行の空白を管理するものです。ハイフンの有無により空白の除去を実行してくれます。

First, the curly brace syntax of template declarations can be modified with special characters to tell the template engine to chomp whitespace. {{- (with the dash and space added) indicates that whitespace should be chomped left, while -}} means whitespace to the right should be consumed. Be careful! Newlines are whitespace!

Helm Docs - Controlling Whitespace

Chart のデバッグ

作成した Chart は、デバッグする方法が幾つか用意されています。

Helm Docs - Debugging Templates

リンターの実行。

$ helm lint ./sample
==> Linting ./sample

1 chart(s) linted, 0 chart(s) failed

helm lint

実行されるマニフェストファイルをレンダリングして表示。

$ helm template ./sample
---
# Source: sample/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: "release-name"
  labels:
    app.kubernetes.io/name: "release-name"
    helm.sh/chart: "sample-1.0.0"
    app.kubernetes.io/managed-by: "Helm"
    app.kubernetes.io/instance: "release-name"
    app.kubernetes.io/version: "2.0.0"
...

helm template

インストールのドライラン。

$ helm install test --dry-run --debug ./sample

helm install

作成した Chart の実行

それでは、Kubernetes 環境へ実際にインストールしてみます。

namespace zunda に、リソース名 zunda としてインストールします。

$ helm install --create-namespace -n zunda zunda ./sample
NAME: zunda
LAST DEPLOYED: Sun Nov  6 20:07:10 2022
NAMESPACE: zunda
STATUS: deployed
REVISION: 1
NOTES:
####  SAMPLE HELM CHART  ####

Chart Name: sample
Chart Version: 1.0.0
Chart Resource Name: zunda

The following resources have been managed.
- Deployment
  - gcr.io/google-samples/hello-app:2.0
- Service
  - ClusterIP

--create-namespace オプションを付与して実行すると、namespace が不在の場合に自動的に作成してくれます。

Automatically creating namespaces

以下の通りリソースが作成されています。

$ helm list -n zunda
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
zunda   zunda           1               2022-11-06 20:07:10.6808611 +0900 JST   deployed        sample-1.0.0    2.0.0

$ kubectl get pod,deployment,svc -n zunda
NAME                         READY   STATUS    RESTARTS   AGE
pod/zunda-6c578977db-l8sk7   1/1     Running   0          3m29s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/zunda   1/1     1            1           3m29s

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/zunda   ClusterIP   10.111.188.28   <none>        80/TCP    3m29s

values.yaml の値を上書きして実行(コマンドラインにて)

values.yaml で定義されたデフォルト値を、更新してインストールしてみます。--set オプションを利用することで上書きすることができ、Replica 3 つの Deployment に、Service を NodePort としてインストールしてみます。

$ helm install --create-namespace -n zunda zunda2 ./sample \
--set deployment.replicas.enabled=true \
--set deployment.replicas.replicaCount=3 \
--set service.type=NodePort
NAME: zunda2
LAST DEPLOYED: Sun Nov  6 20:17:00 2022
NAMESPACE: zunda
STATUS: deployed
REVISION: 1
NOTES:
####  SAMPLE HELM CHART  ####

Chart Name: sample
Chart Version: 1.0.0
Chart Resource Name: zunda2

The following resources have been managed.
- Deployment
  - gcr.io/google-samples/hello-app:2.0
- Service
  - NodePort

確認します。

$ helm list -n zunda
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
zunda   zunda           1               2022-11-06 20:07:10.6808611 +0900 JST   deployed        sample-1.0.0    2.0.0
zunda2  zunda           1               2022-11-06 20:17:00.1188276 +0900 JST   deployed        sample-1.0.0    2.0.0
$
$ kubectl get pod,deployment,svc,sa -n zunda -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
pod/zunda-6c578977db-l8sk7   1/1     Running   0          11m   172.17.0.2    minikube   <none>           <none>
pod/zunda2-7cd6998b-7kpfz    1/1     Running   0          79s   172.17.0.10   minikube   <none>           <none>
pod/zunda2-7cd6998b-9jtjq    1/1     Running   0          79s   172.17.0.8    minikube   <none>           <none>
pod/zunda2-7cd6998b-f8dz4    1/1     Running   0          79s   172.17.0.9    minikube   <none>           <none>

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                SELECTOR
deployment.apps/zunda    1/1     1            1           11m   zunda        gcr.io/google-samples/hello-app:2.0   app.kubernetes.io/instance=zunda,app.kubernetes.io/name=zunda
deployment.apps/zunda2   3/3     3            3           79s   zunda2       gcr.io/google-samples/hello-app:2.0   app.kubernetes.io/instance=zunda2,app.kubernetes.io/name=zunda2

NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/zunda    ClusterIP   10.111.188.28   <none>        80/TCP         11m   app.kubernetes.io/instance=zunda,app.kubernetes.io/name=zunda
service/zunda2   NodePort    10.109.49.124   <none>        80:32523/TCP   79s   app.kubernetes.io/instance=zunda2,app.kubernetes.io/name=zunda2

NAME                     SECRETS   AGE
serviceaccount/default   0         11m
$
$ minikube ip
192.168.49.2
$
$ curl http://192.168.49.2:32523
Hello, world!
Version: 2.0.0
Hostname: zunda2-7cd6998b-9jtjq

values.yaml の値を上書きして実行(ファイルを介して)

コマンドライン経由の他、values.yaml を上書きするファイルを作成して実行することもできます。

以下コマンドで、values の内容を config.yaml ファイルに出力。出力された config.yaml に対して、変更したい値を更新します。

$ helm show values ./sample > config.yaml

helm show values

-f オプションで上書きするファイルを指定して実行。

$ helm install --create-namespace -n zunda -f config.yaml zunda3 ./sample

テストの実行

templates/tests/ ディレクトリ配下においたマニフェストファイルは、helm test コマンドにより実行することができます。

Helm Docs - Chart Tests

今回は以下のマニフェストファイルを用意しています。curl を実行できるコンテナイメージから、curl コマンドを実行するものです。

sample/templates/tests/test.yaml

apiVersion: v1
kind: Pod
metadata:
  name: {{ .Release.Name }}-test
  labels:
    app: {{ .Release.Name }}-test
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: curl
      image: curlimages/curl
      command:
        - "curl"
      args:
        - "{{ .Release.Name }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.port }}"
  restartPolicy: Never

以下の様に出力されます。--logs オプションを付与すると、コンテナ上のログも出力してくれます。

$ helm test --logs -n zunda zunda
NAME: zunda
LAST DEPLOYED: Sun Nov  6 20:07:10 2022
NAMESPACE: zunda
STATUS: deployed
REVISION: 1
TEST SUITE:     zunda-test
Last Started:   Sun Nov  6 20:24:44 2022
Last Completed: Sun Nov  6 20:24:50 2022
Phase:          Succeeded
NOTES:
####  SAMPLE HELM CHART  ####

Chart Name: sample
Chart Version: 1.0.0
Chart Resource Name: zunda

The following resources have been managed.
- Deployment
  - gcr.io/google-samples/hello-app:2.0
- Service
  - ClusterIP

POD LOGS: zunda-test
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
Hello, world!
Version: 2.0.0
Hostname: zunda-6c578977db-l8sk7
100    62  100    62    0     0   8852      0 --:--:-- --:--:-- --:--:-- 10333

helm test

Helm Chart のリポジトリ

最後に、作成した Helm Chart をリポジトリ化して利用してみます。

リポジトリ化するには、index.yaml というファイルと、Chart 一式を固めた tar ファイルを、静的 WEB ホスティングサイトにアップロードすることで実現されます。静的 WEB ホスティングサイトとして、今回は GitHub Pages を利用します。

The Chart Repository Guide

helm package コマンドを利用することで、tar ファイルを作成してくれます。

$ helm package ./sample --destination <tarファイルの作成先パス>
Successfully packaged chart and saved it to: ../sample-1.0.0.tgz

helm package

tar ファイルを置いたパスを指定して helm repo index を実行すると、index.yamlファイル7を自動的に作成してくれます。

$ helm repo index <tarファイルがあるパス>
$ cat ../index.yaml
apiVersion: v1
entries:
  sample:
  - apiVersion: v2
    appVersion: 2.0.0
    created: "2022-11-06T20:41:54.2659454+09:00"
    description: Sample Helm Chart
    digest: 31f67984128e54967d4aa111368c4b9902ecd5e5239e0b3d1fccf1b5b99dea90
    icon: http://dummy.com/
    kubeVersion: '>= 1.25.0'
    name: sample
    type: application
    urls:
    - sample-1.0.0.tgz
    version: 1.0.0
generated: "2022-11-06T20:41:54.2650981+09:00"

helm repo index

この 2 つのファイルを静的 WEB サイトに置けばリポジトリ化してくれます。今回は、URL https://goodbyegangster.github.io/helm/GitHub Pages がリポジトリとなっています。

リポジトリ経由でインストールをしてみます。

$ helm repo add sample https://goodbyegangster.github.io/helm/
"sample" has been added to your repositories
$
$ helm repo list
NAME    URL
sample  https://goodbyegangster.github.io/helm/
$
$ helm install -n zunda zunda99 sample/sample
NAME: zunda99
LAST DEPLOYED: Sun Nov  6 20:54:19 2022
NAMESPACE: zunda
STATUS: deployed
REVISION: 1
NOTES:
####  SAMPLE HELM CHART  ####

Chart Name: sample
Chart Version: 1.0.0
Chart Resource Name: zunda99

The following resources have been managed.
- Deployment
  - gcr.io/google-samples/hello-app:2.0
- Service
  - ClusterIP
$
$ helm list -n zunda
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
zunda   zunda           1               2022-11-06 20:07:10.6808611 +0900 JST   deployed        sample-1.0.0    2.0.0
zunda2  zunda           1               2022-11-06 20:17:00.1188276 +0900 JST   deployed        sample-1.0.0    2.0.0
zunda3  zunda           1               2022-11-06 20:23:32.4401941 +0900 JST   deployed        sample-1.0.0    2.0.0
zunda99 zunda           1               2022-11-06 20:54:19.199032 +0900 JST    deployed        sample-1.0.0    2.0.0