Vanilla Kubernetes

Treći deo: Produkcione operacije, otpornost i enterprise integracije
Kontrolisana kubeadm nadogradnja Kubernetes klastera
X. Lifecycle, nadogradnje i oporavak klastera
45. Kontrolisana kubeadm nadogradnja – pre-check, redosled čvorova, validacija i rollback odluka

Nadogradnja Kubernetes klastera nije paketna operacija koja se istovremeno pokreće na svim serverima. Ona je kontrolisana promena distribuiranog sistema u kome se tokom ograničenog vremena namerno pojavljuju različite, ali podržane verzije API servera, kontrolera, kubelet-a i dodataka. Uspeh zato ne znači samo da je komanda kubeadm upgrade završila kodom 0. Potrebno je dokazati da su API i etcd zdravi, da scheduler i kontroleri rade, da svi nodovi ponovo postaju Ready, da mreža, DNS, storage i kritični workload-i zadržavaju funkciju i da je promena ostala unutar unapred definisanih granica rizika.

Lekcija se neposredno oslanja na inventar i matricu kompatibilnosti iz lekcije 43 i na PKI i kubeconfig lifecycle iz lekcije 44. Ovde se ti dokazi pretvaraju u change plan i izvršnu proceduru za klaster koji je napravljen i kojim se upravlja pomoću kubeadm-a. Detaljan etcd snapshot, restore, quorum i povratak kontrolne ravni ostaju tema lekcije 46; u ovoj lekciji se utvrđuje kada se upgrade može bezbedno nastaviti ili ponoviti, a kada je potreban formalni disaster recovery.

Granica primene: postupak važi za self-managed kubeadm klastere sa static Pod kontrolnom ravni i stacked ili eksternim etcd-om. Managed Kubernetes servis, komercijalna distribucija ili drugačiji bootstrap alat imaju sopstveni orkestrator, redosled i podržanu rollback proceduru. Komande iz ove lekcije ne treba mešati sa procedurom provajdera.

Nadogradnja kao kontrolisana promena stanja

kubeadm upravlja konfiguracijom kontrolne ravni, lokalnim static Pod manifestima, kubelet konfiguracijom i podrazumevanim dodacima CoreDNS i kube-proxy. Ne nadograđuje operativni sistem, kernel, container runtime, CNI/CSI dodatke ni aplikacione workload-e. Takođe ne rešava automatski uklonjene API verzije, ne garantuje kapacitet za evikciju Pod-ova i ne pretvara neproveren backup u upotrebljiv recovery plan. Zato se promena deli na faze sa kontrolnim tačkama, a svaka naredna faza počinje tek kada je prethodna dokazano uspešna.

FazaPromenaMinimalni dokaz pre nastavkaTačka odluke
PlaniranjeNema promene klastera; biraju se putanja, patch nivo i prozor.Kompatibilnost svih zavisnosti, release notes, odobren change i recovery plan.Go ili odlaganje.
Pre-checkRead-only provere i backup; eventualno priprema image-a i paketa.Zdrav control plane, etcd quorum, validni sertifikati, dovoljan kapacitet i testiran restore.Go/No-Go pre prve mutacije.
Prvi control-planekubeadm, static Pod manifesti, mogući etcd i sertifikati, zatim kubelet.API dostupan preko endpointa i direktno, komponentni Pod-ovi zdravi, etcd i osnovni workload test prolaze.Nastaviti ili stabilizovati.
Ostali control-planeInstance se menjaju jedna po jedna pomoću kubeadm upgrade node.Prethodna instanca potpuno zdrava; quorum i load balancer ne pokazuju degradaciju.Nastaviti, pauzirati ili vratiti saobraćaj.
Worker nodoviDrain, kubeadm node faza, kubelet/kubectl paket, restart i uncordon.Node Ready, CNI/CSI zdravi, workload-i dostupni, nema neočekivanih evikcija.Nastaviti sledeći batch.
ZatvaranjeUklanjanje privremenih mera i formalna validacija.Verzije, SLO, događaji, logovi i funkcionalni testovi stabilni tokom observation period-a.Zatvoriti change ili otvoriti problem/RCA.

Upstream podržava prelaz na sledeću minor verziju ili na noviji patch iste minor grane; preskakanje minor verzija nije podržano. Ako je klaster na 1.34.z, put do 1.36.y ima najmanje dve zasebne promene: najpre poslednji odgovarajući patch grane 1.35, puna validacija i observation period, a zatim 1.36. Za svaki korak koriste se dokumentacija i release notes baš te ciljne grane, jer se zahtevi paketa, podrazumevane vrednosti i poznati problemi menjaju.

Pre-check: uslovi koji moraju biti dokazani pre promene

Pre-check nije samo izlaz komande kubeadm upgrade plan. On objedinjuje organizacionu spremnost, zdravlje klastera, kompatibilnost infrastrukture i sposobnost oporavka. Izvodi se dovoljno rano da blokirajući nalaz može biti otklonjen, a zatim ponavlja neposredno pre maintenance prozora kako bi se otkrila promena početnog stanja.

Sledeće komande su read-only i izvršavaju se sa odobrene administratorske radne stanice. One ne zamenjuju inventar iz lekcije 43, već potvrđuju da se odobrena početna slika nije promenila.

kubectl config current-context
kubectl version -o yaml
kubectl get nodes -o wide
kubectl get --raw='/readyz?verbose'
kubectl -n kube-system get pods -o wide
kubectl get pdb -A
kubectl get events -A --sort-by='.lastTimestamp'
kubectl get apiservices
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations

Endpoint /readyz?verbose potvrđuje skup internih API server provera, ali jedan uspešan odgovor kroz load balancer ne dokazuje zdravlje svake HA instance. Zato se proveravaju static Pod-ovi po nodu, load-balancer backend health i, kada je odobreno, direktan lokalni endpoint svake instance. Događaji imaju ograničen retention i ne predstavljaju dugoročni audit trag; korelišu se sa monitoringom, journalctl i runtime logovima u vremenskom opsegu promene.

Verzija paketa, repozitorijum i konfiguracija

Community repozitorijum pkgs.k8s.io organizovan je po minor granama. Za novu minor verziju mora se omogućiti odgovarajući repozitorijum pre instalacije; istorijski apt.kubernetes.io i yum.kubernetes.io repozitorijumi su zamrznuti od 2023. i ne predstavljaju aktuelnu putanju. U produkciji se konkretna verzija prvo proverava, zatim eksplicitno navodi pri instalaciji i ponovo pin-uje/hold-uje da nenamerna opšta OS nadogradnja ne promeni kubeadm ili kubelet.

# Debian/Ubuntu: read-only pregled dostupnih verzija iz već odobrenog repozitorijuma.
sudo apt-get update
sudo apt-cache madison kubeadm
apt-cache policy kubeadm kubelet kubectl

# RPM sistemi sa DNF: read-only pregled kandidata.
sudo dnf list --showduplicates kubeadm --disableexcludes=kubernetes

# Lokalna verzija i aktivna kubeadm konfiguracija.
kubeadm version -o short
sudo kubeadm config view
sudo kubeadm certs check-expiration

kubeadm config view i certs check-expiration čitaju konfiguraciju i sertifikate, ali izlaz se čuva kao operativno osetljiv podatak. kubeadm upgrade apply i kubeadm upgrade node podrazumevano obnavljaju sertifikate kojima kubeadm upravlja na tom nodu; odluka da se koristi --certificate-renewal=false mora biti usklađena sa politikom iz lekcije 44, naročito kada organizacija ima spoljašnji CA ili zaseban renewal prozor.

Plan, diff i dry-run

Na prvom control-plane nodu, koji ima /etc/kubernetes/admin.conf, najpre se instalira ciljna verzija samo paketa kubeadm. Time se još ne menjaju Kubernetes control-plane komponente. Zatim kubeadm upgrade plan proverava dostupnost API-ja, zdravlje i version skew, prikazuje moguće ciljeve i stanja komponentnih konfiguracija. Verzija se navodi eksplicitno kada se želi izbeći oslanjanje na mrežno otkrivanje kandidata.

# Primer promenljive; zameniti stvarnom odobrenom punom verzijom.
TARGET_VERSION='v1.36.x'

sudo kubeadm upgrade plan "${TARGET_VERSION}"
sudo kubeadm upgrade diff "${TARGET_VERSION}"
sudo kubeadm upgrade apply "${TARGET_VERSION}" --dry-run

upgrade diff prikazuje očekivane razlike static Pod manifesta, a --dry-run simulira faze bez trajne promene željenog stanja. Nijedna od tih provera nije garancija da će image pull, restart, webhook ili infrastrukturna zavisnost proći u realnom trenutku. Flag-ovi --ignore-preflight-errors=all, --force, --allow-experimental-upgrades i --allow-release-candidate-upgrades nisu prečice za redovnu produkcionu promenu. Pojedinačno ignorisanje provere dopušteno je samo kada je razlog dokazan, rizik prihvaćen i kompenzaciona kontrola zapisana.

Redosled: prvi control-plane, ostale instance, pa worker nodovi

Zvanični tok je namerno asimetričan. Prvi control-plane node izvršava klastersku operaciju kubeadm upgrade apply. Ostale control-plane instance zatim lokalno usklađuju svoje manifeste pomoću kubeadm upgrade node. Worker nodovi dolaze posle kontrolne ravni, jedan po jedan ili u malim batch-evima čiji paralelizam ne prelazi raspoloživi kapacitet i dozvoljene PDB prekide.

RedLokacijaKubeadm radnjaZašto baš tako
1Izabrani prvi control-plane nodekubeadm upgrade apply v1.xx.yPokreće klasterske faze, konvertuje konfiguraciju i postavlja ciljnu verziju.
2Svaki dodatni control-plane, sekvencijalnokubeadm upgrade nodePreuzima ClusterConfiguration i regeneriše lokalne control-plane i kubelet konfiguracije.
3Worker nodovi po odobrenom batch-ukubeadm upgrade nodePreuzima i prilagođava kubelet konfiguraciju; nema lokalne control-plane manifeste.
4Svaki node tokom svoje etapeUpgrade kubelet/kubectl paketa, restart kubelet-aKubeadm ne nadograđuje OS paket kubelet-a umesto administratora.

Od v1.28 kubeadm podrazumevano čeka da sve control-plane instance budu nadograđene pre upgrade-a kube-proxy i CoreDNS dodataka. Zato se poslednja control-plane instanca ne pokreće dok sve prethodne nisu potpuno završile i prošle validaciju. CNI se nadograđuje ručno prema dokumentaciji njegovog projekta i njegovom propisanom mestu u redosledu; kubeadm to ne radi. Isto važi za CSI i druge add-on komponente.

Drain, PDB i granice dostupnosti

Minor upgrade kubelet-a zahteva prethodni drain noda. kubectl drain ga označava kao unschedulable i koristi Eviction API, pa poštuje PDB i grace period. DaemonSet Pod-ovi se ne eviktuju i zato se koristi --ignore-daemonsets. Uspešan drain znači da su eviktovani Pod-ovi koje je alat trebalo da ukloni; ne znači automatski da je aplikacija dostupna, da su svi Pod-ovi rescheduled niti da su podaci bezbedni.

NODE='cp-1.example.internal'

# Read-only pregled pre evikcije.
kubectl get node "${NODE}"
kubectl get pods -A --field-selector "spec.nodeName=${NODE}" -o wide
kubectl get pdb -A

# State-changing: cordon i kontrolisana evikcija.
kubectl drain "${NODE}" \
  --ignore-daemonsets \
  --timeout=20m

# Posle uspešne lokalne nadogradnje i validacije noda.
kubectl uncordon "${NODE}"

Flag --delete-emptydir-data dozvoljava brisanje podataka iz emptyDir volumena na eviktovanom Pod-u i ne dodaje se rutinski. --force može obrisati Pod bez odgovarajućeg kontrolera i zato se ne koristi dok vlasnik workload-a ne potvrdi posledicu i način povratka. Ako PDB blokira drain, to je signal da trenutno nema dozvoljenog disruption budget-a; PDB se ne briše automatski. Prvo se proveravaju zdravlje replika, pending Pod-ovi, kapacitet, affinity/topology uslovi i politika nezdravih Pod-ova.

Control-plane node može hostovati CoreDNS, ingress ili druge workload-e, u zavisnosti od taint/toleration konfiguracije. Drain ne zaustavlja static Pod-ove jer njima direktno upravlja kubelet. U HA topologiji se pre rada po mogućnosti uklanja konkretni backend iz load balancer rotacije, čeka pražnjenje konekcija i potvrđuje da preostale instance nose saobraćaj. U stacked etcd topologiji se nikada ne rade dve control-plane instance istovremeno: time se štite i API kapacitet i etcd quorum.

Izvršenje na control-plane i worker nodovima

Prvi control-plane node

Nakon odobrenog plana i backup-a, na prvom control-plane nodu se instalira ciljna verzija kubeadm-a i potvrđuje binarni fajl. Paketna sintaksa zavisi od distribucije i tačne revizije paketa; wildcard iz zvaničnog primera treba zameniti potvrđenom verzijom iz lokalnog repozitorijuma. Sledeći Debian/Ubuntu primer menja stanje hosta i izvršava se kao root/sudo u maintenance prozoru.

# Primer: postaviti punu distribucionu verziju, npr. 1.36.x-1.1.
K8S_PKG_VERSION='1.36.x-1.1'
TARGET_VERSION='v1.36.x'

sudo apt-mark unhold kubeadm
sudo apt-get update
sudo apt-get install -y kubeadm="${K8S_PKG_VERSION}"
sudo apt-mark hold kubeadm
kubeadm version -o short

sudo kubeadm upgrade plan "${TARGET_VERSION}"
sudo kubeadm upgrade apply "${TARGET_VERSION}"

upgrade apply izvodi preflight, nadogradnju kontrolne ravni, upload kubeadm/kubelet konfiguracije, kubelet-config, bootstrap-token, add-on i post-upgrade faze. Može nadograditi lokalni etcd kada je --etcd-upgrade=true, što je podrazumevano, i obnavlja kubeadm-managed sertifikate ako nije isključeno. Komanda čuva backup-e lokalnog etcd člana i promenjenih manifesta pod /etc/kubernetes/tmp; oni su pomoć pri lokalnom neuspehu, ali nisu zamena za nezavisni etcd snapshot i testiran restore.

Posle uspešnog apply-a node se drain-uje pre minor upgrade-a kubelet-a, zatim se instaliraju kubelet i po potrebi lokalni kubectl, restartuje servis i radi validacija. Ako je node već drain-ovan prema odobrenom runbook-u, korak se ne ponavlja naslepo.

sudo apt-mark unhold kubelet kubectl
sudo apt-get update
sudo apt-get install -y \
  kubelet="${K8S_PKG_VERSION}" \
  kubectl="${K8S_PKG_VERSION}"
sudo apt-mark hold kubelet kubectl

sudo systemctl daemon-reload
sudo systemctl restart kubelet
sudo systemctl status kubelet --no-pager
sudo journalctl -u kubelet --since '-10 minutes' --no-pager

Dodatne control-plane instance

Na svakoj dodatnoj instanci instalira se ista ciljna verzija kubeadm-a, proverava se lokalna i klasterska spremnost i pokreće kubeadm upgrade node, ne upgrade apply. Zatim se radi drain, paketni upgrade kubelet-a/kubectl-a, restart, validacija i uncordon. Sledeća instanca počinje tek kada je prethodna zdrava kroz lokalni pogled, cluster endpoint i load balancer.

sudo kubeadm upgrade node

sudo systemctl daemon-reload
sudo systemctl restart kubelet

kubectl get node "$(hostname)" -o wide
kubectl -n kube-system get pods \
  --field-selector "spec.nodeName=$(hostname)" -o wide

Pretpostavka da hostname identično odgovara imenu Node objekta mora biti potvrđena; u suprotnom se koristi stvarno ime iz kubectl get nodes. Ako organizacija primenjuje patches direktorijum za kubeadm manifeste, isti odobreni i verzionisani patches moraju biti dostupni na svakoj instanci. --config se ne koristi kao prikriveni način reconfiguracije tokom upgrade-a: upstream upozorava da workflow nije projektovan za menjanje postojeće klasterske konfiguracije tim putem.

Worker nodovi i batch politika

Na worker nodu kubeadm upgrade node preuzima ClusterConfiguration i osvežava lokalnu kubelet konfiguraciju. Zatim se kubelet paket nadograđuje i servis restartuje. Batch veličina se ne bira po brzini, već kao minimum između raspoloživog viška kapaciteta, PDB dozvole, topology raspodele, storage ograničenja i operativne sposobnosti tima da paralelno dijagnostikuje kvar. Prvi worker je canary; naredni batch počinje tek posle observation period-a.

WORKER='worker-1.example.internal'

# Sa administratorske radne stanice.
kubectl drain "${WORKER}" --ignore-daemonsets --timeout=20m

# Na worker nodu, sa sudo privilegijom.
sudo kubeadm upgrade node
sudo systemctl daemon-reload
sudo systemctl restart kubelet
sudo systemctl status kubelet --no-pager

# Sa administratorske radne stanice, tek posle lokalne provere.
kubectl get node "${WORKER}" -o wide
kubectl uncordon "${WORKER}"
Kubernetes 1.36: na Linux nodovima FailCgroupV1 podrazumevano je true, pa kubelet zahteva cgroups v2. Pre prelaska na 1.36 treba dokazati da OS, kernel, runtime i svi node pool-ovi koriste podržan cgroup v2 režim. Ovo nije problem koji treba otkrivati tek posle restarta kubelet-a.

Validacija posle svake etape

Validacija je slojevita. Komponenta može biti Running, a da nije spremna; node može biti Ready, a da DNS, CNI ili CSI ne rade za nove Pod-ove; API endpoint može odgovarati, a jedan load-balancer backend biti neispravan. Zato se proveravaju deklarisano stanje, health endpointi, realan promet i poslovno relevantna funkcija.

SlojDokazNeprihvatljiv nalaz
VerzijeAPI server instance, kubelet po nodu, kube-proxy/CoreDNS i ciljna matrica.Node ili control-plane izvan planiranog prelaznog skew-a.
API/control plane/livez, /readyz?verbose, static Pod readiness, leader election i LB backend health.Nestabilan endpoint, restart loop, neuspešna interna ready provera.
etcdEndpoint health/status, stabilan leader i member quorum prema odobrenom TLS postupku.Gubitak člana/quorum-a, rast latencije, alarm ili neusaglašeni članovi.
Node/runtimeReady, kubelet bez ponavljajućih grešaka, CRI i image pull funkcionalni.NotReady, CNI not initialized, cgroup ili sandbox greške.
Mreža/DNSNovi test Pod dobija IP, rešava cluster DNS i pristupa Service-u.Postojeći Pod radi, ali novi sandbox/IP/DNS ne prolazi.
StorageCSI controller/node Pod-ovi zdravi; odobreni test attach/mount kada je moguć.Volume attach/mount timeout ili topološko blokiranje.
Workload/SLODesired/available replike, synthetic test, error rate, latency i kritični tokovi.Porast grešaka, pending replike ili kršenje SLO-a.
kubectl version -o yaml
kubectl get nodes -o wide
kubectl get --raw='/livez?verbose'
kubectl get --raw='/readyz?verbose'
kubectl -n kube-system get pods -o wide
kubectl -n kube-system get daemonset kube-proxy
kubectl -n kube-system get deployment coredns
kubectl get deployments,statefulsets -A
kubectl get events -A --sort-by='.lastTimestamp' | tail -n 100
kubectl get pods -A \
  --field-selector='status.phase!=Running,status.phase!=Succeeded'

Poslednji filter je pomoćni pregled, ali može propustiti Running Pod koji nije Ready. Zato se proveravaju readiness kolone, rollout status kritičnih kontrolera i metrike. Komanda kubectl rollout status ima smisla za konkretan poznati Deployment ili DaemonSet, ne za nekontrolisani masovni restart svih workload-a.

kubectl -n kube-system rollout status deployment/coredns --timeout=5m
kubectl -n kube-system rollout status daemonset/kube-proxy --timeout=10m

# Primer kontrolisanog testa DNS-a; menja klaster stvaranjem privremenog Pod-a.
kubectl run upgrade-dns-check \
  --image=registry.k8s.io/e2e-test-images/dnsutils:1.3 \
  --restart=Never \
  --command -- nslookup kubernetes.default.svc.cluster.local
kubectl logs upgrade-dns-check
kubectl delete pod upgrade-dns-check

Test image mora biti unapred odobren, dostupan iz internog registry-ja ako organizacija zabranjuje javni pull i kompatibilan sa politikama admission-a. U strogoj produkciji koristi se postojeći sintetički test ili unapred pripremljen namespace i ServiceAccount sa najmanjim privilegijama. Observation period se definiše pre promene; odsustvo greške tokom dva minuta nije dokaz stabilnosti ako se ključni controller reconcile ili poslovni batch izvršava ređe.

Rollback odluka: retry, stabilizacija ili disaster recovery

Kubernetes nadogradnja nema univerzalno „undo” dugme. kubeadm upgrade je projektovan kao idempotentan: ako je prekinut neočekivanim gašenjem ili privremenim kvarom, često se bezbedno ponavlja ista deklarisana ciljna verzija nakon prikupljanja dokaza i otklanjanja uzroka. To je resume/retry, ne rollback. Ručno instaliranje starijih paketa preko novijih control-plane podataka može pogoršati stanje, naročito kada je promenjena etcd verzija ili skladištena API reprezentacija.

StanjeOdlukaUslov
Pre upgrade apply, promenjen samo kubeadm paketPauza ili povratak paketa prema distribucionoj proceduri.Control plane nije mutiran; potvrditi verzijsku kompatibilnost binara i sačuvati dokaz.
Apply prekinut, API/etcd zdravi, greška prolaznaOtkloniti uzrok i ponoviti isti kubeadm upgrade apply.Dokazi potvrđuju stabilno stanje i isti cilj; ne koristiti --force refleksno.
Jedan HA control-plane node ne radi, ostali i quorum zdraviIzolovati node, vratiti LB kapacitet na zdrave instance i popraviti/rekreirati node po runbook-u.Nema nastavka na sledeći node dok redundansa nije obnovljena.
Kubelet paket ne startuje, control plane stabilanProveriti cgroup/runtime/config; po odobrenju vratiti samo host paket ili ispraviti konfiguraciju.Ne vraćati klastersko stanje zbog lokalnog paketnog kvara.
etcd nema quorum ili podaci nisu konzistentniZaustaviti rollout i aktivirati etcd disaster recovery.Restore iz potvrđenog snapshot-a po lekciji 46; nema improvizovanog kopiranja data-dir-a između članova.
Nova verzija radi, ali workload/SLO ne prolaziFreeze, mitigacija ili application/add-on rollback; procena klasterskog recovery-ja.Odluka vlasnika incidenta prema unapred definisanoj rollback granici i kompatibilnosti podataka.

Tokom upgrade-a kubeadm pravi direktorijume /etc/kubernetes/tmp/kubeadm-backup-manifests-* i, za lokalni etcd, kubeadm-backup-etcd-*. Vraćanje manifesta u /etc/kubernetes/manifests ili lokalnog etcd data direktorijuma je rizična, state-changing recovery operacija. Radi se samo prema verzijski odgovarajućoj zvaničnoj proceduri, nakon potvrde da automatski rollback nije uspeo, uz zaustavljanje komponenti i očuvanje forenzičkih kopija. Kod eksternog etcd-a kubeadm backup direktorijum za etcd je prazan.

Stop kriterijum: zaustaviti naredne batch-eve kada control plane izgubi redundansu, etcd health/quorum nije potvrđen, API ili kritični webhook nije stabilan, node ne vraća Ready u predviđenom roku, CNI/CSI/DNS test ne prolazi, error rate ili latency pređu prag, PDB blokira planirani kapacitet ili se pojavi nalaz bez vlasnika i bez dokazane korekcije.

Troubleshooting tokom upgrade prozora

Dijagnostika prati redosled simptom → obim → dokaz → neposredni uzrok → osnovni uzrok → bezbedna korekcija → validacija. Pre bilo kakvog --force, restarta više servisa ili ručnog vraćanja manifesta čuvaju se kubeadm izlaz, vreme, package history, static Pod manifesti, kubelet i runtime logovi, događaji i metrike. Tako se razlikuje prethodni kvar od posledice nadogradnje.

SimptomPrve provereTipični uzrociBezbedna naredna akcija
kubeadm upgrade plan odbija ciljTačne verzije, repozitorijum, API dostupnost, Node Ready, skew i preflight tekst.Preskočena minor verzija, pogrešan kubeadm, nezdrav node ili nedostupan registry.Ispraviti putanju ili početno stanje; ne ignorisati sve provere.
API nestabilan posle manifestacrictl ps -a, kubelet journal, static Pod log, portovi, sertifikati i LB health.Image pull, nevažeći flag/patch, cert, etcd veza ili resursni pritisak.Izolovati lokalnu instancu; zadržati zdrave backende; ponoviti tek posle potvrde uzroka.
Node ostaje NotReadyNode conditions, kubelet journal, runtime status, CNI DaemonSet i cgroup režim.Kubelet config, cgroup v1 na 1.36, runtime/CRI ili CNI inicijalizacija.Node ostaje cordoned; popraviti lokalni sloj i validirati pre uncordon-a.
Drain se ne završavaPDB, vlasnik Pod-a, finalizer, local storage, pending zamene i scheduler events.Nedovoljna dostupnost/kapacitet, singleton ili pogrešna affinity pravila.Popraviti workload/kapacitet; ne koristiti --force bez odobrenja vlasnika.
CoreDNS/kube-proxy nije nadograđenVerzije svih control-plane instanci, rollout status i kubeadm log.Preostala stara control-plane instanca; očekivano odlaganje add-on upgrade-a od v1.28.Završiti i validirati control-plane redosled, zatim proveriti add-on rollout.
# Na pogođenom nodu; read-only dijagnostika osim ako se posebno ne navede.
sudo systemctl status kubelet containerd --no-pager
sudo journalctl -u kubelet --since '-30 minutes' --no-pager
sudo crictl ps -a
sudo crictl pods
sudo crictl images

# Log konkretnog control-plane kontejnera, kada je ID potvrđen.
sudo crictl logs CONTROL_PLANE_CONTAINER_ID

# Pregled backup tragova koje je napravio kubeadm.
sudo find /etc/kubernetes/tmp -maxdepth 2 -type f \
  -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\n' | sort

crictl mora koristiti tačan CRI endpoint; pogrešan endpoint daje lažni utisak da kontejneri ne postoje. Za containerd se često koristi unix:///run/containerd/containerd.sock, a za CRI-O unix:///var/run/crio/crio.sock, ali se putanja potvrđuje iz konfiguracije konkretnog noda. Logovi se filtriraju od nekoliko minuta pre početka promene do sada, uz UTC korelaciju sa monitoringom i audit tragom.

Integrisani praktikum: kontrolisana nadogradnja HA kubeadm klastera

Cilj i kontekst. Platform tim nadograđuje laboratorijski HA klaster sa podržane minor verzije n na n+1. Cilj je izvesti pre-check, prvi control-plane, drugu control-plane instancu i jedan canary worker, a zatim doneti dokumentovanu odluku za ostatak rollout-a. Brojevi verzija ostaju promenljive kako vežba ne bi podsticala instaliranje zastarelog patch nivoa.

Topologija. Tri control-plane noda cp-1, cp-2, cp-3 koriste stacked etcd iza TCP load balancer-a; najmanje tri worker noda koriste containerd i CNI/CSI koji eksplicitno podržavaju cilj. Postoji odvojena administratorska radna stanica i out-of-band konzola za svaki server.

Preduslovi i rizik. Ovo je laboratorijska vežba sa state-changing i potencijalno destruktivnim fazama. Potrebni su root/sudo na nodovima, cluster-admin za change prozor, odobreni package/image izvori, najmanje jedna dodatna kopija laboratorije ili dokazano obnovljiv etcd snapshot i backup aplikativnih podataka. Ne izvoditi na produkciji bez formalnog change-a, vlasnika aplikacija, monitoring-a, LB procedure i testiranog recovery runbook-a.

Vežba 1: change paket i početni dokaz

Na radnoj stanici se pravi restriktivna fascikla za izlaze. Prve komande menjaju samo lokalni filesystem. U plan se unose puna izvorna i ciljna verzija, linkovana interna odobrenja, pragovi za stop, RTO/RPO, batch veličina, redosled nodova i kontakt vlasnika svake zavisnosti.

umask 077
CHANGE_DIR="${PWD}/kubeadm-upgrade-$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "${CHANGE_DIR}"

date -u +'%Y-%m-%dT%H:%M:%SZ' > "${CHANGE_DIR}/started-at-utc.txt"
kubectl config current-context > "${CHANGE_DIR}/context.txt"
kubectl version -o yaml > "${CHANGE_DIR}/version-before.yaml"
kubectl get nodes -o wide > "${CHANGE_DIR}/nodes-before.txt"
kubectl get --raw='/readyz?verbose' > "${CHANGE_DIR}/readyz-before.txt"
kubectl -n kube-system get pods -o wide > "${CHANGE_DIR}/kube-system-before.txt"
kubectl get pdb -A > "${CHANGE_DIR}/pdb-before.txt"
kubectl get events -A --sort-by='.lastTimestamp' \
  > "${CHANGE_DIR}/events-before.txt"

Očekivani rezultat. Kontekst je tačan, sve tri control-plane instance i svi planirani worker nodovi su Ready, readiness provere su uspešne, nema nerešenog kritičnog alarma i kapacitet dopušta gubitak jednog noda. Etcd snapshot/restore dokaz i backup aplikativnih podataka moraju biti vezani za change, ali se tajne i privatni ključevi ne kopiraju u ovu fasciklu.

Vežba 2: preflight na prvom control-plane nodu

Na cp-1 se potvrđuju slobodan prostor, runtime, cgroup i verzije, instalira ciljna kubeadm verzija i izvršavaju plan, diff i dry-run. Promenljive moraju sadržati vrednosti iz zvaničnog repozitorijuma za dan vežbe.

df -h / /var/lib/etcd /var/lib/containerd
findmnt -no FSTYPE /sys/fs/cgroup
stat -fc %T /sys/fs/cgroup
kubelet --version
kubeadm version -o short
sudo crictl version

TARGET_VERSION='v1.36.x'
sudo kubeadm upgrade plan "${TARGET_VERSION}"
sudo kubeadm upgrade diff "${TARGET_VERSION}"
sudo kubeadm upgrade apply "${TARGET_VERSION}" --dry-run

Kriterijum. Cilj je upravo sledeća minor ili noviji patch iste grane, preflight nema neobjašnjenu grešku, diff odgovara odobrenom planu, potrebni image-i su dostupni, a cert renewal ponašanje je svesno izabrano. Ako se pojavi upozorenje, ono se klasifikuje i potpisuje; ne koristi se globalni ignore.

Vežba 3: prvi control-plane i hold point

Posle završnog Go odobrenja pokreće se apply. Tačna package instalacija sledi distribucionu proceduru iz teorijskog dela. Izlaz se čuva pomoću tee; zbog pipefail-a shell zadržava neuspeh prve komande u pipeline-u.

set -o pipefail
sudo kubeadm upgrade apply "${TARGET_VERSION}" 2>&1 \
  | tee "${CHANGE_DIR}/cp-1-upgrade-apply.log"

kubectl get --raw='/readyz?verbose'
kubectl get nodes -o wide
kubectl -n kube-system get pods -o wide
sudo systemctl status kubelet --no-pager
sudo journalctl -u kubelet --since '-20 minutes' --no-pager

Hold point. Ne prelazi se na cp-2 dok API, etcd i sve komponente na cp-1 nisu zdrave, LB backend nije stabilan i sintetički test nije uspešan tokom definisanog perioda. Ako komanda stane zbog privremenog image pull-a, prvo se čuva dokaz i popravlja registry/DNS put; ista ciljna operacija se ponavlja tek kada je klaster stabilan. Ako se izgubi etcd quorum, vežba prelazi na DR runbook i ovde se prekida.

Vežba 4: dodatni control-plane i canary worker

cp-2 se drain-uje prema planu, nadograđuje komandom kubeadm upgrade node, zatim se nadogradi kubelet, validira i uncordon-uje. Isti tok se tek potom primenjuje na cp-3. Posle treće instance proveravaju se CoreDNS i kube-proxy, jer ih aktuelni kubeadm po pravilu nadograđuje kada su sve control-plane instance dostigle cilj.

kubectl drain cp-2 --ignore-daemonsets --timeout=20m

# Na cp-2, nakon instalacije ciljnog kubeadm paketa.
sudo kubeadm upgrade node
sudo systemctl daemon-reload
sudo systemctl restart kubelet

# Sa radne stanice.
kubectl get node cp-2 -o wide
kubectl -n kube-system get pods --field-selector='spec.nodeName=cp-2' -o wide
kubectl uncordon cp-2

# Posle završetka svih control-plane instanci.
kubectl -n kube-system rollout status deployment/coredns --timeout=5m
kubectl -n kube-system rollout status daemonset/kube-proxy --timeout=10m

Canary worker prolazi isti drain → kubeadm node → kubelet paket/restart → validacija → uncordon tok. Posle uncordon-a mora se rasporediti nov Pod na node ili potvrditi ekvivalentnim sintetičkim testom da CNI, DNS, image pull i CSI funkcionišu. Samo postojeći dugovečni Pod nije dovoljan dokaz nove sandbox putanje.

Vežba 5: simulirani kvar i odluka

Bez namernog kvarenja klastera tim obrađuje scenario: cp-2 je posle kubeadm upgrade node izbačen iz LB rotacije, lokalni API server se restartuje zbog nepostojećeg custom flag-a u odobrenom patches direktorijumu, dok cp-1, cp-3 i etcd quorum ostaju zdravi.

  1. Simptom: LB i dalje služi API preko dve instance; lokalni kube-apiserver na cp-2 je u restart loop-u.
  2. Obim i posledica: degradirana je redundansa, ali nema globalnog prekida ni gubitka quorum-a.
  3. Neposredni uzrok: nevažeći argument u generisanom static Pod manifestu.
  4. Osnovni uzrok: custom patch nije validiran protiv ciljne verzije i nije bio obuhvaćen change diff pregledom.
  5. Privremena mera: cp-2 ostaje cordoned i izvan LB-a; rollout se zaustavlja.
  6. Trajna korekcija: ispraviti verzionisani patch, ponoviti istu kubeadm node fazu prema odobrenoj proceduri i validirati lokalnu instancu.

Odluka. Ovo nije razlog za globalni etcd restore, jer klastersko stanje i quorum nisu izgubljeni. Nije dozvoljeno nastaviti na sledeći node dok se redundansa ne vrati. Ako se uzrok ne može bezbedno korigovati unutar prozora, aktivira se odobrena procedura rekreiranja ili lokalnog povratka instance; odluku donosi change/incident owner na osnovu RTO-a i dokaza.

Vežba 6: završna validacija, checksum i čišćenje

date -u +'%Y-%m-%dT%H:%M:%SZ' > "${CHANGE_DIR}/finished-at-utc.txt"
kubectl version -o yaml > "${CHANGE_DIR}/version-after.yaml"
kubectl get nodes -o wide > "${CHANGE_DIR}/nodes-after.txt"
kubectl get --raw='/readyz?verbose' > "${CHANGE_DIR}/readyz-after.txt"
kubectl -n kube-system get pods -o wide > "${CHANGE_DIR}/kube-system-after.txt"
kubectl get events -A --sort-by='.lastTimestamp' \
  > "${CHANGE_DIR}/events-after.txt"

find "${CHANGE_DIR}" -maxdepth 1 -type f ! -name SHA256SUMS \
  -printf '%f\n' | sort | while IFS= read -r file; do
    sha256sum "${CHANGE_DIR}/${file}"
  done > "${CHANGE_DIR}/SHA256SUMS"

(cd "${CHANGE_DIR}" && sha256sum --check SHA256SUMS)

Kriterijum završetka. Sve planirane komponente i nodovi imaju ciljnu ili eksplicitno dozvoljenu prelaznu verziju, svi nodovi su Ready i schedulable, control-plane i etcd su zdravi, CoreDNS/kube-proxy/CNI/CSI testovi prolaze, critical workload i SLO metrike su stabilni tokom observation period-a, a svaki incident ima zapis. Backup direktorijumi pod /etc/kubernetes/tmp ne brišu se pre formalnog zatvaranja change-a i isteka rollback/recovery perioda; zatim se uklanjaju prema politici zaštite i retention-a jer mogu sadržati osetljive klasterske podatke.

Povratak laboratorije. Ako je cilj vežbe bio trajna podržana nadogradnja, početno stanje se ne vraća samo radi čišćenja. Ako laboratorijski zahtev izričito traži staru verziju, bezbedniji povratak je obnova cele izolovane laboratorije iz prethodno testiranog snapshot-a/infrastructure-as-code procedure, a ne ad hoc downgrade živog klastera. Time se izbegava mešanje novog etcd/API stanja sa starim binarnim komponentama.

Administratorske prakse

Završna kontrolna tačka

Lekcija je savladana kada administrator ume da pretvori kompatibilnost iz lekcije 43 i PKI nalaze iz lekcije 44 u izvršan kubeadm change plan: bira podržan cilj bez preskakanja minor verzija, proverava pakete i repozitorijume, tumači upgrade plan, diff i dry-run, procenjuje PDB i kapacitet, određuje stop kriterijume i obezbeđuje testiran recovery dokaz pre prve mutacije.

Praktični kriterijum je uspešna sekvenca prvi control-plane → ostale control-plane instance → canary worker → kontrolisani worker batch, sa validacijom posle svakog noda. Administrator mora da razlikuje klasterski upgrade apply od lokalnog upgrade node, kubeadm fazu od paketnog upgrade-a kubelet-a, Ready stanje od pune funkcionalnosti mreže/storage-a i idempotentan retry od destruktivnog rollback-a. Na osnovu logova, health endpointa, etcd quorum-a, synthetic testa i SLO metrika ume da donese dokazivu odluku: nastaviti, pauzirati, stabilizovati ili aktivirati DR.

Zaključak

Kontrolisana kubeadm nadogradnja je serija malih, proverljivih promena, a ne jedna velika komanda. Njena bezbednost zavisi od zdravog početnog stanja, podržane putanje bez preskakanja minor verzija, poznatih zavisnosti, testiranog oporavka i discipline da se posle svake instance zastane i proveri stvarna funkcija sistema. Redosled prvog control-plane noda, ostalih control-plane instanci i worker nodova čuva version skew, dostupnost API-ja i etcd quorum, dok drain i PDB upravljaju planiranim prekidom workload-a.

kubeadm automatizuje složene faze, ali ne preuzima odgovornost za CNI/CSI, aplikativne podatke, kapacitet, SLO ili poslovnu odluku. Zato uspešan izlaz mora biti potvrđen health endpointima, logovima, događajima, metrikama i sintetičkim testovima. Posebno je važno razumeti rollback granicu: ponavljanje idempotentnog upgrade-a može biti pravilna korekcija prolaznog kvara, dok gubitak etcd quorum-a zahteva formalni disaster recovery, ne improvizovani downgrade.

Odgovoran administrator ne nastavlja rollout zato što je maintenance prozor kratak, već samo zato što dokaz pokazuje da je prethodna etapa stabilna. Time nadogradnja postaje upravljiv lifecycle proces sa poznatim blast radius-om, jasnim vlasništvom i obnovljivim stanjem. Sledeća lekcija produbljuje upravo tu poslednju liniju odbrane: etcd snapshot, restore, quorum i povratak kontrolne ravni kada stabilizacija više nije dovoljna.

← Prethodna lekcija Povratak na sadržaj Sledeća lekcija →