Nehany Kubernetes klasztert uzemeltetek bare metalon, Cluster API-val es BYOH (Bring Your Own Host) providerrel. Eddig minden upgrade ugyanarra a forgatokonyvre epult: node drain, machine torles, ujraprovisionalas, varakozas. Mukodik, de 40+ node es szuk tartalek kapacitas mellett ez brutal lassu.
A Cluster API v1.12 par hete jelent meg, es nekem az in-place update volt a legfontosabb ujdonsag. Nem kell minden valtozasnal uj gepeket epiteni, bizonyos modositasok mehetnek a mar futo machine-okra is. A mult heten ezt teszteltem a staging klaszterunkon, es meglepoen jo eredmenyt kaptam.
Hol faj az immutable rollout
Az immutable megkozelitest tovabbra is szeretem. A problema az ara bare metalon. Egy uj machine letrehozasa azt jelenti, hogy PXE boot, teljes OS telepites, klaszterhez csatlakozas, image-ek ujrahuzasa. Jo esetben is 15-20 perc node-onkent.
Ha csak egy kisebb valtozas kell, peldaul kubelet credential rotacio vagy egy cloud-init user modositas, ez mar tulzas. Mi is nyultunk Ansible side-channel megoldasokhoz, de ezzel pont a deklarativ mukodesbol engedunk.
Hogyan mukodik az in-place update v1.12-ben
Az egesz update extensionokra epul. Runtime SDK hookokat irsz, amikkel megmondod a CAPI-nak, hogy az adott diffet tudod helyben kezelni.
A folyamat roviden:
- Modositas tortenik a Machine specben, tipikusan KubeadmControlPlane vagy MachineDeployment oldalon.
- A CAPI ellenorzi, van-e regisztralt extension, ami kezeli ezt a diffet.
- Ha van, meghivja az extensiont, es a valtozas helyben lefut.
- Ha nincs, marad a klasszikus rollout.
Tehat nem az a kerdes, hogy mutable vagy immutable. Inkabb az, hogy a CAPI minden valtozashoz a jobb utat valasztja.
Beallitas
Eloszor kapcsold be a feature gate-eket a clusterctl configban vagy a CAPI controller deploymentben:
apiVersion: v1
kind: ConfigMap
metadata:
name: capi-feature-gates
namespace: capi-system
data:
feature-gates: "InPlaceUpdates=true,RuntimeSDK=true"
Utana jon az update extension. En egy egyszeru verziot irtam credential rotaciora es metadata modositasokra. Minimum a BeforeUpdateMachine es UpdateMachine hook kell:
func (h *Handler) BeforeUpdateMachine(ctx context.Context, req *runtimehooksv1.BeforeUpdateMachineRequest) *runtimehooksv1.BeforeUpdateMachineResponse {
resp := &runtimehooksv1.BeforeUpdateMachineResponse{}
oldSpec := req.OldMachine.Spec
newSpec := req.NewMachine.Spec
// Csak a bizonyitottan biztonsagos valtozasokat kezeljuk helyben
if onlyLabelsOrAnnotationsChanged(oldSpec, newSpec) {
resp.RetryAfterSeconds = 0
resp.Status = runtimehooksv1.ResponseStatusSuccess
return resp
}
// Minden mas menjen rollouttal
resp.Status = runtimehooksv1.ResponseStatusFailure
return resp
}
Az extension regisztralasa egy ExtensionConfig objektummal tortenik:
apiVersion: runtime.cluster.x-k8s.io/v1alpha1
kind: ExtensionConfig
metadata:
name: inplace-updater
spec:
clientConfig:
service:
name: inplace-updater
namespace: capi-system
port: 8443
namespaceSelector:
matchLabels:
cluster.x-k8s.io/managed: "true"
Mit teszteltem a gyakorlatban
Harom scenariot futtattam stagingen (12 node, BYOH provider, Ubuntu 22.04):
1. Worker label valtozas
Egy custom labelt modositottam a MachineDeployment templateben. A CAPI nem gorgette ujra a 8 workert, hanem helyben patchelte a labeleket. Osszesen kb. 3 masodperc volt. Korabban ugyanez tobb mint ket ora rolloutot jelentett.
2. Kubelet config frissites
A maxPods erteket 110-rol 150-re emeltem. Az extension SSH-val belepett a node-ra, atirta a kubelet configot, majd ujrainditotta a kubeletet. A node vegig klaszterben maradt, pod eviction nem tortent.
3. Control plane Kubernetes verzio update
A KubeadmControlPlane verziot 1.31.3-rol 1.31.4-re emeltem. A CAPI helyesen ugy dontott, hogy ezt nem szabad in-place modon kezelni, es standard rolling replacementet csinalt. Pont ezt vartam.
Lancolt upgrade
A masik eros ujitas a lancolt upgrade. ClusterClass mellett eleg a topologiaban verziot emelni, es a CAPI intezi a sorrendet: eloszor control plane, utana workerek.
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: staging
spec:
topology:
class: my-cluster-class
version: v1.31.4 # csak ezt kell emelni
controlPlane:
replicas: 3
workers:
machineDeployments:
- class: default-worker
name: md-0
replicas: 8
Verziot modositasz, apply, es a CAPI vegigviszi. Nalunk 1.31.3-rol 1.31.4-re tisztan lefutott: control plane node-ok egyesevel, utana workerek batchenkent a maxUnavailable szerint.
Buktatok
Feature gate-ek kellenek. Az InPlaceUpdates es a RuntimeSDK is legyen bekapcsolva.
Az extension legyen stabil. Ha feluton elszall, a machine rossz allapotban maradhat. Nincs automatikus rollback, ugyhogy idempotens lepesek es korrekt hibakezeles kell.
BYOH mellett marad egyedi munka. Egyszerubb metadata valtozasokra jo, de OS-szintu feladatokhoz jellemzoen sajat extension kell.
Nincs dry-run. Ma meg nincs olyan elonezet, ami megmondja, hogy adott diffre in-place vagy rollout lesz. Ezert staging teszteles kotelezo.
Megerte?
A mi bare-metal kornyezetunkben egyertelmuen igen. Mar csak a label valtozasokkal orakat nyerunk, a lancolt upgrade pedig rengeteg kezi koordinaciot vesz le a vallunkrol.
Cloudon, ahol 2-3 perc alatt jon uj node, kisebb a kulonbseg, de az in-place update ott is hasznos lehet alacsony kockazatu, nem diszruptiv valtozasoknal.
Nalam a tanulsag: konzervativan kell kezdeni. Ahol biztos a helyben frissites, ott hasznald, minden masnal nyugodtan maradjon a klasszikus rollout.
A kovetkezo lepes nalunk a tanusitvany rotacio es nehany kubelet flag kezelese lesz. Ha rendbe rakom a kodot, felteszem GitHubra.