ライブラリチャート

ライブラリチャートは、他のチャートの Helm テンプレートで共有できるチャートのプリミティブまたは定義を定義する Helm チャート の一種です。これにより、ユーザーはチャート全体で再利用できるコードスニペットを共有し、繰り返しを回避し、チャートを DRY に保つことができます。

ライブラリチャートは、Helm 2 以降、チャートメンテナーが使用してきた共通またはヘルパーチャートを正式に認識するために、Helm 3 で導入されました。チャートタイプとして含めることで、以下が提供されます。

  • 共通チャートとアプリケーションチャートを明確に区別する手段
  • 共通チャートのインストールを防止するロジック
  • リリース成果物を含む可能性がある共通チャートでのテンプレートのレンダリングをしない
  • 依存チャートがインポーターのコンテキストを使用できるようにする

チャートメンテナーは、共通チャートをライブラリチャートとして定義でき、Helm が標準の一貫した方法でチャートを処理することを確信できます。これはまた、アプリケーションチャートの定義をチャートタイプを変更することで共有できることを意味します。

シンプルなライブラリチャートの作成

前に述べたように、ライブラリチャートは Helm チャート の一種です。つまり、まずスキャフォールドチャートを作成することから始められます。

$ helm create mylibchart
Creating mylibchart

まず、この例では独自のテンプレート定義を作成するため、templates ディレクトリ内のすべてのファイルを削除します。

$ rm -rf mylibchart/templates/*

値ファイルも不要になります。

$ rm -f mylibchart/values.yaml

共通コードの作成に入る前に、関連する Helm の概念を簡単に確認しましょう。名前付きテンプレート (部分テンプレートまたはサブテンプレートと呼ばれることもあります) は、ファイル内で定義され、名前が付けられたテンプレートにすぎません。templates/ ディレクトリでは、アンダースコア(_) で始まるファイルは Kubernetes マニフェストファイルを出力しないと想定されています。したがって、慣例的に、ヘルパーテンプレートと部分テンプレートは _*.tpl または _*.yaml ファイルに配置されます。

この例では、空の ConfigMap リソースを作成する共通 ConfigMap をコーディングします。共通 ConfigMap をファイル mylibchart/templates/_configmap.yaml で次のように定義します。

{{- define "mylibchart.configmap.tpl" -}}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data: {}
{{- end -}}
{{- define "mylibchart.configmap" -}}
{{- include "mylibchart.util.merge" (append . "mylibchart.configmap.tpl") -}}
{{- end -}}

ConfigMap コンストラクトは、名前付きテンプレート mylibchart.configmap.tpl で定義されています。これは、空のリソースである data を持つシンプルな ConfigMap です。このファイル内には、mylibchart.configmap という別の名前付きテンプレートがあります。この名前付きテンプレートには、mylibchart.util.merge という別の名前付きテンプレートが含まれています。これは、mylibchart.configmap を呼び出すテンプレートと mylibchart.configmap.tpl の 2 つの名前付きテンプレートを引数として受け取ります。

ヘルパー関数 mylibchart.util.merge は、mylibchart/templates/_util.yaml の名前付きテンプレートです。これは 共通 Helm ヘルパーチャート の便利なユーティリティで、2 つのテンプレートをマージし、両方の共通部分を上書きします。

{{- /*
mylibchart.util.merge will merge two YAML templates and output the result.
This takes an array of three values:
- the top context
- the template name of the overrides (destination)
- the template name of the base (source)
*/}}
{{- define "mylibchart.util.merge" -}}
{{- $top := first . -}}
{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}}
{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}}
{{- toYaml (merge $overrides $tpl) -}}
{{- end -}}

これは、チャートが構成でカスタマイズする必要のある共通コードを使用する場合に重要です。

最後に、チャートタイプを library に変更しましょう。これには、mylibchart/Chart.yaml を次のように編集する必要があります。

apiVersion: v2
name: mylibchart
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
# type: application
type: library

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application and it is recommended to use it with quotes.
appVersion: "1.16.0"

これで、ライブラリチャートを共有し、ConfigMap の定義を再利用する準備が整いました。

次に進む前に、Helm がチャートをライブラリチャートとして認識しているかどうかを確認する価値があります。

$ helm install mylibchart mylibchart/
Error: library charts are not installable

シンプルなライブラリチャートの使用

ライブラリチャートを使用する時が来ました。これは、再びスキャフォールドチャートを作成することを意味します。

$ helm create mychart
Creating mychart

ConfigMap のみを作成するため、テンプレートファイルを再度クリーンアップしましょう。

$ rm -rf mychart/templates/*

Helm テンプレートでシンプルな ConfigMap を作成する場合、次のようになります。

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name | printf "%s-%s" .Chart.Name }}
data:
  myvalue: "Hello World"

ただし、mylibchart で既に作成した共通コードを再利用します。ConfigMap は、ファイル mychart/templates/configmap.yaml で次のように作成できます。

{{- include "mylibchart.configmap" (list . "mychart.configmap") -}}
{{- define "mychart.configmap" -}}
data:
  myvalue: "Hello World"
{{- end -}}

共通の ConfigMap の標準プロパティを追加する共通の ConfigMap 定義を継承することで、行う必要がある作業が簡略化されていることがわかります。テンプレートでは、構成を追加します。この場合、データキー myvalue とその値です。構成は、共通の ConfigMap の空のリソースを上書きします。これは、前のセクションで述べたヘルパー関数 mylibchart.util.merge のおかげで可能です。

共通コードを使用できるようにするには、mylibchart を依存関係として追加する必要があります。ファイル mychart/Chart.yaml の最後に次を追加します。

# My common code in my library chart
dependencies:
- name: mylibchart
  version: 0.1.0
  repository: file://../mylibchart

これにより、ライブラリチャートが、アプリケーションチャートと同じ親パスにあるファイルシステムからの動的な依存関係として含まれます。ライブラリチャートを動的な依存関係として含めているため、helm dependency update を実行する必要があります。ライブラリチャートが charts/ ディレクトリにコピーされます。

$ helm dependency update mychart/
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Deleting outdated charts

これで、チャートをデプロイする準備が整いました。インストールする前に、まずレンダリングされたテンプレートを確認する価値があります。

$ helm install mydemo mychart/ --debug --dry-run
install.go:159: [debug] Original chart version: ""
install.go:176: [debug] CHART PATH: /root/test/helm-charts/mychart

NAME: mydemo
LAST DEPLOYED: Tue Mar  3 17:48:47 2020
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
affinity: {}
fullnameOverride: ""
image:
  pullPolicy: IfNotPresent
  repository: nginx
imagePullSecrets: []
ingress:
  annotations: {}
  enabled: false
  hosts:
  - host: chart-example.local
    paths: []
  tls: []
mylibchart:
  global: {}
nameOverride: ""
nodeSelector: {}
podSecurityContext: {}
replicaCount: 1
resources: {}
securityContext: {}
service:
  port: 80
  type: ClusterIP
serviceAccount:
  annotations: {}
  create: true
  name: null
tolerations: []

HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
  myvalue: Hello World
kind: ConfigMap
metadata:
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: mydemo
  name: mychart-mydemo

これは、myvalue: Hello World のデータ上書きを含む、必要な ConfigMap のようです。インストールしてみましょう。

$ helm install mydemo mychart/
NAME: mydemo
LAST DEPLOYED: Tue Mar  3 17:52:40 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

リリースを取得し、実際のテンプレートがロードされたことを確認できます。

$ helm get manifest mydemo
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
data:
  myvalue: Hello World
kind: ConfigMap
metadata:
  labels:
    app: mychart
    chart: mychart-0.1.0
    release: mydemo
  name: mychart-mydemo

ライブラリチャートのメリット

ライブラリチャートはスタンドアロンチャートとして機能しないため、次の機能を利用できます。

  • .Files オブジェクトは、ライブラリチャートのローカルパスではなく、親チャートのファイルパスを参照します
  • .Values オブジェクトは、アプリケーションの サブチャート とは対照的に、親チャートと同じです。サブチャートは、親のヘッダーの下に構成された値のセクションを受け取ります。

共通 Helm ヘルパーチャート

Note: The Common Helm Helper Chart repo on Github is no longer actively maintained, and the repo has been deprecated and archived.

この チャート は、共通チャートの元のパターンでした。これは、Kubernetes チャート開発のベストプラクティスを反映したユーティリティを提供します。何よりも、チャートを開発するときにすぐに使用して、便利な共有コードを提供できます。

ここでは、それを使用するための簡単な方法を示します。詳細については、README を参照してください。

再びスキャフォールドチャートを作成します。

$ helm create demo
Creating demo

ヘルパーチャートからの共通コードを使用してみましょう。まず、デプロイメント demo/templates/deployment.yaml を次のように編集します。

{{- template "common.deployment" (list . "demo.deployment") -}}
{{- define "demo.deployment" -}}
## Define overrides for your Deployment resource here, e.g.
apiVersion: apps/v1
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "demo.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "demo.selectorLabels" . | nindent 8 }}

{{- end -}}

そして、サービスファイル demo/templates/service.yaml を次のように編集します。

{{- template "common.service" (list . "demo.service") -}}
{{- define "demo.service" -}}
## Define overrides for your Service resource here, e.g.
# metadata:
#   labels:
#     custom: label
# spec:
#   ports:
#   - port: 8080
{{- end -}}

これらのテンプレートは、ヘルパーチャートからの共通コードを継承することで、コーディングがリソースの構成またはカスタマイズにまで簡略化される方法を示しています。

共通コードを使用できるようにするには、common を依存関係として追加する必要があります。ファイル demo/Chart.yaml の最後に次を追加します。

dependencies:
- name: common
  version: "^0.0.5"
  repository: "https://charts.helm.sh/incubator/"

注: incubator リポジトリを Helm リポジトリリスト (helm repo add) に追加する必要があります。

チャートを動的な依存関係として含めているため、helm dependency update を実行する必要があります。ヘルパーチャートが charts/ ディレクトリにコピーされます。

ヘルパーチャートは一部の Helm 2 コンストラクトを使用しているため、Helm 3 スキャフォールドチャートで更新されたため、nginx イメージをロードできるようにするために、demo/values.yaml に次を追加する必要があります。

image:
  tag: 1.16.0

helm lint コマンドと helm template コマンドを使用して、デプロイする前にチャートテンプレートが正しいことをテストできます。

問題がなければ、helm install を使用してデプロイしてください。