Cluster API — 故事驅動式學習
情境:雲原生平台工程師的一天
小明是某金融科技公司的平台工程師。公司的工程團隊快速成長,每個業務線都需要自己的 Kubernetes 叢集,而且要求快速佈建、統一規格、並能在不同基礎設施上運行(公有雲 + 私有雲)。
傳統方式需要寫大量 Terraform + Ansible 腳本,維護成本極高。主管建議小明評估 Cluster API(CAPI)。
第一章:認識 CAPI 架構
小明首先要理解 CAPI 的核心概念。
「所以 CAPI 就是用 Kubernetes 管理 Kubernetes?」
正是!CAPI 引入了 Management Cluster 的概念:
公司內網的 Kubernetes(Management Cluster)
│
├─ 管理 dev-cluster(AWS ap-northeast-1)
├─ 管理 staging-cluster(AWS ap-northeast-1)
└─ 管理 prod-cluster(vSphere 私有雲)每個 Workload Cluster 都是一個 Cluster CRD:
// 檔案: api/core/v1beta2/cluster_types.go
const (
ClusterFinalizer = "cluster.cluster.x-k8s.io"
ClusterKind = "Cluster"
)
// 每個 Cluster 物件代表一個目標 Kubernetes 叢集
type Cluster struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ClusterSpec `json:"spec,omitempty,omitzero"`
Status ClusterStatus `json:"status,omitempty,omitzero"`
}小明理解了:Management Cluster 是控制平面,CAPI Core CRD 定義了「期望狀態」,Provider 負責讓基礎設施達到那個狀態。
第二章:初始化 Management Cluster
小明決定先在本機用 Docker Provider(CAPD)實驗。
# 建立 kind 叢集作為 Management Cluster
kind create cluster --name capi-management
# 安裝 CAPI Core + Docker Provider
clusterctl init --infrastructure docker背後發生了什麼?clusterctl init 會:
- 安裝 CAPI Core CRD(
Cluster,Machine,MachineSet等) - 部署 CAPI Core Controller Manager
- 安裝 Bootstrap Provider(kubeadm)
- 安裝 ControlPlane Provider(KubeadmControlPlane)
- 安裝 Infrastructure Provider(DockerCluster)
第三章:建立第一個 Workload Cluster
# 產生叢集 YAML
clusterctl generate cluster dev-cluster \
--flavor development \
--kubernetes-version v1.31.0 \
--control-plane-machine-count=1 \
--worker-machine-count=2 > dev-cluster.yaml
# 套用
kubectl apply -f dev-cluster.yaml套用後,Management Cluster 上出現了一系列物件:
| 物件 | 說明 |
|---|---|
Cluster/dev-cluster | 主要叢集物件 |
KubeadmControlPlane/dev-cluster-control-plane | 控制平面(1 台) |
MachineDeployment/dev-cluster-md-0 | Worker 節點池(2 台) |
DockerCluster/dev-cluster | Docker 基礎設施 |
小明觀察到整個建立流程:
Cluster Controller 偵測到 Cluster
→ DockerCluster status.ready = true
→ KubeadmControlPlane 建立第一台控制平面 Machine
→ Machine Controller 呼叫 DockerMachine(建立容器模擬 VM)
→ KubeadmConfig 產生 cloud-init(kubeadm init 腳本)
→ 節點加入叢集,Machine status.phase = Running
→ MachineDeployment 建立 2 台 Worker Machine
→ 叢集就緒!第四章:ClusterClass 讓叢集標準化
公司有多個業務線,每個都要建相似的叢集,但每次都要寫複雜的 YAML。
小明的主管說:「用 ClusterClass 吧!」
# 檔案: config/samples/clusterclass.yaml
# 平台團隊定義一次,業務線重複使用
apiVersion: cluster.x-k8s.io/v1beta2
kind: ClusterClass
metadata:
name: company-standard
spec:
infrastructure:
ref:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DockerClusterTemplate
name: company-standard-infra
controlPlane:
ref:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlaneTemplate
name: company-standard-control-plane
workers:
machineDeployments:
- class: worker
template:
bootstrap:
ref:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
name: company-standard-worker
infrastructure:
ref:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DockerMachineTemplate
name: company-standard-worker現在業務線只需要這樣建叢集:
# 檔案: config/samples/cluster-topology-simple.yaml
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: payment-cluster
spec:
topology:
class: company-standard # 引用公司標準範本
version: v1.31.0
controlPlane:
replicas: 3
workers:
machineDeployments:
- class: worker
name: md-0
replicas: 5第五章:叢集升級
三個月後,Kubernetes v1.32 發布了,小明需要升級 production 叢集。
# 查看可升級的版本
clusterctl upgrade plan
# 使用 ClusterClass,只需修改 version
kubectl patch cluster payment-cluster \
--type merge \
-p '{"spec":{"topology":{"version":"v1.32.0"}}}'CAPI 的升級順序:
1. TopologyReconciler 更新 KubeadmControlPlane.spec.version
2. KCP Controller 開始滾動升級控制平面
├─ 建立新的控制平面 Machine(v1.32)
├─ 等待新 Machine 健康
└─ 刪除舊的控制平面 Machine(v1.31)
3. Worker MachineDeployment.spec.template.spec.version 更新
4. MachineDeploymentReconciler 建立新 MachineSet(v1.32)
5. 滾動替換 Worker 節點// 檔案: api/core/v1beta2/machinedeployment_types.go
const (
// MachineDeploymentFinalizer 確保 MachineSet 有序清理
MachineDeploymentFinalizer = "cluster.x-k8s.io/machinedeployment"
// RevisionAnnotation 記錄升級序號
RevisionAnnotation = "machinedeployment.clusters.x-k8s.io/revision"
)第六章:機器故障自動修復
某天,production 叢集的一台 Worker 節點突然出現 NotReady 狀態。
小明之前已設定 MachineHealthCheck:
# 檔案: config/samples/machinehealthcheck.yaml
apiVersion: cluster.x-k8s.io/v1beta2
kind: MachineHealthCheck
metadata:
name: payment-cluster-worker-mhc
spec:
clusterName: payment-cluster
selector:
matchLabels:
cluster.x-k8s.io/deployment-name: md-0
unhealthyConditions:
- type: Ready
status: "False"
timeout: 300s
maxUnhealthy: "33%"CAPI 自動處理:
MachineHealthCheckReconciler偵測到節點Ready=False超過 300 秒- 標記該 Machine 為「需要修復」
- 刪除該 Machine(觸發 drain → 刪除 Docker 容器)
- MachineSet Controller 自動建立新的替換 Machine
- 新節點加入叢集,服務恢復正常
小明的心得
CAPI 讓我用 GitOps 的方式管理多個叢集:叢集定義存在 Git,PR 審查後自動套用。比起維護複雜的腳本,現在我只需要維護少量 YAML 就能管理整個公司的 Kubernetes 基礎設施。
CAPI 的核心價值:
- 宣告式管理:叢集狀態由 CRD 定義,Controller 自動維持
- Provider 插件化:同一套 CAPI 管理 AWS、vSphere 等不同平台
- ClusterClass 標準化:平台團隊定義一次,業務線重複使用
- 自動修復:MachineHealthCheck 無需人工介入