ローカル Helm チャートのデプロイ

KubernetesBeginner
オンラインで実践に進む

はじめに

これまでのデプロイメントに関する実験では、Kubernetes のマニフェストファイルを直接使用してきました。Helm は、それらのマニフェストをパッケージ化するレイヤーを追加するツールです。Helm チャートは、関連する Kubernetes テンプレートをまとめて管理し、再利用可能な設定を values.yaml で公開し、レンダリングされたオブジェクトを「リリース」としてインストールします。

この実験では、リポジトリからダウンロードするのではなく、小規模なローカルチャートをゼロから作成します。チャートのメタデータ、値(values)、Deployment テンプレート、Service テンプレートを記述し、インストール前にチャートをレンダリングし、値を変更してリリースをアップグレードします。これにより、ローカルチャートがどのようにして通常の Kubernetes オブジェクトに変換されるのかという、CKAD で求められるスキルを重点的に学習します。

Helm ワークスペースの準備

このステップでは、名前空間(namespace)を準備し、ローカル Helm チャートのワークフローに必要なツールが揃っているかを確認します。

まずは /home/labex/project から始めます。この実験では、チャートディレクトリ、生成されたマニフェスト、およびすべてのコマンドをこのワークスペース内で管理します。

mkdir -p /home/labex/project
cd /home/labex/project

Kubernetes API サーバーに接続できるか確認します。VM が起動した直後でノードの準備ができていない場合は、数秒待ってから再度コマンドを実行してください。

kubectl get nodes --request-timeout=5s

以下のような出力が表示されれば成功です:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

クラスターネットワークの Pod が「Ready」になるまで待ちます。チャートによって Service が作成されるため、トラフィックテストを行う前にアプリケーション Pod がクラスターネットワークに接続されている必要があります。

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

期待される出力:

pod/calico-node-... condition met

ckad-prep-helm という名前の名前空間を作成し、現在の名前空間として設定します:

kubectl create namespace ckad-prep-helm
kubectl config set-context --current --namespace=ckad-prep-helm

現在の名前空間と Helm クライアントを確認します。Helm 3 は現在の kubeconfig を使用して直接 Kubernetes と連携するため、サーバー側に Tiller コンポーネントを別途インストールする必要はありません。

kubectl config view --minify --output 'jsonpath={..namespace}'; echo
helm version --short

以下のような出力が表示されれば成功です:

ckad-prep-helm
v...

ローカルチャートの作成とレンダリング

このステップでは、最小限のローカル Helm チャートを作成し、インストール前にレンダリングを行います。

チャートディレクトリにはいくつかの重要な構成要素があります。Chart.yaml はチャート自体を記述し、values.yaml にはデフォルト設定が含まれます。templates/ 配下のファイルは、{{ .Values.replicaCount }} のようなテンプレート式を含む Kubernetes マニフェストです。Helm はチャートをレンダリングまたはインストールする際、これらの式を具体的な値に置き換えます。

チャートディレクトリを作成します:

mkdir -p local-web-chart/templates

Chart.yaml を作成します。チャート名はリリース名とは異なります。リリース名はチャートをインストールする際に指定します。

cat > local-web-chart/Chart.yaml <<'EOF'
apiVersion: v2
name: local-web
description: A small local chart for CKAD deployment practice
type: application
version: 0.1.0
appVersion: "1.0"
EOF

values.yaml を作成します。これらのデフォルト値は、Pod の数、コンテナイメージ、Service のポート、およびアプリケーションが返すメッセージを制御します。

cat > local-web-chart/values.yaml <<'EOF'
replicaCount: 2
image:
  repository: busybox
  tag: "1.36"
service:
  port: 80
  targetPort: 8080
message: helm-v1
EOF

Deployment テンプレートを作成します。テンプレート内でリリース名({{ .Release.Name }})を使用することで、同じチャートを異なるリリース名でインストールできるようになります。

cat > local-web-chart/templates/deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-web
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/instance: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ .Chart.Name }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ .Chart.Name }}
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: web
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: IfNotPresent
        command:
        - /bin/sh
        - -c
        - |
          mkdir -p /www
          echo {{ .Values.message | quote }} > /www/index.html
          httpd -f -p {{ .Values.service.targetPort }} -h /www
        ports:
        - containerPort: {{ .Values.service.targetPort }}
        readinessProbe:
          httpGet:
            path: /
            port: {{ .Values.service.targetPort }}
          initialDelaySeconds: 1
          periodSeconds: 2
EOF

Service テンプレートを作成します。Service のセレクターが Pod テンプレートと同じラベルを使用していることに注目してください。

cat > local-web-chart/templates/service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/instance: {{ .Release.Name }}
spec:
  selector:
    app.kubernetes.io/name: {{ .Chart.Name }}
    app.kubernetes.io/instance: {{ .Release.Name }}
  ports:
  - port: {{ .Values.service.port }}
    targetPort: {{ .Values.service.targetPort }}
EOF

helm lint を実行して、チャートの構造やテンプレートに問題がないか確認します:

helm lint ./local-web-chart

以下のような出力が表示されれば成功です:

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

チャートをローカルでレンダリングします。helm template は、Helm が API サーバーに送信する Kubernetes YAML を表示しますが、実際にはオブジェクトを作成しません。

helm template local-web ./local-web-chart | sed -n '1,120p'

local-web という名前の Service と local-web-web という名前の Deployment が含まれていることが確認できます。

チャートのリリースとしてのインストール

このステップでは、ローカルチャートを ckad-prep-helm 名前空間にインストールします。

チャートをインストールすると Helm リリースが作成されます。この実験ではリリース名を local-web とします。Helm はリリースのメタデータを記録し、Kubernetes は Deployment や Service といった通常のオブジェクトを受け取ります。

チャートをインストールします:

helm install local-web ./local-web-chart

以下のような出力が表示されれば成功です:

NAME: local-web
STATUS: deployed

チャートによって作成された Deployment の完了を待ちます:

kubectl rollout status deployment/local-web-web --timeout=120s

期待される出力:

deployment "local-web-web" successfully rolled out

リリースと、それによって作成された Kubernetes オブジェクトを確認します:

helm list
kubectl get deployment,service -l app.kubernetes.io/instance=local-web

以下のような出力が表示されます:

local-web
deployment.apps/local-web-web
service/local-web

クライアント Pod を作成し、Service にリクエストを送信します。これにより、チャートが単にオブジェクトを作成しただけでなく、インストールされたアプリケーションが実際にアクセス可能であることが確認できます。

kubectl run chart-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/chart-client --timeout=120s
kubectl exec chart-client -- wget -qO- http://local-web

期待される出力:

helm-v1

新しい値によるリリースのアップグレード

このステップでは、チャートの値を上書きして既存のリリースをアップグレードします。

チャートにはすでに再利用可能なテンプレートが含まれています。メッセージやレプリカ数を変更するためにテンプレートファイルを編集する必要はありません。helm upgrade を実行すると、新しい値でチャートが再レンダリングされ、Kubernetes オブジェクトが更新され、新しいリリースリビジョンが記録されます。

リリースをアップグレードし、3 つのレプリカで helm-v2 を提供するように変更します:

helm upgrade local-web ./local-web-chart --set message=helm-v2 --set replicaCount=3

以下のような出力が表示されれば成功です:

Release "local-web" has been upgraded.
STATUS: deployed

アップグレードされた Deployment の完了を待ちます:

kubectl rollout status deployment/local-web-web --timeout=120s

期待される出力:

deployment "local-web-web" successfully rolled out

リリース履歴と、現在リリースに保存されている値を確認します:

helm history local-web
helm get values local-web

2 つのリビジョンと上書きされた値が表示されます:

REVISION
1
2
message: helm-v2
replicaCount: 3

実行中の Deployment とアプリケーションの応答を確認します:

kubectl get deployment local-web-web
kubectl exec chart-client -- wget -qO- http://local-web

以下のような出力が表示されます:

3/3
helm-v2

まとめ

チャートのメタデータ、デフォルト値、および Kubernetes テンプレートからローカル Helm チャートを作成しました。インストール前にチャートをレンダリングし、リリースとしてインストールし、Service をテストし、値を上書きしてリリースをアップグレードしました。重要なポイントは、Helm は反復可能なアプリケーションデプロイメント作業をパッケージ化しつつ、kubectl で確認可能な通常の Kubernetes オブジェクトを生成するということです。