1. 概要

Helmは、Kubernetesアプリケーションのパッケージマネージャーです。 このチュートリアルでは、Helmの基本と、HelmがKubernetesリソースを操作するための強力なツールを形成する方法を理解します。

過去数年間で、Kubernetesは驚異的な成長を遂げ、それをサポートするエコシステムも成長しました。 最近、Helmは Cloud Native Computing Foundation(CNCF)から卒業ステータスを獲得しました。これは、Kubernetesユーザーの間で人気が高まっていることを示しています。

2. バックグラウンド

これらの用語は最近、特にクラウドテクノロジーを使用している人々の間ではかなり一般的ですが、知らない人のためにすばやく調べてみましょう。

  1. Container Containerはオペレーティングシステムレベルの仮想化を指します。 複数のコンテナが、オペレーティングシステム内の隔離されたユーザースペースで実行されます。 コンテナ内で実行されているプログラムは、コンテナに割り当てられたリソースにのみアクセスできます。
  2. Docker Dockerは、コンテナーを作成して実行するための人気のあるプログラムです。 コンテナを管理するメインプログラムであるDockerデーモンが付属しています。 Docker Daemonは、Dockerコマンドラインインターフェイス(CLI)で使用されるDockerEngineAPIを介してその機能へのアクセスを提供します。 Docker の詳細については、この記事を参照してください。
  3. Kubernetes Kubernetesは人気のあるコンテナオーケストレーションプログラムです。 さまざまなコンテナで動作するように設計されていますが、Dockerが最もよく使用されます。 展開の自動化、スケーリング、ホストのクラスター全体での操作など、幅広い機能を提供します。 この記事では、さらに参照できるようにKubernetesの優れたカバレッジがあります

3. ヘルムアーキテクチャ

Helmは、Helm3の一部として大幅なアーキテクチャの向上を遂げました。 Helm 2と比較して、重要で待望の変更がいくつかあります。 Helm 3は、新しい機能セットをパックするだけでなく、内部配管の変更も備えています。 これらの変更のいくつかを調べます。

Helm 2は主に、クライアントとクラスター内サーバーで構成されるクライアントサーバーアーキテクチャ上にありました。

  • Tillerサーバー: Helmは、Kubernetesクラスター内にインストールされたTillerサーバーを介してKubernetesアプリケーションを管理します。 TillerはKubernetesAPIサーバーと対話して、Kubernetesリソースをインストール、アップグレード、クエリ、および削除します。
  • Helmクライアント: Helmは、ユーザーがHelmChartsを操作するためのコマンドラインインターフェイスを提供します。 Tillerサーバーと対話して、チャートのインストール、アップグレード、ロールバックなどのさまざまな操作を実行します。

Helm 3は完全にクライアント専用のアーキテクチャに移行し、クラスター内サーバーは削除されました。

ご覧のとおり、Helm 3のクライアントはほとんど同じように動作しますが、はTillerサーバーではなくKubernetesAPIサーバーと直接対話します。 この移動により、Helmのアーキテクチャが簡素化され、Kubernetesユーザークラスターのセキュリティを活用できるようになりました。

4. ヘルムチャート、リリース、およびリポジトリ

Helmは、チャートを介してKubernetesリソースパッケージを管理します。 チャートは基本的にHelmのパッケージ形式です。 チャートインフラストラクチャも、Helm2と比較してHelm3の一部としていくつかの変更が加えられています。

チャートとHelm3の変更点については、間もなく作成します。 ただし、現時点では、Kubernetesクラスターを前提として、チャートはKubernetesアプリケーションを作成するために必要な一連の情報にすぎません。

  • チャートは、特定のディレクトリ構造に編成されたファイルのコレクションです。
  • チャートに関連する構成情報は、構成で管理されます
  • 最後に、特定の構成を持つチャートの実行中のインスタンスはリリースと呼ばれます

Helm 3は、ライブラリチャートの概念も導入しました。 基本的に、ライブラリチャートは、チャートプリミティブまたは定義を定義するために使用できる一般的なチャートのサポートを有効にします。 これは、チャート間で再利用できるコードのスニペットを共有するのに役立ちます。

Helm は、releases を使用して、Kubernetesクラスターにインストールされているチャートを追跡します。 これにより、クラスター内の異なるリリースで単一のチャートを複数回インストールできます。 Helm 2まで、リリースはConfigMapsまたはSecretsとしてクラスターのTiller名前空間に保存されていました。 Helm 3以降、リリースはデフォルトでシークレットとしてリリースの名前空間に直接保存されます。

最後に、リポジトリを介してアーカイブとしてチャートを共有できます。 基本的には、パッケージチャートを保存および共有できる場所です。 Artifact Hub という名前の分散型コミュニティチャートリポジトリがあり、ここで共同作業を行うことができます。 独自のプライベートチャートリポジトリを作成することもできます。 使用するチャートリポジトリをいくつでも追加できます。

5. 前提条件

最初のヘルムチャートを作成するには、事前にいくつかの設定が必要です。

まず、Helmでの作業を開始するには、Kubernetesクラスターが必要です。 このチュートリアルでは、 Minikubeを使用します。これは、単一ノードのKubernetesクラスターをローカルで操作するための優れた方法を提供します。 Windowsでは、Minikubeを実行するためのネイティブハイパーバイザーとしてHyper-Vを使用できるようになりました。 Minikubeの設定の詳細については、この記事を参照してください

多くの場合、Helm でサポートされているとして、最も互換性のあるバージョンのKubernetesをインストールすることをお勧めします。 また、Kubernetesコマンドラインツール kubectlをインストールして構成し、がクラスターを効率的に操作できるようにする必要があります。

また、Kubernetesクラスター内で管理するための基本的なアプリケーションが必要です。 このチュートリアルでは、Dockerコンテナとしてパッケージ化された単純なSpring Bootアプリケーションを使用します。 Dockerコンテナーなどのアプリケーションをパッケージ化する方法の詳細については、この記事を参照してください。

6. Helmのインストール

Helmをインストールする方法はいくつかありますが、Helmの公式インストールページで詳しく説明されています。 Windowsにhelmをインストールする最も簡単な方法は、Windowsプラットフォーム用のパッケージマネージャーであるChocolatyを使用することです。

Chocolatyを使用すると、Helmをインストールするための簡単な1行のコマンドです。

choco install kubernetes-helm

これにより、Helmクライアントがローカルにインストールされます。 これにより、このチュートリアルでHelmを操作するために使用するHelmコマンドラインツールも提供されます。

先に進む前に、 Kubernetesクラスターが実行され kubectl コマンドを使用してアクセスできることを確認する必要があります

kubectl cluster-info

さて、Helm 2までは、Helmを初期化する必要もありました。 これにより、Tillerサーバーが効果的にインストールされ、KubernetesクラスターにHelm状態が設定されます。 次のコマンドを使用して、HelmCLIからHelmを初期化できます。

helm init

ただし、Helm 3以降、Tillerサーバーがなくなったため、Helmを初期化する必要はありません。 実際、このコマンドは削除されました。 したがって、必要に応じてヘルム状態が自動的に作成されます。

7. 最初のチャートの作成

これで、テンプレートと値を使用して最初のヘルムチャートを作成する準備が整いました。 以前にインストールしたHelmCLIを使用して、チャートに関連する一般的なアクティビティのいくつかを実行します。

7.1. チャートの作成

もちろん、最初のステップは、指定された名前で新しいグラフを作成することです。

helm create hello-world

ここで提供されるチャートの名は、チャートが作成され保存されるディレクトリの名前になることに注意してください。

私たちのために作成されたディレクトリ構造を簡単に見てみましょう。

hello-world /
  Chart.yaml
  values.yaml
  templates /
  charts /
  .helmignore

私たちのために作成されたこれらのファイルとフォルダの関連性を理解しましょう:

  • Chart.yaml :これはチャートの説明を含むメインファイルです
  • values.yaml :これはチャートのデフォルト値を含むファイルです
  • templates :これはKubernetesリソースがテンプレートとして定義されているディレクトリです
  • charts :これはサブチャートを含む可能性のあるオプションのディレクトリです
  • .helmignore :これは、パッケージ化時に無視するパターンを定義できる場所です(.gitignoreと概念が似ています)

7.2. テンプレートの作成

テンプレートディレクトリ内を見ると、一般的なKubernetesリソース用のいくつかのテンプレートがすでに作成されていることがわかります

hello-world /
  templates /
    deployment.yaml
    service.yaml
    ingress.yaml
    ......

これらのリソースの一部と、場合によっては他のリソースがアプリケーションに必要になる場合があります。これらのリソースは、テンプレートとして自分で作成する必要があります。

このチュートリアルでは、デプロイメントとそのデプロイメントを公開するためのサービスを作成します。 ここで強調しているのは、Kubernetesを詳細に理解することではないことに注意してください。 したがって、これらのリソースは可能な限りシンプルに保ちます。

templatesディレクトリ内のファイルdeployment.yamlを次のように編集してみましょう。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "hello-world.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ include "hello-world.name" . }}
    helm.sh/chart: {{ include "hello-world.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "hello-world.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "hello-world.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP

同様に、ファイルservice.yamlを次のように編集してみましょう。

apiVersion: v1
kind: Service
metadata:
  name: {{ include "hello-world.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ include "hello-world.name" . }}
    helm.sh/chart: {{ include "hello-world.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: {{ include "hello-world.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}

さて、Kubernetesの知識があると、これらのテンプレートファイルは、いくつかの奇妙な点を除いて、非常によく知られているように見えます。 二重括弧{{}}内のテキストの自由な使用法に注意してください。 これは、いわゆるテンプレートディレクティブです。

HelmはGoテンプレート言語を利用し、それをHelmテンプレート言語と呼ばれるものに拡張します。評価中、テンプレートディレクトリ内のすべてのファイルがテンプレートレンダリングエンジンに送信されます。 これは、テンプレートディレクティブが実際の値をテンプレートに挿入する場所です。

7.3. 価値の提供

前のサブセクションでは、テンプレートでテンプレートディレクティブを使用する方法を説明しました。 それでは、テンプレートレンダリングエンジンに値を渡す方法を理解しましょう。 通常、Helmの組み込みオブジェクトを介して値を渡します。

リリース、値、グラフ、ファイルなど、Helmで利用できるそのようなオブジェクトはたくさんあります。

チャートのファイルvalues.yamlを使用して、組み込みオブジェクト値を介してテンプレートレンダリングエンジンに値を渡すことができます。 values.yamlを次のように変更してみましょう。

replicaCount: 1
image:
  repository: "hello-world"
  tag: "1.0"
  pullPolicy: IfNotPresent
service:
  type: NodePort
  port: 80

ただし、名前空間を区切るドットを使用して、テンプレート内でこれらの値にアクセスする方法に注意してください。 イメージリポジトリとタグを「hello-world」と「1.0」として使用しました。これは、SpringBootアプリケーション用に作成したdockerイメージタグと一致する必要があります。

8. チャートの管理

これまでにすべてが完了したので、チャートを試す準備が整いました。 これを楽しくするためにHelmCLIで使用できるさまざまなコマンドを見てみましょう。 Helmで使用可能なコマンドの一部のみを取り上げることに注意してください。

8.1. ヘルムリント

まず、これはチャートへのパスを取得し、一連のテストを実行してチャートが整形式であることを確認する単純なコマンドです。

helm lint ./hello-world
==> Linting ./hello-world
1 chart(s) linted, no failures

出力には、特定した問題を含むリンティングの結果が表示されます。

8.2. ヘルムテンプレート

また、このコマンドを使用して、テンプレートをローカルにレンダリングし、すばやくフィードバックできるようにします。

helm template ./hello-world
---
# Source: hello-world/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: release-name-hello-world
  labels:
    app.kubernetes.io/name: hello-world
    helm.sh/chart: hello-world-0.1.0
    app.kubernetes.io/instance: release-name
    app.kubernetes.io/managed-by: Tiller
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: hello-world
    app.kubernetes.io/instance: release-name

---
# Source: hello-world/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: release-name-hello-world
  labels:
    app.kubernetes.io/name: hello-world
    helm.sh/chart: hello-world-0.1.0
    app.kubernetes.io/instance: release-name
    app.kubernetes.io/managed-by: Tiller
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: hello-world
      app.kubernetes.io/instance: release-name
  template:
    metadata:
      labels:
        app.kubernetes.io/name: hello-world
        app.kubernetes.io/instance: release-name
    spec:
      containers:
        - name: hello-world
          image: "hello-world:1.0"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP

このコマンドは、クラスターで取得されることが期待される値を偽造することに注意してください。

8.3. ヘルムインストール

グラフが正常であることを確認したら、最後に次のコマンドを実行してグラフをKubernetesクラスターにインストールできます。

helm install --name hello-world ./hello-world
NAME:   hello-world
LAST DEPLOYED: Mon Feb 25 15:29:59 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME         TYPE      CLUSTER-IP     EXTERNAL-IP  PORT(S)       AGE
hello-world  NodePort  10.110.63.169  <none>       80:30439/TCP  1s

==> v1/Deployment
NAME         DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
hello-world  1        0        0           0          1s

==> v1/Pod(related)
NAME                          READY  STATUS   RESTARTS  AGE
hello-world-7758b9cdf8-cs798  0/1    Pending  0         0s

このコマンドには、グラフの値を上書きするためのいくつかのオプションもあります。 このチャートのリリースには、フラグ–nameを付けていることに注意してください。 このコマンドは、プロセスで作成されたKubernetesリソースの概要で応答します。

8.4. ヘルムゲット

ここで、どのチャートがどのリリースとしてインストールされているかを確認したいと思います。 このコマンドを使用すると、名前付きリリースを照会できます。

helm ls --all
NAME            REVISION        UPDATED                         STATUS          CHART               APP VERSION NAMESPACE
hello-world     1               Mon Feb 25 15:29:59 2019        DEPLOYED        hello-world-0.1.0   1.0         default

このコマンドで拡張情報を取得するために使用できるサブコマンドがいくつかあります。 これらには、すべて、フック、マニフェスト、音価、および値が含まれます。

8.5. ヘルムアップグレード

チャートを変更し、更新されたバージョンをインストールする必要がある場合はどうなりますか? このコマンドは、リリースを指定されたバージョンまたは現在のバージョンのチャートまたは構成にアップグレードするのに役立ちます。

helm upgrade hello-world ./hello-world
Release "hello-world" has been upgraded. Happy Helming!
LAST DEPLOYED: Mon Feb 25 15:36:04 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME         TYPE      CLUSTER-IP     EXTERNAL-IP  PORT(S)       AGE
hello-world  NodePort  10.110.63.169  <none>       80:30439/TCP  6m5s

==> v1/Deployment
NAME         DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
hello-world  1        1        1           1          6m5s

==> v1/Pod(related)
NAME                          READY  STATUS   RESTARTS  AGE
hello-world-7758b9cdf8-cs798  1/1    Running  0         6m4s

Helm 3では、リリースアップグレードで3方向の戦略的マージパッチが使用されることに注意してください。 ここでは、パッチを生成するときに、古いマニフェスト、クラスターのライブ状態、および新しいものを考慮します。 Helm 2は、Helmの外部のクラスターに適用された変更を破棄する双方向の戦略的マージパッチを使用しました。

8.6. ヘルムロールバック

リリースが失敗し、取り戻す必要がある場合は常に発生する可能性があります。 これは、リリースを以前のバージョンにロールバックするコマンドです。

helm rollback hello-world 1
Rollback was a success! Happy Helming!

ロールバックする特定のバージョンを指定するか、この引数を黒のままにすることができます。その場合、前のバージョンにロールバックします。

8.7. ヘルムアンインストール

可能性は低いですが、リリースを完全にアンインストールすることをお勧めします。 このコマンドを使用して、Kubernetesからリリースをアンインストールできます。

helm uninstall hello-world
release "hello-world" deleted

チャートの最後のリリースとリリース履歴に関連するすべてのリソースが削除されます。

9. チャートの配布

テンプレートは、HelmがKubernetesリソースを管理する世界にもたらす強力なツールですが、Helmを使用する利点はそれだけではありません。 前のセクションで見たように、HelmはKubernetesアプリケーションのパッケージマネージャーとして機能し、リリースのインストール、クエリ、アップグレード、削除を非常にシームレスにします。

これに加えて、Helmを使用して、Kubernetesアプリケーションをチャートアーカイブとしてパッケージ化、公開、フェッチすることもできます。 Helm CLIは、これらのアクティビティを実行するためのいくつかのコマンドを提供するため、これに使用することもできます。 以前と同様に、使用可能なすべてのコマンドについて説明するわけではありません。

9.1. ヘルムパッケージ

まず、作成したチャートをパッケージ化して配布できるようにする必要があります。 これは、チャートのバージョン管理されたアーカイブファイルを作成するためのコマンドです。

helm package ./hello-world
Successfully packaged chart and saved it to: \hello-world\hello-world-0.1.0.tgz

手動で、またはパブリックまたはプライベートのチャートリポジトリを介して配布できるアーカイブがマシン上に生成されることに注意してください。 チャートアーカイブに署名するオプションもあります。

9.2. ヘルムレポ

最後に、共有リポジトリと連携するためのメカニズムが必要です。 このコマンドには、チャートリポジトリの追加、削除、更新、一覧表示、またはインデックス作成に使用できるいくつかのサブコマンドがあります。 それらの使い方を見てみましょう。

gitリポジトリを作成し、それを使用してチャートリポジトリとして機能させることができます。唯一の要件は、index.yamlファイルが必要です。

チャートリポジトリ用にindex.yamlを作成できます。

helm repo index my-repo/ --url https://<username>.github.io/my-repo

これにより、 index.yaml ファイルが生成されます。このファイルは、チャートアーカイブとともにリポジトリにプッシュする必要があります。

チャートリポジトリが正常に作成されたら、その後、このリポジトリをリモートで追加できます。

helm repo add my-repo https://my-pages.github.io/my-repo

これで、リポジトリからチャートを直接インストールできるようになります。

helm install my-repo/hello-world --name=hello-world

チャートリポジトリを操作するために利用できるコマンドはかなりたくさんあります。

9.3. ヘルムサーチ

最後に、パブリックまたはプライベートのチャートリポジトリに存在する可能性のあるチャート内のキーワードを検索する必要があります。

helm search repo <KEYWORD>

このコマンドで使用できるサブコマンドがあり、チャートのさまざまな場所を検索できます。 たとえば、ArtifactHubまたは独自のリポジトリでチャートを検索できます。 さらに、構成したすべてのリポジトリで使用可能なチャートでキーワードを検索できます。

10. Helm2からHelm3への移行

Helmはしばらく使用されているため、Helm3の一部として大幅な変更が加えられたHelm2の将来を疑うことは明らかです。 新たに開始する場合はHelm3から開始することをお勧めしますが、Helm2のサポートは近い将来Helm3で継続されます。 ただし、注意点があるため、必要な調整を行う必要があります。

注意すべき重要な変更のいくつかには、Helm3がリリース名を自動的に生成しなくなったことが含まれます。 ただし、リリース名を生成するために使用できる必要なフラグがあります。 さらに、リリースの作成時に名前名は作成されなくなりました。 事前に名前名を作成しておく必要があります。

ただし、Helm 2を使用し、Helm3への移行を希望するプロジェクトにはいくつかのオプションがあります。 まず、Helm2とHelm3を使用して同じクラスターを管理し、Helm3を新しいリリースに使用しながらHelm2リリースをゆっくりと排出することができます。 または、Helm3を使用してHelm2リリースを管理することもできます。 これには注意が必要ですが、Helmはこのタイプの移行を処理するプラグインを提供しています。

11. 結論

要約すると、このチュートリアルでは、KubernetesアプリケーションのパッケージマネージャーであるHelmのコアコンポーネントについて説明しました。 Helmをインストールするオプションを理解しました。 さらに、値を使用してサンプルのグラフとテンプレートを作成しました。

次に、Helm CLIの一部として利用できる複数のコマンドを実行して、KubernetesアプリケーションをHelmパッケージとして管理しました。 最後に、リポジトリを介してHelmパッケージを配布するためのオプションについて説明しました。 その過程で、Helm2と比較してHelm3の一部として行われた変更を確認しました。