2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kubernetesを学ぶ9日間 - Day 6: Helm と Kustomize の使い分け

Last updated at Posted at 2025-12-10

はじめに

「ジャンルなしオンラインもくもく会 Advent Calendar 2025」の10日目の記事です。

Week 1ではTalos Linuxを使ってKubernetesクラスタを構築し、監視スタックまで導入しました。Week 2では、構築したクラスタで運用自動化に取り組みます。

今日のテーマはマニフェスト管理です。Kubernetes運用で避けて通れない「環境ごとの設定差分をどう管理するか」という課題に、HelmとKustomizeという2つの代表的なツールで挑みます。

本シリーズの全体構成

前回のおさらい

ポイント

ツール 向いているケース
Helm パッケージ管理、複雑な条件分岐、外部Chart利用
Kustomize GitOps、シンプルなカスタマイズ、マニフェストの可読性重視

重要: どちらが優れているかではなく、用途に応じて使い分ける


1. Helm と Kustomize の役割

Helm: テンプレートベース(変数を埋め込む)

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.app.name }}  # 変数
spec:
  replicas: {{ .Values.app.replicas }}  # 変数
  template:
    spec:
      containers:
      - name: {{ .Values.app.name }}
        image: {{ .Values.app.image }}:{{ .Values.app.version }}  # 変数

アプローチ:

  • Go Templateで変数を埋め込む
  • テンプレート + 値 → 最終的なマニフェスト生成
  • 「変数を置き換える」

Kustomize: オーバーレイベース(差分を適用)

# base/deployment.yaml(元のマニフェスト - 有効なYAML)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:latest

# overlays/production/kustomization.yaml(差分)
bases:
  - ../../base
replicas:
  - name: myapp
    count: 3
images:
  - name: myapp
    newTag: v1.2.3

アプローチ:

  • 元のマニフェストに差分(パッチ)を適用
  • ベース + オーバーレイ → 最終的なマニフェスト生成
  • 「差分を上書きする」

2. 実践: Prometheusスタックのデプロイ

Week 1で構築した監視スタックを例に、HelmとKustomizeでどうデプロイするか比較します。

Helm版: Chart Repositoryから導入

# Chart Repositoryを追加
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# values.yamlで設定カスタマイズ
cat <<EOF > monitoring-values.yaml
prometheus:
  prometheusSpec:
    nodeSelector:
      node-role.kubernetes.io/monitoring: "true"
    resources:
      requests:
        memory: 2Gi
        cpu: 1000m
      limits:
        memory: 4Gi
        cpu: 2000m

grafana:
  adminPassword: "your-secure-password"
  ingress:
    enabled: true
    hosts:
      - grafana.local

alertmanager:
  config:
    receivers:
      - name: 'discord'
        webhook_configs:
          - url: 'https://discord.com/api/webhooks/YOUR_WEBHOOK'
            send_resolved: true
EOF

# インストール
helm install monitoring prometheus-community/kube-prometheus-stack \
  -n monitoring --create-namespace \
  -f monitoring-values.yaml

# アップグレード
helm upgrade monitoring prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f monitoring-values.yaml

メリット:

  • ✅ 1コマンドで複雑なスタックを導入
  • ✅ values.yamlだけ管理すればOK
  • ✅ Chart Repositoryからバージョン指定で取得
  • ✅ リリース履歴管理・ロールバック可能
# 履歴確認
helm history monitoring
REVISION  STATUS      DESCRIPTION
1         superseded  Install complete
2         deployed    Upgrade complete

# ロールバック
helm rollback monitoring 1

Kustomize版: マニフェストベースで管理

# ディレクトリ構造
monitoring-kustomize/
├── base/
│   ├── kustomization.yaml
│   ├── prometheus-deployment.yaml
│   ├── grafana-deployment.yaml
│   ├── alertmanager-configmap.yaml
│   └── service-monitor.yaml
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml
    │   └── resources-patch.yaml
    └── production/
        ├── kustomization.yaml
        ├── node-selector-patch.yaml
        └── resources-patch.yaml

base/prometheus-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:v2.45.0
        ports:
        - containerPort: 9090
        resources:
          requests:
            memory: 1Gi
            cpu: 500m
          limits:
            memory: 2Gi
            cpu: 1000m

overlays/production/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
  - ../../base

namespace: monitoring

replicas:
  - name: prometheus
    count: 2

patchesStrategicMerge:
  - node-selector-patch.yaml
  - resources-patch.yaml

overlays/production/node-selector-patch.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
spec:
  template:
    spec:
      nodeSelector:
        node-role.kubernetes.io/monitoring: "true"
      tolerations:
        - key: dedicated
          operator: Equal
          value: monitoring
          effect: NoSchedule

デプロイ:

# 開発環境
kubectl apply -k overlays/dev/

# 本番環境
kubectl apply -k overlays/production/

# Dry-run(差分確認)
kubectl diff -k overlays/production/

# 生成されるマニフェストを確認(デプロイせず)
kubectl kustomize overlays/production/

メリット:

  • ✅ 元のマニフェストが有効なYAML(読みやすい)
  • ✅ Git差分が明確(レビューしやすい)
  • ✅ kubectl組み込み(追加インストール不要)
  • ✅ GitOpsとの相性が抜群

3. GitOpsとの関係

GitOpsとは?

定義: Gitをインフラの唯一の信頼できる情報源(Single Source of Truth)として扱う運用手法

原則:

  1. 宣言的な設定(Declarative)
  2. Gitで管理
  3. 自動的にデプロイ
  4. 継続的な監視と修正

Kustomize + GitOps = 相性抜群

Argo CDでの例:

# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: monitoring
spec:
  source:
    repoURL: https://github.com/your-org/k8s-manifests
    targetRevision: main
    path: monitoring/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: monitoring
  syncPolicy:
    automated:
      prune: true      # 削除されたリソースをクラスタからも削除
      selfHeal: true   # クラスタの状態をGitに自動修正

フロー:

Git commit → Argo CD検知 → kubectl apply -k → クラスタ更新

メリット:

  • Git履歴 = デプロイ履歴
  • PRレビュー = 変更レビュー
  • Git revert = ロールバック

Helm + GitOps = 可能だが少し複雑

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: monitoring
spec:
  source:
    repoURL: https://github.com/your-org/helm-values
    targetRevision: main
    path: monitoring
    helm:
      valueFiles:
        - values-prod.yaml  # Gitで管理
  destination:
    server: https://kubernetes.default.svc
    namespace: monitoring

課題:

  • values.yamlの変更はGitで追えるが、Chartの変更は追いにくい
  • helm templateしないと最終的なマニフェストが見えない
  • レビューが難しい

4. 併用パターン(推奨)

実は両方を組み合わせることが現実的な解決策です。

ハイブリッド方式

k8s-manifests/
├── infrastructure/     # Helmで管理
│   ├── postgresql/
│   │   └── values.yaml
│   ├── redis/
│   │   └── values.yaml
│   └── monitoring/
│       └── values.yaml
└── applications/       # Kustomizeで管理
    ├── base/
    │   ├── frontend/
    │   ├── backend/
    │   └── api-gateway/
    └── overlays/
        ├── dev/
        ├── staging/
        └── production/

使い分け

  • 外部サービス(PostgreSQL, Redis, Prometheus など) → Helm
    • コミュニティChartをそのまま利用
    • values.yamlだけカスタマイズ
  • カスタムアプリ(自社開発アプリ) → Kustomize
    • GitOpsで管理
    • マニフェストの可読性重視

Helmfile: 複数Helmリリースを管理

# helmfile.yaml
repositories:
  - name: prometheus-community
    url: https://prometheus-community.github.io/helm-charts
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: postgresql
    namespace: database
    chart: bitnami/postgresql
    version: 12.1.0
    values:
      - postgresql/values.yaml

  - name: monitoring
    namespace: monitoring
    chart: prometheus-community/kube-prometheus-stack
    version: 51.0.0
    values:
      - monitoring/values.yaml
# 全てのリリースを適用
helmfile sync

# 特定のリリースのみ
helmfile -l name=monitoring sync

5. メリット・デメリット

Helm

メリット

  • ✅ パッケージの再利用が容易(Artifact Hub)
  • ✅ 依存関係の管理(Chart.yaml)
  • ✅ リリース履歴・ロールバック
  • ✅ 複雑な条件分岐・ループ(Go Template)
  • ✅ コミュニティChartが豊富

デメリット

  • ❌ Go Templateの学習コスト
  • ❌ デバッグが難しい(変数だらけ)
  • ❌ Git差分が見づらい
  • helm templateしないと最終形がわからない

Kustomize

メリット

  • ✅ シンプル(YAMLのみ、テンプレート言語不要)
  • ✅ 元のマニフェストが有効なYAML(読みやすい)
  • ✅ Gitで差分が見やすい
  • ✅ kubectl組み込み(追加インストール不要)
  • ✅ GitOpsとの相性が良い

デメリット

  • ❌ 複雑な条件分岐ができない
  • ❌ 依存関係の管理なし
  • ❌ リリース履歴なし(Gitで代替)
  • ❌ パッケージの共有が難しい

6. 実務でのパターン

小規模チーム

推奨: Kustomize

理由:

  • シンプルで学習コスト低い
  • GitOpsで管理しやすい
  • kubectlだけで完結

中規模チーム

推奨: Helm + Kustomize

理由:

  • 外部サービスはHelmで楽に導入
  • カスタムアプリはKustomizeで管理
  • チーム間で設定を共有

大規模組織

推奨: Helm(社内Chart作成)+ Helmfile

理由:

  • 標準化が重要
  • 複雑な環境差分
  • 依存関係が複雑
  • リリース管理が厳格

7. トラブルシューティング

どちらのツールを使っても、問題が起きたときの調査方法は共通です。

基本フロー

# 1. Pod状態確認
kubectl get pods -n monitoring

# 2. Pod詳細確認
kubectl describe pod prometheus-0 -n monitoring

# 3. Podログ確認
kubectl logs prometheus-0 -n monitoring

# 4. 前回起動ログ確認(CrashLoopBackOffの場合)
kubectl logs prometheus-0 -n monitoring --previous

# 5. イベント確認
kubectl get events -n monitoring --sort-by='.lastTimestamp'

# 6. サービス・エンドポイント確認
kubectl get svc,endpoints -n monitoring

# 7. ConfigMap/Secret確認
kubectl get configmaps -n monitoring
kubectl describe configmaps prometheus-config -n monitoring

まとめ

比較

観点 Helm Kustomize
例え npmパッケージマネージャー gitブランチ戦略
アプローチ テンプレート(変数埋め込み) パッチ(差分適用)
複雑性 高機能だが複雑 シンプル
学習コスト 高(Go Template) 低(YAML知識のみ)
再利用性 Chart共有可能 共有は難しい
kubectl統合 別途インストール 組み込み済み
GitOps 可能(少し複雑) 最適

所感

  • 改めて調べてみるとまとまっているサイトが多くわかりやすかったです。
  • もっと深堀りしたいところはありますが、今回はこのくらいで
  • 各コンポーネントのバージョンは古いので、適宜ご自身の状況にあったものに変更してくださいませ(アップグレード検証早くしたいっす)
  • Kustomizeをcustomizeと書いてしまうクセが付いてしまったのを早く直す

明日の予告

明日(12/11)は、KustomizeとArgo CDを組み合わせたGitOps実践を解説します。Gitへのcommit/pushだけでクラスタが自動更新を体験しましょう!


参考リンク

本記事のサンプルコード(GitHub)

Helm

Kustomize

Helmfile

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?