CAPI Parte 2: Anatomia di Cluster API - Componenti e Meccanismi
Architettura dei Componenti CAPI
Cluster API implementa un’architettura modulare basata sul pattern dei controller Kubernetes, dove ogni componente ha responsabilità specifiche e ben definite. Questa separazione delle responsabilità garantisce estensibilità, manutenibilità e testabilità del sistema.
Management Cluster vs Workload Cluster
La distinzione fondamentale in CAPI è la separazione tra il cluster che gestisce l’infrastruttura e i cluster che eseguono i workload applicativi.
Management Cluster
Il Management Cluster serve come hub di controllo centrale per l’infrastruttura Kubernetes. Le sue caratteristiche principali includono:
Responsabilità operative:
- Hosting dei controller CAPI core
- Archiviazione delle Custom Resource Definitions che rappresentano lo stato desiderato
- Orchestrazione del ciclo di vita dei Workload Cluster
- Gestione delle credenziali di accesso all’infrastruttura
Requisiti tecnici:
- Cluster Kubernetes standard (può essere locale con kind)
- Accesso di rete ai provider di infrastruttura
- Capacità computazionale limitata (principalmente per i controller)
- High availability opzionale ma raccomandata per ambienti production
Workload Cluster
I Workload Cluster rappresentano i cluster Kubernetes di destinazione dove vengono deployate le applicazioni business. Caratteristiche distintive:
Lifecycle gestito dichiarativamente:
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: workload-cluster-01
spec:
controlPlaneRef:
kind: TalosControlPlane
name: workload-cluster-01-control-plane
infrastructureRef:
kind: ProxmoxCluster
name: workload-cluster-01-proxmox
Noi definiamo solamente le caratteristiche che desideriamo, in questo caso un control plane gestito tramite il controller TalosControlPlane
, e il sistema si occupa di come raggiungere questo stato.
Isolamento operativo:
- Nessun accesso diretto ai componenti CAPI
- Gestione tramite
kubeconfig
generato automaticamente - Scaling e maintenance orchestrati dal Management Cluster
Componenti Core di CAPI
CAPI Core Controller
Il Core Controller rappresenta il cervello operativo di CAPI, responsabile dell’orchestrazione di alto livello del ciclo di vita dei cluster.
Cluster Controller
Il Cluster Controller gestisce la risorsa Cluster
, coordinando l’interazione tra infrastructure provider e control plane provider:
Funzioni principali:
- Validazione della configurazione del cluster
- Orchestrazione della sequenza di provisioning
- Gestione dello stato
controlPlaneReady
einfrastructureReady
- Generazione del
kubeconfig
per l’accesso al workload cluster
Reconciliation logic:
// Pseudocodice del reconciliation loop
func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) {
// 1. Fetch cluster object
cluster := &clusterv1.Cluster{}
// 2. Reconcile infrastructure
if !cluster.Status.InfrastructureReady {
return r.reconcileInfrastructure(ctx, cluster)
}
// 3. Reconcile control plane
if !cluster.Status.ControlPlaneReady {
return r.reconcileControlPlane(ctx, cluster)
}
// 4. Generate kubeconfig
return r.reconcileKubeconfig(ctx, cluster)
}
Machine Controller
Il Machine Controller gestisce il ciclo di vita delle singole istanze di calcolo che compongono il cluster:
Responsabilità operative:
- Coordinamento con Infrastructure Provider per provisioning VM
- Gestione del processo di bootstrap tramite Bootstrap Provider
- Monitoring dello stato dei nodi e recovery automatico
- Implementazione delle politiche di sostituzione per oggetti Machine immutabili
Stati del ciclo di vita:
status:
phase: "Running" # Pending, Provisioning, Provisioned, Running, Deleting, Failed
addresses:
- type: "InternalIP"
address: "192.168.1.100"
nodeRef:
kind: "Node"
name: "workload-cluster-01-control-plane-abc123"
Bootstrap Provider
Il “bootstrap provider” in Kubernetes Cluster API è un componente fondamentale che si occupa di inizializzare il primo nodo di un nuovo cluster Kubernetes, noto come “control plane node” o “master node”. In parole semplici, è il motore che avvia il cluster. Esistono diverse implementazioni in base al “modo” in cui vogliamo che il cluster sia inizializzato
Kubeadm Bootstrap Provider
Il provider kubeadm rappresenta l’implementazione di riferimento, utilizzando kubeadm per l’inizializzazione dei nodi:
Generazione cloud-init:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfig
metadata:
name: worker-node-config
spec:
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
preKubeadmCommands:
- "swapoff -a"
- "modprobe br_netfilter"
postKubeadmCommands:
- "kubectl label node ${HOSTNAME} node-role.kubernetes.io/worker="
Talos Bootstrap Provider
Il Talos Bootstrap Provider genera configurazioni specifiche per Talos Linux:
Configurazione Talos:
apiVersion: bootstrap.cluster.x-k8s.io/v1alpha3
kind: TalosConfig
metadata:
name: talos-worker-config
spec:
generateType: "join"
talosVersion: "v1.7.0"
configPatches:
- op: "add"
path: "/machine/network/interfaces"
value:
- interface: "eth0"
dhcp: true
Control Plane Provider
Il “control plane provider” in Kubernetes Cluster API è un componente chiave che si occupa della gestione del piano di controllo del cluster (control plane) dopo che il primo nodo è stato inizializzato. A differenza del bootstrap provider, che si limita ad avviare il primo nodo, il control plane provider gestisce l’intero ciclo di vita dei nodi del piano di controllo, garantendo che il cluster rimanga stabile e ad alta disponibilità.
Come per il bootstrap provider, anche in questo caso abbiamo diverse implementazioni a seconda del caso d’uso.
KubeadmControlPlane Provider
Il KubeadmControlPlane provider utilizza kubeadm per gestire il control plane:
Configurazione dichiarativa:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
name: cluster-control-plane
spec:
replicas: 3
version: "v1.29.0"
kubeadmConfigSpec:
clusterConfiguration:
etcd:
local:
dataDir: "/var/lib/etcd"
networking:
serviceSubnet: "10.96.0.0/16"
podSubnet: "10.244.0.0/16"
Rolling update strategy:
- Update sequenziali per mantenere quorum etcd
- Validation dei componenti prima del prossimo nodo
- Rollback automatico in caso di failure
TalosControlPlane Provider
Il TalosControlPlane provider offre gestione nativa per Talos Linux:
Vantaggi specifici:
- Configurazione immutabile via API
- Upgrade atomici senza downtime
- Eliminazione di SSH e accesso shell
- Integration nativa con Talos API
Infrastructure Provider
L’infrastrucure provider è il componente che si occupa di dialogare con le risorse hardware, siano essere cloud o on-premise, con lo scopo di inizializzare le risorse che formeranno il cluster.
A differenza del bootstrap provider e del control plane provider, che si concentrano specificamente sulla configurazione di Kubernetes, l’infrastructure provider si occupa di tutto ciò che sta “sotto” il cluster.
Provider Pattern
Tutti i provider implementano il contratto standard CAPI:
InfraCluster Resource:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ProxmoxCluster
spec:
controlPlaneEndpoint:
host: "192.168.1.100"
port: 6443
ipv4Config:
addresses: ["192.168.1.100-192.168.1.110"]
prefix: 24
gateway: "192.168.1.1"
InfraMachine Resource:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ProxmoxMachine
spec:
sourceNode: "proxmox-node-01"
templateID: 8700
diskSize: "20G"
memoryMiB: 4096
numCores: 2
Proxmox Provider
Il Cluster API Provider Proxmox fornisce integrazione nativa con Proxmox VE:
Funzionalità supportate:
- VM provisioning tramite Proxmox API
- Template cloning e customization
- Network configuration automatica
- Storage management per dischi VM
- Integration con cloud-init per bootstrap
Custom Resource Definitions (CRDs)
Le CRDs rappresentano il linguaggio dichiarativo di CAPI, permettendo di definire infrastruttura Kubernetes attraverso manifest YAML standard.
Cluster CRD
La risorsa Cluster
serve come entry point dichiarativo per definire un cluster Kubernetes completo:
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: production-cluster
namespace: default
spec:
clusterNetwork:
services:
cidrBlocks: ["10.96.0.0/16"]
pods:
cidrBlocks: ["10.244.0.0/16"]
controlPlaneEndpoint:
host: "192.168.1.100"
port: 6443
controlPlaneRef:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: TalosControlPlane
name: production-control-plane
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ProxmoxCluster
name: production-proxmox
Campi critici:
controlPlaneRef
: riferimento al provider che gestisce il control planeinfrastructureRef
: riferimento al provider di infrastrutturaclusterNetwork
: configurazione di rete del clustercontrolPlaneEndpoint
: endpoint per l’accesso all’API server
Machine CRD
La risorsa Machine
rappresenta l’astrazione di una singola istanza di calcolo destinata a diventare un nodo Kubernetes:
apiVersion: cluster.x-k8s.io/v1beta1
kind: Machine
metadata:
name: worker-node-01
spec:
version: "v1.29.0"
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: TalosConfig
name: worker-bootstrap-config
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ProxmoxMachine
name: worker-node-01-proxmox
status:
phase: "Running"
addresses:
- type: "InternalIP"
address: "192.168.1.101"
nodeRef:
kind: "Node"
name: "worker-node-01"
Principio di immutabilità: Le Machine sono progettate come immutable infrastructure. Modifiche alla specifica richiedono sostituzione completa dell’istanza piuttosto che update in-place.
MachineSet CRD
MachineSet
implementa il pattern ReplicaSet per gestire gruppi di Machine identiche:
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineSet
metadata:
name: worker-machines
spec:
replicas: 3
selector:
matchLabels:
cluster.x-k8s.io/cluster-name: "production-cluster"
template:
metadata:
labels:
cluster.x-k8s.io/cluster-name: "production-cluster"
spec:
version: "v1.29.0"
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: TalosConfig
name: worker-bootstrap-config
Funzionalità:
- Mantiene costante il numero di macchine desiderato
- Sostiusce macchine in caso di fail
- Gestisce scale up/down
- Configurazione basata su template
MachineDeployment CRD
MachineDeployment
fornisce update dichiarativi e rolling changes per flotte di Machine:
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
name: worker-deployment
spec:
replicas: 5
selector:
matchLabels:
cluster.x-k8s.io/cluster-name: "production-cluster"
template:
# Machine template specification
strategy:
type: "RollingUpdate"
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
Rolling update process:
- Crea un nuovo MachineSet con la configurazione aggiornata
- Scala il nuovo MachineSet in base alla strategia definita
- Riduci il vecchio MachineSet man mano che le nuove macchine diventano pronte
- Elimina il vecchio MachineSet al termine della migrazione
Reconciliation Loop e Control Theory
Principi del Control Loop
CAPI implementa il controller pattern di Kubernetes, basato sui principi della teoria del controllo:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Desired │───▶│ Controller │───▶│ Actual │
│ State │ │ │ │ State │
│ (Spec) │ │ │ │ (Status) │
└─────────────┘ └──────────────┘ └─────────────┘
▲ ▲ │
│ │ │
│ ┌──────────────┐ │
└────────────│ Feedback │◀───────────┘
│ Loop │
└──────────────┘
Algoritmo di Reconciliation
Ogni controller CAPI implementa la stessa logica base:
func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
// 1. Observe - Fetch current state
obj := &v1beta1.Object{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// 2. Analyze - Compare desired vs actual state
if obj.DeletionTimestamp != nil {
return r.reconcileDelete(ctx, obj)
}
// 3. Act - Take corrective action
return r.reconcileNormal(ctx, obj)
}
Idempotenza e Error Handling
Principi di Idempotenza
Le operazioni CAPI sono progettate per essere idempotenti, permettendo esecuzione sicura multipla:
Esempi di operazioni idempotenti:
- Provisioning VM: verifica esistenza prima della creazione
- Configuration update: apply solo se diversa dallo stato corrente
- Resource cleanup: ignora errori “not found” durante la cancellazione
Gestione Errori e Retry
CAPI implementa strategie di retry sofisticate per gestire errori transienti:
// Exponential backoff per retry
return ctrl.Result{
Requeue: true,
RequeueAfter: time.Duration(math.Pow(2, float64(retryCount))) * time.Second,
}, nil
Categorie di errori:
- Transient errors: network timeouts, temporary API unavailability
- Configuration errors: invalid specifications, missing resources
- Infrastructure errors: quota exceeded, hardware failures
Flusso End-to-End: Da Manifest a Cluster
Phase 1: Resource Creation
kubectl apply -f cluster-manifest.yaml
Sequenza di eventi:
- API Server: valida e persiste le risorse nel cluster
- CAPI Core Controller: rileva nuova risorsa
Cluster
- Admission Controllers: applicano policies e defaults
- Event Recording: registra eventi per debugging
Phase 2: Infrastructure Provisioning
Cluster Controller ──→ Infrastructure Provider ──→ Proxmox API
│ │ │
│ ▼ ▼
│ ProxmoxCluster Created VM Template Cloned
│ │ │
▼ ▼ ▼
Status Update Infrastructure Ready VM Started
Attività del Proxmox Provider:
- Clone VM template per ogni machine
- Configure network interfaces
- Inject cloud-init configuration
- Start VM instances
- Update ProxmoxMachine status
Phase 3: Bootstrap Process
Machine Controller ──→ Bootstrap Provider ──→ TalosConfig Generation
│ │ │
│ ▼ ▼
│ Cloud-Init Generated Config Applied to VM
│ │ │
▼ ▼ ▼
Bootstrap Ready Node Joins Cluster Kubernetes Ready
Bootstrap Provider activities:
- Genera configurazioni node-specific
- Genera token di join e certificati
- Configura prametri kubelet
- Setup container runtime
- Applica policy di sicurezza
Phase 4: Control Plane Initialization
Per control plane nodes, il processo include passaggi aggiuntivi:
- Primo nodo: inizializza cluster etcd
- Genera certificati per il cluster
- Avvia API server, controller-manager, scheduler
- Nodi successivi: join al cluster esistente
- Configura endpoint per il load balancer
Phase 5: Kubeconfig Generation
Una volta che l’API server è accessibile viene generato, all’interno del management cluster, un secret che contiene il kubeconfig
necessario per connettersi al workload cluster:
// Controller genera kubeconfig
kubeconfig := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-kubeconfig", cluster.Name),
Namespace: cluster.Namespace,
},
Data: map[string][]byte{
"value": kubeconfigBytes,
},
}
Contenuto kubeconfig:
- Certificate Authority del cluster
- Client certificate per admin access
- API server endpoint configuration
- Context configuration per
kubectl
Debugging e Resouce Inspection
Monitoring Controller Health
# Check controller pod status
kubectl get pods -n capi-system
kubectl get pods -n capx-system # Infrastructure provider
kubectl get pods -n capi-bootstrap-talos-system
# Review controller logs
kubectl logs -n capi-system deployment/capi-controller-manager
kubectl logs -n capx-system deployment/capx-controller-manager
Resource Status Inspection
# Check cluster status
kubectl get cluster production-cluster -o wide
# Examine machine lifecycle
kubectl get machines -A -o wide
# Review events for troubleshooting
kubectl describe cluster production-cluster
kubectl get events --sort-by='.lastTimestamp' -A
Common Debugging Patterns
Infrastructure provisioning failures:
# Check infrastructure resources
kubectl get proxmoxclusters,proxmoxmachines -A -o wide
kubectl describe proxmoxmachine <machine-name>
# Verify Proxmox connectivity
curl -k -H "Authorization: PVEAPIToken=$PROXMOX_TOKEN=$PROXMOX_SECRET" \
"$PROXMOX_URL/version"
Bootstrap failures:
# Examine bootstrap configuration
kubectl get talosconfigs -A -o yaml
kubectl describe talosconfig <config-name>
# Check cloud-init logs on VM
# (requires VM console access)
tail -f /var/log/cloud-init-output.log
L’architettura modulare di CAPI, basata su controller specializzati e CRDs estensibili, fornisce un framework robusto per gestire cluster Kubernetes su qualsiasi infrastruttura. La comprensione di questi componenti e dei loro pattern di interazione è fondamentale per implementazioni production-ready.
Per approfondimenti sull’implementazione dei controller custom e l’estensione di CAPI, consultare la Developer Guide e il Kubebuilder Book.
La prossima parte esplorerà Talos Linux e la sua integrazione nativa con CAPI, mostrando come l’OS immutabile semplifichi la gestione dei nodi Kubernetes.