Cluster API (CAPI) を使った複数環境にまたがる Kubernetes クラスターのライフサイクル管理

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

複数の Kubernetes クラスターを手動で管理する問題点

開発環境、ステージング環境、本番環境など、2 つ以上の Kubernetes クラスターを管理したことがあれば、すぐに混乱が生じることをご存知でしょう。各クラスターはそれぞれ異なる方法で作成され、アップグレードのスケジュールもバラバラです。あるチームは eksctl を使って AWS 上でノードを手動プロビジョニングし、別のチームは GCP で Terraform を使い、ベアメタルのセットアップは誰も完全には理解していない Ansible Playbook の寄せ集めになっています。

結果として「スノーフレーク化」したクラスター群が生まれます。表面上は似て見えても、内部では一貫性がありません。Kubernetes のバージョンアップグレードは午後一発で終わるタスクではなく、1 週間がかりのプロジェクトになります。新しいリージョン向けのクラスターをオンボーディングするには、再利用を前提に設計されていなかったスクリプトをコピー&修正する必要があります。

Cluster API (CAPI) はまさにこの問題を解決するために生まれました。ワークロードに対して使っているのと同じ GitOps フレンドリーな宣言型管理・リコンシリエーションループのアプローチを、そのインフラ自体に適用します。

まず押さえておくべきコアコンセプト

マネジメントクラスターとワークロードクラスター

CAPI は 2 階層モデルを採用しています:

  • マネジメントクラスター:CAPI コントローラーを実行する専用の Kubernetes クラスターです。これがクラスター群全体のコントロールプレーンになります。ClusterMachineDeployment などの CAPI カスタムリソースを監視し、実際のインフラがその状態と一致するよう調整します。
  • ワークロードクラスター:アプリケーションが実際に動作するクラスターです。適用した YAML マニフェストに基づいて、マネジメントクラスターによって作成・アップグレード・削除されます。

マネジメントクラスターはクラスターのファクトリーだと考えるとわかりやすいでしょう。欲しいものを記述すれば、それを構築してくれます。

インフラストラクチャープロバイダー

CAPI はプロバイダー非依存です。各クラウドやプラットフォームには、CAPI リソースを実際のインフラ呼び出しに変換する独自のプロバイダーがあります:

  • CAPA — Cluster API Provider AWS
  • CAPG — Cluster API Provider GCP
  • CAPM3 — Cluster API Provider Metal3(BMC/IPMI 経由のベアメタル)

コアの CAPI コントローラーはマシンヘルスチェック、ローリングアップグレード、スケーリングといった汎用的なライフサイクルロジックを担い、インフラプロバイダーは VM、ロードバランサー、ネットワークを作成する実際の API 呼び出しを処理します。

主要なリソースタイプ

CAPI でワークロードクラスターを作成する際は、以下のリソースを YAML で定義します:

  • Cluster — インフラとコントロールプレーンを参照するトップレベルオブジェクト
  • AWSCluster / GCPCluster — プロバイダー固有のネットワーク・VPC 設定
  • KubeadmControlPlane — コントロールプレーンノード(etcd + API サーバー + スケジューラー)を管理
  • MachineDeployment — ワーカーノードグループを管理(Deployment と同様だがマシン向け)
  • AWSMachineTemplate / GCPMachineTemplate — マシンのスペック(インスタンスタイプ、イメージ、ディスク)を定義

ハンズオン:CAPI のセットアップと最初のクラスターのプロビジョニング

ステップ 1:clusterctl のインストール

clusterctl はプロバイダーの初期化とクラスターマニフェストの生成に使う CLI ツールです。

# clusterctl のインストール (Linux/macOS)
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.7.3/clusterctl-linux-amd64 -o clusterctl
chmod +x clusterctl
sudo mv clusterctl /usr/local/bin/

# バージョン確認
clusterctl version

ステップ 2:マネジメントクラスターの準備

既存の Kubernetes クラスター(テスト用途ならローカルの kind クラスターでも動作します)を使います。Kubernetes 1.26 以上が必要です。

# kind でローカルのマネジメントクラスターを作成(テスト用)
kind create cluster --name capi-management
export KUBECONFIG=$(kind get kubeconfig --name capi-management)

ステップ 3:AWS プロバイダー (CAPA) の初期化

まず AWS 認証情報を環境変数にセットし、clusterctl init でコントローラーをインストールします:

export AWS_REGION=ap-northeast-1
export AWS_ACCESS_KEY_ID=<your-key-id>
export AWS_SECRET_ACCESS_KEY=<your-secret>

# clusterawsadm をインストールして IAM リソースをブートストラップ
clusterawsadm bootstrap iam create-cloudformation-stack

# コントローラー用に認証情報を base64 エンコードしてエクスポート
export AWS_B64ENCODED_CREDENTIALS=$(clusterawsadm bootstrap credentials encode-as-profile)

# マネジメントクラスターで CAPA を初期化
clusterctl init --infrastructure aws

GCP の場合は以下のコマンドになります:

export GCP_B64ENCODED_CREDENTIALS=$(cat sa-key.json | base64 | tr -d '\n')
clusterctl init --infrastructure gcp

ステップ 4:クラスターマニフェストの生成

YAML をゼロから書く代わりに、clusterctl generate cluster を使うとプロバイダーのテンプレートをもとにすぐ使えるマニフェストを生成できます:

export AWS_SSH_KEY_NAME=my-key-pair
export AWS_CONTROL_PLANE_MACHINE_TYPE=t3.medium
export AWS_NODE_MACHINE_TYPE=t3.medium

clusterctl generate cluster dev-cluster \
  --infrastructure aws \
  --kubernetes-version v1.30.0 \
  --control-plane-machine-count 1 \
  --worker-machine-count 2 \
  > dev-cluster.yaml

dev-cluster.yaml を開いて内容を確認してみましょう。先ほど説明したリソースタイプがすべて含まれています。このファイル 1 枚でクラスター全体(コントロールプレーンノード、ワーカーノード、VPC 設定、Kubernetes バージョン)が記述されています。

ステップ 5:適用してクラスターの起動を監視する

kubectl apply -f dev-cluster.yaml

# プロビジョニングの状態を確認
clusterctl describe cluster dev-cluster

CAPI は AWS API を呼び出して VPC、サブネット、セキュリティグループ、EC2 インスタンスを作成します。全体のプロセスは通常 8〜12 分かかります。準備ができたら、新しいワークロードクラスターの kubeconfig を取得します:

clusterctl get kubeconfig dev-cluster > dev-cluster.kubeconfig
export KUBECONFIG=dev-cluster.kubeconfig
kubectl get nodes

ステップ 6:Kubernetes バージョンのアップグレード

ここが CAPI の真骨頂です。クラスターのアップグレードは YAML のフィールドを 1 つ変更するだけ — SSH も手動のローリング手順も不要です。

# KubeadmControlPlane リソースを編集
kubectl patch kcp dev-cluster-control-plane \
  --type merge \
  -p '{"spec":{"version":"v1.31.0"}}'

CAPI は 1.31.0 を実行する新しいコントロールプレーンノードを 1 台ずつロールアウトし、各ノードが正常になるのを待ってから古いものを終了させます。ワーカーノードも MachineDeployment を通じて同じローリング戦略に従います。この方法を本番環境で適用した経験上、結果は一貫して安定しており、マイナーバージョンをまたぐアップグレードでも手動介入なしに CAPI が正しくシーケンスを処理してくれます。

ワーカーノードをアップグレードするには:

kubectl patch machinedeployment dev-cluster-md-0 \
  --type merge \
  -p '{"spec":{"template":{"spec":{"version":"v1.31.0"}}}}'

ステップ 7:ワーカーノードのスケーリング

スケーリングは MachineDeploymentreplicas フィールドを変更するだけです:

# ワーカーを 5 台にスケールアウト
kubectl scale machinedeployment dev-cluster-md-0 --replicas=5

# 宣言的にパッチを当てる場合
kubectl patch machinedeployment dev-cluster-md-0 \
  --type merge \
  -p '{"spec":{"replicas":5}}'

ステップ 8:クラスターの削除

削除も同様にクリーンです。CAPI は正しい順序でティアダウンを処理します — まずワーカー、次にコントロールプレーン、最後にインフラです:

kubectl delete cluster dev-cluster

これにより、プロバイダーは EC2 インスタンス、ロードバランサー、VPC(CAPI が作成した場合)を含む、クラスターに関連するすべての AWS リソースを削除します。孤立したリソースが残ることはありません。

ベアメタル (Metal3) での同じワークフロー

ベアメタルプロバイダー (CAPM3) は、BMC(Baseboard Management Controller)を通じて登録された物理マシンを表す BareMetalHost オブジェクトを使って動作します。ホストが登録されると、ワークフローはまったく同じです — Metal3ClusterMetal3MachineTemplate を参照する Cluster マニフェストを書いて apply すれば、CAPI が PXE ブートと cloud-init を使ってクラスターをプロビジョニングします:

# Metal3 プロバイダーを初期化
clusterctl init --infrastructure metal3

# ベアメタル向けクラスターマニフェストを生成
clusterctl generate cluster prod-baremetal \
  --infrastructure metal3 \
  --kubernetes-version v1.30.0 \
  --control-plane-machine-count 3 \
  --worker-machine-count 6 \
  > prod-baremetal.yaml

まとめ:GitOps フレンドリーなクラスター群の構築

CAPI の真の力は、クラスターマニフェストを Git で管理し、Flux や ArgoCD などのツールを使ってマネジメントクラスターに同期したときに発揮されます。AWS 上の開発環境、GCP 上のステージング環境、ベアメタルの本番環境など、クラスター群全体がリポジトリ内の YAML ファイル群になります。新しい環境の作成は git commit 一発です。10 クラスターのアップグレードは Kustomize オーバーレイのバージョン変更です。クラスターの廃止はファイルの削除です。

このパターンは属人的な知識の問題を解消します。チームのエンジニアであれば誰でもリポジトリを読んで、どのクラスターが存在し、どのバージョンを実行し、ノード数がいくつかを正確に把握できます。マネジメントクラスターが継続的に望ましい状態を維持するため、設定のドリフトが蓄積しにくくなります。

次のステップ

まずは小さく始めましょう。ローカルで kind マネジメントクラスターを立ち上げ、Docker インフラプロバイダー(CAPD)を使ってテスト用ワークロードクラスターを作成してみてください — クラウドの認証情報は不要です。リソースモデルを理解したら、AWS や GCP の実際のマシンに移行します。その後、Machine Health Checks を追加して不健全なノードを自動で置き換えられるようにし、ClusterClass(CAPI の新機能)を導入することで、チームが毎回 YAML を手書きせずにセルフサービスで利用できる再利用可能なクラスターテンプレートを作成できます。

CAPI の学習曲線は eksctlGKE Autopilot より急ですが、クラスター群が拡大しても一貫性・監査可能性・自動化を備えたインフラ管理の恩恵は大きいです。

Share: