Learning Journey: Part 03 of 16
Module Goal: Master the complete Cluster API object graph: how
Cluster,Machine,MachineSet,MachineDeployment,MachinePool,KubeadmControlPlane,BootstrapConfig, and Infrastructure resources relate, delegate, and transfer state.
Target Spec: Cluster APIv1.14(v1beta2APIs).
Prerequisites: Part 02: Cluster API Architecture: How the Control Plane Pieces Cooperate (Asynchronous Controller Coordination & Provider Contracts).
1. The Core Challenge: Decoupling Abstraction Overload
The most common obstacle when adopting Cluster API (CAPI) is not installation; it is navigating the object graph.
A standard CAPI management cluster registers dozens of Custom Resource Definitions (CRDs):
Cluster
Machine
MachineSet
MachineDeployment
MachinePool
KubeadmControlPlane
KubeadmConfig
InfrastructureCluster (e.g., AWSCluster / VSphereCluster)
InfrastructureMachine (e.g., AWSMachine / VSphereVM)
InfrastructureMachineTemplate (e.g., AWSMachineTemplate)
KubeadmConfigTemplate
At first glance, this layered object graph can appear over-engineered for a system designed to provision virtual machines and join them to a Kubernetes cluster.
However, each custom resource encapsulates a single, tightly scoped responsibility. To prevent monolithic controller code, Cluster API categorizes these resources into three architectural layers:
flowchart TD
subgraph Layer1["Layer 1: Cluster Intent & High-Level Policy"]
C["Cluster"]
KCP["KubeadmControlPlane"]
MD["MachineDeployment"]
MP["MachinePool"]
MHC["MachineHealthCheck"]
end
subgraph Layer2["Layer 2: Machine Lifecycle & Replica Management"]
MS["MachineSet"]
M["Machine"]
end
subgraph Layer3["Layer 3: Provider Implementation & Blueprints"]
IC["InfrastructureCluster"]
IM["InfrastructureMachine"]
BC["KubeadmConfig"]
IT["InfraMachineTemplate"]
BT["KubeadmConfigTemplate"]
end
C -->|infraRef| IC
C -->|controlPlaneRef| KCP
C --> MD
MD --> MS
MS --> M
KCP --> M
M -->|bootstrapRef| BC
M -->|infraRef| IM
MD -. blueprint .-> IT
MD -. blueprint .-> BT
MHC --> M
Once every object is mapped to its layer, the object graph transforms from a confusing collection of CRDs into a predictable state machine.
2. The Complete Object Graph
To understand how a cluster comes into existence, we trace the full object tree across both worker nodes and the control plane.
flowchart TD
C["Cluster"] --> MD["MachineDeployment"]
MD -->|Manages Replicas & Rollouts| MS["MachineSet"]
MS -->|Maintains Host Count| M["Machine"]
MD -. Specifies Blueprint .-> BT["KubeadmConfigTemplate"]
MD -. Specifies Blueprint .-> IT["InfraMachineTemplate"]
BT -. Instantiates .-> BC["KubeadmConfig (Bootstrap)"]
IT -. Instantiates .-> IM["InfraMachine (Infrastructure)"]
M -->|Refers| BC
M -->|Refers| IM
IM -->|Provisions| HOST["Cloud VM / Hypervisor Host"]
BC -->|Injects Cloud-Init / Join Script| HOST
HOST -->|Registers via ProviderID| NODE["Kubernetes Node (Workload Cluster)"]
Worker Node Object Pathway
MachineDeploymentdefines the desired worker count and references infrastructure/bootstrap blueprints (Templates).MachineSetmaintains a fixed count of activeMachineobjects.Machinerepresents the lifecycle of a single host.KubeadmConfiggenerates the cloud-init bootstrap script.InfrastructureMachineprovisions the cloud VM or bare-metal host.- The host executes the bootstrap payload and registers as a
Nodeinside the target workload cluster.
Control Plane Object Pathway
Control plane nodes follow a dedicated control-loop pathway to protect API server availability and etcd quorum:
flowchart TD
C["Cluster"] --> KCP["KubeadmControlPlane"]
KCP -->|Directly Manages CP Hosts| M_CP["Machine (Control Plane)"]
M_CP --> BC_CP["KubeadmConfig"]
M_CP --> IM_CP["InfraMachine"]
IM_CP --> HOST_CP["Control Plane VM"]
HOST_CP --> NODE_CP["Control Plane Node"]
3. The Workload Analogy: Pods vs. Machines
The fastest way to understand CAPI’s worker abstractions is to compare them with native Kubernetes workload primitives.
flowchart LR
subgraph K8S["Native Kubernetes Workload Model"]
direction TB
DEP["Deployment"] -->|Manages| RS["ReplicaSet"]
RS -->|Maintains| POD["Pod (Container Lifecycle)"]
end
subgraph CAPI["Cluster API Machine Worker Model"]
direction TB
MD["MachineDeployment"] -->|Manages| MS["MachineSet"]
MS -->|Maintains| M["Machine (Host Lifecycle)"]
end
| Workload Primitive | Cluster API Worker Primitive | Functional Scope |
|---|---|---|
Deployment | MachineDeployment | Declarative specification of desired state, rolling update strategies, and scaling boundaries. |
ReplicaSet | MachineSet | Maintains a stable pool of identical active replicas (Pods or Machines). |
Pod | Machine | Atomic execution unit representing a single scheduled entity (Container host vs. Node host). |
4. Deep-Dive Custom Resource Breakdown
4.1. Cluster: The Root Intent Object
The Cluster object represents the top-level declaration of a single Kubernetes cluster. It does not directly create cloud resources; instead, it anchors the object graph by linking infrastructure and control plane providers.
apiVersion: cluster.x-k8s.io/v1beta2
kind: Cluster
metadata:
name: production-us-east
namespace: default
spec:
clusterNetwork:
services:
cidrBlocks: ["10.96.0.0/12"]
pods:
cidrBlocks: ["192.168.0.0/16"]
serviceDomain: "cluster.local"
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: AWSCluster
name: production-us-east
controlPlaneRef:
apiGroup: controlplane.cluster.x-k8s.io
kind: KubeadmControlPlane
name: production-us-east-control-plane
4.2. InfrastructureCluster: The Environment Contract
InfrastructureCluster is a contract role implemented by concrete infrastructure providers (e.g., AWSCluster, AzureCluster, GCPCluster, VSphereCluster).
It provisions cluster-wide networking and gateway infrastructure:
- Virtual Private Clouds (VPC) / Subnets / Route Tables
- Security Groups / Firewall Rules
- External Control Plane Load Balancers (HA Proxy / AWS ELB)
- Target API Server Endpoints (
spec.controlPlaneEndpoint)
flowchart LR
C["Cluster"] -->|spec.infrastructureRef| IC["InfrastructureCluster (e.g. AWSCluster)"]
IC -->|Provisions| LB["Control Plane Load Balancer"]
IC -->|Provisions| VPC["VPC & Subnets"]
IC -->|Populates| Status["status.controlPlaneEndpoint"]
4.3. Machine: Host Lifecycle Abstraction
A common misconception is that Machine == VM.
A Machine is a declarative custom resource in the management cluster that tracks the lifecycle state of a host intended to become a Node in the workload cluster.
apiVersion: cluster.x-k8s.io/v1beta2
kind: Machine
metadata:
name: production-us-east-worker-0
spec:
clusterName: production-us-east
bootstrap:
configRef:
apiGroup: bootstrap.cluster.x-k8s.io
kind: KubeadmConfig
name: production-us-east-worker-0
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: AWSMachine
name: production-us-east-worker-0
version: v1.31.0
Machine vs. Node Boundary
flowchart LR
subgraph MGMT["Management Cluster"]
M["Machine Resource<br/>(spec.providerID)"]
end
subgraph WORKLOAD["Workload Cluster"]
N["Kubernetes Node Resource<br/>(spec.providerID)"]
end
M <===>|Correlated asynchronously via ProviderID| N
Machine: Lives in the management cluster. Controls provisioning, bootstrapping, cloud instance lifecycle, and deletion.Node: Lives in the workload cluster. Managed bykubeletand the Kubernetes control plane.providerID: Unique provider URI (aws:///us-east-1a/i-0123456789abcdef0) used by CAPI controllers to bind aMachineobject to its registeredNode.
4.4. InfrastructureMachine & BootstrapConfig
A Machine delegates specialized work via two reference pointers:
flowchart TD
M["Machine"] -->|bootstrap.configRef| BC["BootstrapConfig (e.g., KubeadmConfig)"]
M -->|infrastructureRef| IM["InfrastructureMachine (e.g., AWSMachine)"]
BC -->|Generates| DATA["Bootstrap Cloud-Init Payload"]
IM -->|Provisions| VM["Virtual Machine Instance"]
VM -->|Executes Data Payload| JOIN["Runs kubeadm join & Registers Node"]
BootstrapConfig(KubeadmConfig): Responsible for generating initialization scripts (cloud-init,ignition), ignition tokens, andkubeadm joinparameters.InfrastructureMachine(AWSMachine,VSphereVM): Responsible for concrete provider instance parameters (instance size, root disk, AMI ID, subnets, IAM roles).
4.5. MachineSet & MachineDeployment
MachineSet ensures a target number of active Machine replicas match a specific configuration spec.
MachineDeployment wraps MachineSet to provide zero-downtime rolling updates across worker node pools.
flowchart TD
MD["MachineDeployment (Updated Spec: Image v2)"] -->|1. Creates| MS2["New MachineSet (v2)<br/>Replicas: 0 -> 1 -> 2 -> 3"]
MD -->|2. Scales Down| MS1["Old MachineSet (v1)<br/>Replicas: 3 -> 2 -> 1 -> 0"]
MS2 -->|Spawns| M2["New Machine (v2)"]
MS1 -->|Drains & Evicts| M1["Old Machine (v1)"]
When a field in a worker template changes (e.g., updating the OS image or kubelet flag):
MachineDeploymentcreates a newMachineSet.- It scales up the new
MachineSetwhile scaling down the oldMachineSet. - CAPI handles node cordon, pod eviction/drain, and VM termination safely.
5. Architectural Variants: MachineDeployment vs. MachinePool
While MachineDeployment manages individual CAPI Machine objects, some cloud providers offer native auto-scaling infrastructure primitives (e.g., AWS Auto Scaling Groups, Azure VM Scale Sets).
Cluster API supports MachinePool for these environments:
flowchart TD
subgraph MD_MODEL["MachineDeployment Strategy (CAPI-Managed Replicas)"]
MD["MachineDeployment"] --> MS["MachineSet"] --> M1["Machine 1"] & M2["Machine 2"] & M3["Machine 3"]
M1 --> H1["VM 1"]
M2 --> H2["VM 2"]
M3 --> H3["VM 3"]
end
subgraph MP_MODEL["MachinePool Strategy (Provider-Managed Scaling Group)"]
MP["MachinePool"] --> IMP["InfrastructureMachinePool (e.g. AWS ASG / Azure VMSS)"]
IMP --> ASG["Cloud Auto Scaling Group"]
ASG --> N1["Node 1"] & N2["Node 2"] & N3["Node 3"]
end
| Operational Dimension | MachineDeployment | MachinePool |
|---|---|---|
| Granularity | Explicit CAPI Machine object per host node. | Single object representing an entire scaling group. |
| Reconciliation Unit | Individual machine lifecycle loops. | Provider scaling group API handles instance creation. |
| Provider Portability | Universal (works on cloud, hypervisors, bare-metal). | Requires provider implementation (InfrastructureMachinePool). |
| Use Case | Custom topologies, strict node placement, bare-metal. | High-volume cloud auto-scaling, spot instance pools. |
6. Template Blueprints vs. Runtime Objects
A MachineDeployment cannot point to static AWSMachine or KubeadmConfig instances, as every worker host requires a unique infrastructure object and bootstrap secret.
Instead, deployment resources reference Templates:
apiVersion: cluster.x-k8s.io/v1beta2
kind: MachineDeployment
metadata:
name: production-workers
spec:
clusterName: production-us-east
replicas: 3
template:
spec:
clusterName: production-us-east
bootstrap:
configRef:
apiGroup: bootstrap.cluster.x-k8s.io
kind: KubeadmConfigTemplate
name: production-workers-bootstrap
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: AWSMachineTemplate
name: production-workers-infra
flowchart TD
BT["KubeadmConfigTemplate"] -. Factory Blueprint .-> BC1["KubeadmConfig 1"] & BC2["KubeadmConfig 2"] & BC3["KubeadmConfig 3"]
IT["AWSMachineTemplate"] -. Factory Blueprint .-> IM1["AWSMachine 1"] & IM2["AWSMachine 2"] & IM3["AWSMachine 3"]
BC1 & IM1 --> M1["Machine 1"]
BC2 & IM2 --> M2["Machine 2"]
BC3 & IM3 --> M3["Machine 3"]
Templates serve as immutable factory blueprints. When MachineSet provisions a new replica, it clones the template spec to produce concrete runtime instances.
7. Contract References vs. OwnerReferences
Understanding CAPI requires distinguishing between Contract References and OwnerReferences:
flowchart TD
subgraph Ref["Contract Reference (spec.infrastructureRef / spec.bootstrap.configRef)"]
MA["Machine"] -. Pointer / Functional Dependency .-> IMA["InfrastructureMachine"]
end
subgraph OwnerRef["OwnerReference (metadata.ownerReferences)"]
CL["Cluster"] ==>|Garbage Collection Ownership| MD["MachineDeployment"]
MD ==>|Garbage Collection Ownership| MS["MachineSet"]
MS ==>|Garbage Collection Ownership| M["Machine"]
M ==>|Garbage Collection Ownership| IMA
end
| Parameter | Contract Reference (spec.*Ref) | OwnerReference (metadata.ownerReferences) |
|---|---|---|
| Purpose | Connects functional components across providers. | Defines Kubernetes garbage collection and cascading deletion. |
| Direction | Points from parent to dependency (Machine → AWSMachine). | Points from child to parent (AWSMachine → Machine). |
| Mutability | Set during creation; defines resource bindings. | Injected by controllers during object instantiation. |
8. Status Aggregation & Debugging Traversal
CAPI controllers communicate status asynchronously using .status.conditions. Conditions bubble up from lower-level provider resources to root intent objects:
flowchart BT
IM["InfraMachine<br/>(Status: InfrastructureReady = True)"] -->|Status Update| M["Machine<br/>(Status: Ready = True)"]
BC["KubeadmConfig<br/>(Status: DataSecretReady = True)"] -->|Status Update| M
M -->|Aggregates Ready Count| MS["MachineSet<br/>(Status: 3/3 Replicas Ready)"]
MS -->|Aggregates Ready Count| MD["MachineDeployment<br/>(Status: Available = True)"]
MD -->|Aggregates Summary| C["Cluster<br/>(Status: ControlPlaneReady & WorkersReady)"]
Diagnostic Graph Walk Procedure
When a node fails to join a cluster, navigate the object graph from top to bottom:
flowchart TD
STEP1["1. Check Cluster Status<br/>kubectl get cluster"] --> STEP2["2. Check Control Plane & Deployments<br/>kubectl get kcp,md"]
STEP2 --> STEP3["3. Inspect Machine Readiness<br/>kubectl get machines"]
STEP3 --> STEP4{"Identify Pending Machine"}
STEP4 -->|Check Bootstrap| STEP5["Inspect KubeadmConfig<br/>kubectl describe kubeadmconfig <name>"]
STEP4 -->|Check Provider VM| STEP6["Inspect InfrastructureMachine<br/>kubectl describe awsmachine <name>"]
9. Key Learning Takeaways
- Three-Layer Architecture: CAPI separates objects into Cluster Intent, Machine Lifecycle, and Provider Implementation.
- Analogy Alignment:
MachineDeployment→MachineSet→Machinedirectly mirrorsDeployment→ReplicaSet→Pod. - Machine != Node:
Machinelives in the management cluster;Nodelives in the workload cluster. They correlate viaspec.providerID. - Blueprints via Templates: Deployments use
Templates(AWSMachineTemplate,KubeadmConfigTemplate) as factories to instantiate concrete resources per machine. - Reference Dualism:
spec.*Refestablishes functional contracts;metadata.ownerReferencesdictates cascading garbage collection during deletion.
10. Self-Check Questions
- Why does a
MachineDeploymentreference anInfrastructureMachineTemplateinstead of anInfrastructureMachinedirectly? - If a
Nodein the workload cluster is manually deleted usingkubectl delete node, how does the management cluster detect and repair the failure? - What is the fundamental architectural difference between
MachineDeploymentandMachinePool? - How do
Contract ReferencesandOwnerReferencesdiffer during a cascading cluster deletion (kubectl delete cluster <name>)?
Next Milestone in the Learning Journey
In Part 04: Building the First Cluster API Environment, we will put this object model into practice by initializing a local management cluster, deploying provider CRDs using clusterctl, and executing an end-to-end workload cluster provisioning sequence.