Vanilla Kubernetes
Game day je vremenski ograničena, unapred odobrena i posmatrana vežba u kojoj tim namerno uvodi kontrolisan poremećaj da bi proverio pretpostavke o otpornosti sistema, spremnost ljudi, kvalitet procedura i pouzdanost dokaza. Cilj nije demonstracija dramatičnog kvara niti takmičenje u brzini, već bezbedno učenje: da li monitoring prepoznaje problem, da li se uticaj pravilno procenjuje, da li se uzrok lokalizuje bez nasumičnih intervencija, da li oporavak vraća stvarnu funkcionalnost i da li tim može da objasni šta se dogodilo.
Laboratorija nadograđuje klaster iz prethodnih dodataka: jedan control plane čvor k8s-cp01, dva worker čvora k8s-w01 i k8s-w02, administratorsku stanicu admin01, containerd i funkcionalan CNI. Izvode se dva glavna eksperimenta. Prvi simulira neočekivanu nedostupnost jednog worker čvora. Drugi degradira aplikacioni servis tako što jedna replika postaje nespremna, ali ostaje pokrenuta. Time se jasno razdvajaju infrastrukturni kvar, Node kontrola, raspoređivanje, readiness signal, EndpointSlice stanje i korisnički rezultat.
Referentni baseline prati Kubernetes 1.35 iz Dodatka 4, ali se vežba ne vezuje za proizvoljnu oznaku latest. Pre izvođenja proveravaju se tačna patch verzija klastera, verzija klijenta, CNI i runtime-a, kao i dokumentacija koja pripada instaliranoj minor grani. Komande u ovoj lekciji koriste stabilne Kubernetes objekte i standardne kubectl postupke, ali stvarne podrazumevane pragove Node kontrolera i eviction ponašanje treba očitati iz konkretne konfiguracije control plane-a, a ne pretpostaviti.
1. Ishodi učenja i granice eksperimenta
Po završetku game day-a polaznik treba da ume da izmeri početno stanje, definiše hipotezu i blast radius, razlikuje dobrovoljnu od nedobrovoljne disrupcije, prepozna posledice gubitka čvora, pronađe promenu u Node Lease-u i uslovima čvora, prati ponovno raspoređivanje podova, protumači readiness i EndpointSlice stanje, vrati sistem u poznato dobro stanje i izradi retrospektivu bez okrivljavanja pojedinca.
| Granica | Dozvoljeno u vežbi | Nije dozvoljeno |
|---|---|---|
| Okruženje | Izolovan laboratorijski klaster bez produkcionih korisnika i podataka | Izvođenje na produkciji bez zasebnog dizajna, odobrenja i change procesa |
| Čvor | Zaustavljanje samo k8s-w02 ili njegove VM nakon potvrđenog baseline-a | Gašenje k8s-cp01, oba worker-a ili ESXi hosta u ovoj vežbi |
| Aplikacija | Promena ConfigMap-a kontrolisane aplikacije game-day/web | Izmena CNI-ja, kube-proxy pravila, sertifikata ili stvarnih tajni |
| Podaci | Stateless demo workload i privremeni dijagnostički podovi | Test gubitka persistent volume-a bez zasebnog backup/restore scenarija |
| Intervencija | Jedna promena u jednom trenutku, sa vremenom i vlasnikom | Nasumičan restart više komponenti, brisanje podova bez dokaza ili korišćenje --force radi ubrzanja |
Stop kriterijumi: facilitator odmah prekida eksperiment ako Kubernetes API postane nedostupan, ako drugi worker pređe u NotReady, ako se pojavi gubitak trajnih podataka, ako se više ne može pristupiti VM konzoli, ako opterećenje napusti laboratorijski opseg ili ako tim ne može pouzdano da utvrdi poslednju izvršenu promenu. Prekid nije neuspeh vežbe; to je dokaz da je bezbednosna granica funkcionisala.
2. Referentna topologija i promenljive
| Uloga | Hostname | Node IP | Resursi | Operativna uloga u vežbi |
|---|---|---|---|---|
| Control plane | k8s-cp01 | 192.168.50.11 | 4 vCPU, 8 GB RAM, 80 GB | API, scheduler, controller manager i lokalni etcd; ne uvodi se kvar |
| Worker 1 | k8s-w01 | 192.168.50.21 | 4 vCPU, 8 GB RAM, 100 GB | Preživeli čvor i cilj ponovnog raspoređivanja |
| Worker 2 | k8s-w02 | 192.168.50.22 | 4 vCPU, 8 GB RAM, 100 GB | Čvor na kome se izaziva kontrolisani prekid |
| Administratorska stanica | admin01 | 192.168.50.10 | Linux, kubectl, curl, SSH | Komandni, dokazni i vremenski zapis |
| Node mreža | VMware port group | 192.168.50.0/24 | MTU prema baseline-u | SSH, API i Node saobraćaj |
| Pod / Service mreža | CNI / Kubernetes | 10.244.0.0/16 / 10.96.0.0/12 | Bez preklapanja | Pod komunikacija i ClusterIP |
| Promenljiva | Referentna vrednost | Pravilo |
|---|---|---|
TARGET_NODE | k8s-w02 | Jedini čvor na kome se uvodi kvar |
SURVIVING_NODE | k8s-w01 | Mora ostati zdrav i imati dovoljan allocatable kapacitet |
LAB_NAMESPACE | game-day | Svi aplikacioni resursi vežbe nalaze se ovde |
APP_NAME | web | Deployment, Service i PDB koriste iste labels |
EVIDENCE_DIR | game-day-evidence-YYYYMMDD-HHMMSS | Ne sadrži kubeconfig, tokene, Secrets ni privatne ključeve |
OBSERVATION_WINDOW | 15 minuta po scenariju | Nije timeout produkcionog incidenta; facilitator ga prilagođava laboratoriji |
Ako se shell promenljive koriste radi pogodnosti, važe samo u tekućoj sesiji. Na admin01, običnim korisnikom sa ispravnim kubeconfig-om, sledeće komande samo postavljaju lokalne vrednosti i odmah ih proveravaju. Ne koriste se za destruktivne petlje.
export TARGET_NODE='k8s-w02'
export LAB_NAMESPACE='game-day'
printf 'TARGET_NODE=%s\nLAB_NAMESPACE=%s\n' "$TARGET_NODE" "$LAB_NAMESPACE"
test -n "$TARGET_NODE" && test -n "$LAB_NAMESPACE"
3. Mapa game day laboratorije
| Faza | Mesto | Promena | Dokaz uspeha |
|---|---|---|---|
| 1. Odobrenje i uloge | Tim | Definišu se obim, vreme, stop kriterijumi i komunikacija | Popunjen game day brief |
| 2. Baseline | admin01 i sva tri čvora | Nema promene; prikuplja se početno stanje | API, čvorovi, sistemski podovi, DNS i runtime zdravi |
| 3. Workload | admin01 | Kreiraju se namespace, Deployment, Service i PDB | Tri spremne replike, endpoint-i i HTTP odgovor |
| 4. Kvar čvora | k8s-w02 ili vCenter | Zaustavlja se kubelet ili VM | Node heartbeat zastaje; uticaj je ograničen |
| 5. Dijagnostika | admin01, k8s-w02, vCenter | Read-only korelacija slojeva | Potvrđena hipoteza i vremenska linija |
| 6. Oporavak čvora | k8s-w02 i admin01 | Vraća se VM/kubelet i scheduling | Ready, sve replike spremne, nema kritičnih događaja |
| 7. Degradacija servisa | admin01 | Jedna replika postaje NotReady | EndpointSlice uklanja nespreman backend; Service ostaje funkcionalan |
| 8. Oporavak aplikacije | admin01 | Vraća se ispravna konfiguracija | Tri endpoint-a i stabilan funkcionalni test |
| 9. Retrospektiva | Tim | Nema promene klastera | Činjenice, nalazi, vlasnici i rokovi akcija |
4. Uloge, komunikacija i game day brief
- Facilitator vodi faze, potvrđuje preduslove, odobrava fault injection i ima pravo da prekine vežbu.
- Operator izvršava unapred dogovorene state-changing komande; ne improvizuje dodatne kvarove.
- Incident commander održava zajedničku sliku uticaja, prioriteta, odluka i eskalacija.
- Observer/scribe beleži UTC vreme, komandu, izvršioca, rezultat, hipotezu i odluku, ali ne vodi paralelnu intervenciju.
- Service owner potvrđuje očekivano ponašanje aplikacije i kriterijume poslovnog oporavka.
| Polje brief-a | Primer |
|---|---|
| Hipoteza 1 | Gubitak jednog worker-a ne prekida dostupnost troreplikatnog stateless servisa duže od dogovorenog laboratorijskog prozora |
| Hipoteza 2 | Readiness kvar uklanja neispravnu repliku iz Service endpoint-a bez nepotrebnog restartovanja kontejnera |
| Blast radius | Samo namespace game-day i worker k8s-w02 |
| Početak/kraj | UTC timestamp i maksimalno trajanje |
| Rollback | Start kubelet/VM, uncordon po potrebi, povratak ConfigMap-a i rollout status |
| Komunikacioni kanal | Jedan dogovoreni kanal i jedna vremenska linija |
| Stop autoritet | Facilitator i bilo koji član koji uoči izlazak iz blast radius-a |
5. Faza baseline-a – dokaz poznatog dobrog stanja
Mesto: admin01; običan korisnik sa odobrenim kubeconfig-om. Vrsta: read-only. Cilj je da se pre fault injection-a dokaže zdravlje upravljačke ravni, čvorova i mreže. Ako baseline nije uspešan, game day se ne pokreće: postojeći kvar ne sme postati deo eksperimenta bez jasne oznake.
kubectl version
kubectl cluster-info
kubectl get nodes -o wide
kubectl get --raw='/readyz?verbose'
kubectl get pods -n kube-system -o wide
kubectl get events -A --sort-by='.metadata.creationTimestamp'
Očekuje se odziv API-ja, uspešan readyz, sva tri Node objekta u stanju Ready i sistemski podovi bez nerešenih CrashLoopBackOff, ImagePullBackOff ili dugotrajnog Pending stanja. Upozorenje u Events nije automatski aktivna greška: proveravaju se vreme, broj ponavljanja, pogođeni objekat i da li se događaj i dalje ponavlja.
Mesto: svaki Kubernetes čvor pojedinačno; korisnik labadmin sa sudo. Sledeće provere su read-only i potvrđuju servise, vreme, disk i mrežni identitet.
sudo systemctl is-active kubelet containerd
timedatectl show -p NTPSynchronized
df -h /
ip -br address
ip route
sudo journalctl -u kubelet --since '-15 min' --no-pager | tail -n 80
Preživeli worker mora imati dovoljno CPU-a, memorije i dozvoljenih scheduling uslova za zamenske podove. Sa admin01 proveriti allocatable resurse, zahteve i postojeće taint vrednosti:
kubectl describe node k8s-w01
kubectl describe node k8s-w02
kubectl get pods -A -o custom-columns='NS:.metadata.namespace,POD:.metadata.name,NODE:.spec.nodeName,CPU:.spec.containers[*].resources.requests.cpu,MEM:.spec.containers[*].resources.requests.memory'
Kontrolna tačka: API je spreman, CoreDNS i CNI su zdravi, oba worker-a su Ready, nema pressure uslova, runtime i kubelet rade, vreme je sinhronizovano, disk nije pri kritičnom pragu i k8s-w01 ima kapacitet za tri demo replike. U suprotnom zabeležiti nalaz i odložiti vežbu.
6. Priprema dokaznog paketa
Mesto: admin01; običan korisnik. Kreiranje lokalnog direktorijuma menja samo administratorsku stanicu. U dokazni paket ne smeju ući ~/.kube/config, Secret sadržaj, bootstrap tokeni, privatni ključevi ni nefiltrirani environment podaci.
EVIDENCE_DIR="game-day-evidence-$(date -u +%Y%m%d-%H%M%S)"
test -n "$EVIDENCE_DIR" || exit 1
mkdir -m 0700 -- "$EVIDENCE_DIR"
printf '%s\n' "$EVIDENCE_DIR"
date -u +%FT%TZ | tee "$EVIDENCE_DIR/00-start-utc.txt"
kubectl get nodes -o wide > "$EVIDENCE_DIR/01-nodes-before.txt"
kubectl get pods -A -o wide > "$EVIDENCE_DIR/02-pods-before.txt"
kubectl get events -A --sort-by='.metadata.creationTimestamp' > "$EVIDENCE_DIR/03-events-before.txt"
kubectl version -o yaml > "$EVIDENCE_DIR/04-kubectl-version.yaml"
Datoteke predstavljaju snimak, ne kompletnu observability platformu. Za realnu organizaciju koriste se centralni monitoring, logovi, audit i vremenski usklađeni dashboard-i sa pravilima retention-a. Game day zapis mora navesti vremensku zonu; UTC olakšava korelaciju između Kubernetes, systemd, vCenter i aplikacionih zapisa.
7. Postavljanje otpornog probnog workload-a
Mesto: admin01; korisnik sa pravom kreiranja resursa u laboratorijskom namespace-u. Vrsta: state-changing, ali ograničena na game-day. Manifest kreira tri replike, anti-affinity preferencu, requests, readiness/liveness probe, Service i PDB. Preferirana anti-affinity nije garancija raspodele; zato se stvarni položaj podova proverava pre kvara.
apiVersion: v1
kind: Namespace
metadata:
name: game-day
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: game-day
spec:
replicas: 3
strategy:
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app: web
containers:
- name: web
image: registry.k8s.io/e2e-test-images/agnhost:2.53
args: ["netexec", "--http-port=8080"]
ports:
- name: http
containerPort: 8080
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
cpu: 200m
memory: 128Mi
readinessProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 3
failureThreshold: 2
livenessProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 10
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: game-day
spec:
selector:
app: web
ports:
- name: http
port: 80
targetPort: http
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web
namespace: game-day
spec:
minAvailable: 2
unhealthyPodEvictionPolicy: AlwaysAllow
selector:
matchLabels:
app: web
Pre primene manifest sačuvati kao game-day.yaml, pregledati, verzionisati i izvršiti server-side proveru. Referencu slike i digest, kada organizacija zahteva reproducibilnost, potvrditi u odobrenom registru; ako instalirana Kubernetes grana koristi drugačiju verziju test slike, promena mora biti dokumentovana.
kubectl apply --server-side --dry-run=server -f game-day.yaml
kubectl apply -f game-day.yaml
kubectl rollout status deployment/web -n game-day --timeout=180s
kubectl get pods -n game-day -o wide
kubectl get pdb -n game-day
kubectl get endpointslice -n game-day -l kubernetes.io/service-name=web -o wide
PDB štiti od dobrovoljnih evikcija pokrenutih Eviction API-jem, kao što je standardni kubectl drain. Ne može sprečiti nestanak VM, kvar diska, mrežnu particiju ili drugu nedobrovoljnu disrupciju; takav kvar se uračunava u dostupni budžet. PDB takođe nije mehanizam koji ograničava Deployment rolling update. Polje unhealthyPodEvictionPolicy: AlwaysAllow sprečava da trajno nespreman pod nepotrebno blokira administrativni drain, ali ne zamenjuje analizu uzroka nespremnosti.
Funkcionalni test iz privremenog Pod-a dokazuje DNS, Service i aplikacioni odgovor. Komanda menja stanje samo kreiranjem kratkotrajnog Pod-a koji se posle završetka uklanja.
kubectl run service-check -n game-day --rm -i --restart=Never \
--image=busybox:1.36.1 \
-- /bin/sh -c 'for i in 1 2 3 4 5; do wget -qO- http://web/hostname; echo; done'
Kontrolna tačka: Deployment ima 3/3 dostupne replike; bar jedna replika je na k8s-w02; EndpointSlice sadrži tri spremne adrese; PDB prikazuje dozvoljenu disrupciju u skladu sa trenutnim zdravljem; pet zahteva uspeva. Ako scheduler smesti sve replike na jedan worker zbog kapaciteta ili ograničenja, ne nastavljati dok se topologija i resursi ne isprave.
8. Kontrolni eksperiment – cordon, drain i uncordon
Pre neočekivanog kvara korisno je dokazati kako izgleda planirana disrupcija. cordon sprečava novo raspoređivanje, ali ne uklanja postojeće podove. drain koristi bezbedne evikcije, poštuje PDB i grace period; DaemonSet podovi ostaju i zato je potreban --ignore-daemonsets. Mesto: admin01. Vrsta: state-changing. Ne koristi se --disable-eviction, jer bi zaobišao PDB, niti --force bez prethodne analize unmanaged podova.
kubectl cordon k8s-w02
kubectl get node k8s-w02
kubectl drain k8s-w02 --ignore-daemonsets --timeout=180s
kubectl get pods -n game-day -o wide
kubectl get pdb -n game-day
kubectl uncordon k8s-w02
kubectl get node k8s-w02
Ako drain blokira PDB, ne povećavati silom dozvoljeni prekid. Proveriti broj zdravih replika, kapacitet drugog čvora, readiness probe, tačan selector PDB-a i unmanaged/emptyDir podove. Opcija --delete-emptydir-data prihvata gubitak lokalnih ephemeral podataka i koristi se samo kada je taj rizik eksplicitno odobren. Uspešan drain znači da su odgovarajući workload podovi bezbedno eviktovani; ne znači da je aplikacija funkcionalno proverena.
9. Scenario A – neočekivani kvar worker čvora
Scenario ima dve varijante. Varijanta A1, za početnu vežbu, zaustavlja samo kubelet i ostavlja SSH dostupan; lakša je za oporavak i omogućava lokalne dokaze. Varijanta A2 gasi VM i realističnije prikazuje potpuni gubitak čvora, ali zahteva potvrđen pristup vCenter-u ili hipervizorskoj konzoli. Izvodi se samo jedna varijanta po prolazu.
9.1. Poslednja provera pre fault injection-a
Mesto: admin01; read-only. Scribe beleži vreme i položaj podova. Facilitator potvrđuje da je k8s-w02 schedulable posle kontrolnog drain-a i da je najmanje jedna replika na njemu.
date -u +%FT%TZ
kubectl get node k8s-w02
kubectl get pods -n game-day -o wide
kubectl get lease -n kube-node-lease k8s-w02 -o yaml
kubectl get endpointslice -n game-day -l kubernetes.io/service-name=web -o yaml
9.2. Varijanta A1 – zaustavljanje kubelet-a
Mesto: samo k8s-w02; labadmin sa sudo. Vrsta: state-changing i reverzibilna. Containerd može nastaviti da drži postojeće kontejnere aktivnim, ali čvor prestaje da šalje kubelet heartbeat i ne izvršava nove PodSpec odluke.
date -u +%FT%TZ
sudo systemctl stop kubelet
sudo systemctl is-active kubelet
Očekivani izlaz poslednje komande je inactive. Ako se zaustavi containerd ili izgubi SSH, scenario više nije A1; primenjuje se stop kriterijum i prelazi na konzolu, bez dodatnog improvizovanog kvara.
9.3. Varijanta A2 – gašenje VM
Mesto: vCenter ili drugi odobreni VMware alat; ovlašćeni operator. Najpre se potvrđuje tačan VM identitet k8s-w02. Guest shutdown je uredno gašenje, dok power-off više liči na nagli kvar, ali nosi veći rizik po lokalni filesystem. Za ovu vežbu prednost ima uredan shutdown, osim kada je zasebno odobreno testiranje naglog prekida. Ne vraća se stari VM snapshot kao način oporavka Node-a.
10. Posmatranje, trijaža i potvrda uzroka
Mesto: admin01; read-only. Ne očekuje se da Node odmah postane NotReady. Kubelet heartbeat i Lease prestaju, zatim Node kontroler nakon svojih pragova menja uslov i dodaje odgovarajuće taint vrednosti. Pod evikcije takođe nisu trenutne. Podrazumevane vrednosti postoje u upstream dokumentaciji, ali rezultat se meri u ovom klasteru i povezuje sa stvarnom konfiguracijom controller manager-a.
kubectl get nodes -w
U drugom terminalu pratiti podove i endpoint-e:
kubectl get pods -n game-day -o wide -w
U trećem terminalu, bez beskonačnog čuvanja izlaza, periodično prikupiti sledeće dokaze:
date -u +%FT%TZ
kubectl get node k8s-w02 -o yaml
kubectl get lease -n kube-node-lease k8s-w02 -o yaml
kubectl describe node k8s-w02
kubectl get pods -n game-day -o wide
kubectl get endpointslice -n game-day -l kubernetes.io/service-name=web -o yaml
kubectl get events -n game-day --sort-by='.metadata.creationTimestamp'
Dokazi se tumače po slojevima. Zastareo renewTime Lease-a potvrđuje prestanak heartbeat-a. Ready: Unknown ili False i taint node.kubernetes.io/unreachable ili node.kubernetes.io/not-ready pokazuju reakciju control plane-a. Pod koji je još prikazan kao Running na nedostupnom Node-u nije dokaz da stvarno uslužuje zahteve: API stanje može biti zastarelo. Service dostupnost se dokazuje zahtevom, EndpointSlice stanjem i, kada postoji, metrikama uspešnosti i latencije.
10.1. Funkcionalni test tokom kvara
kubectl run outage-check -n game-day --rm -i --restart=Never \
--image=busybox:1.36.1 \
-- /bin/sh -c 'n=0; while [ "$n" -lt 20 ]; do date -u +%FT%TZ; wget -T 2 -qO- http://web/hostname || echo REQUEST_FAILED; n=$((n+1)); sleep 1; done'
Rezultat se beleži kao broj uspešnih i neuspešnih zahteva i najveća primećena pauza, ne samo kao „radi/ne radi”. Troreplikatni stateless workload na dva worker-a može ostati dostupan, ali to nije garantovano ako su sve replike bile na pogođenom Node-u, ako preživeli čvor nema kapacitet, ako topology/affinity pravila onemogućavaju raspoređivanje ili ako sama aplikacija zavisi od node-local stanja.
10.2. Lokalni dokazi za A1
Mesto: k8s-w02; labadmin sa sudo; read-only. Birati vremenski prozor koji počinje nekoliko minuta pre fault injection-a.
sudo systemctl status kubelet --no-pager
sudo journalctl -u kubelet --since '-20 min' --no-pager
sudo systemctl status containerd --no-pager
sudo crictl ps -a
ip -br address
ip route
df -h / /var/lib/containerd /var/lib/kubelet
Za A2 se lokalni podaci možda ne mogu prikupiti dok se VM ne vrati. Tada vCenter stanje, VM događaji, konzola, datastore i mrežni podaci postaju primarni infrastrukturni dokazi. Nedostupan SSH sam po sebi ne dokazuje kvar kubelet-a; uzrok može biti VM power state, guest mreža, firewall, DNS ili host infrastruktura.
11. Oporavak worker čvora
Oporavak počinje tek kada su zabeleženi simptom, obim, poslednja promena, hipoteza i dokazi koji potvrđuju uzrok. Za A1, na k8s-w02 se vraća samo kubelet. Za A2 se VM uključuje i čeka se operativni sistem; ne izvodi se kubeadm reset niti ponovni kubeadm join nad postojećim članom bez dokaza da je identitet čvora nepovratno izgubljen.
A1 – mesto: k8s-w02; sudo; state-changing.
sudo systemctl start kubelet
sudo systemctl is-active kubelet
sudo journalctl -u kubelet --since '-5 min' --no-pager
Ako je čvor ostao cordon-ovan iz ranije faze, tek nakon stabilnog Ready stanja i provere lokalnih servisa vratiti scheduling sa admin01:
kubectl get node k8s-w02
kubectl uncordon k8s-w02
kubectl get nodes
kubectl get pods -n game-day -o wide
kubectl rollout status deployment/web -n game-day --timeout=180s
kubectl get endpointslice -n game-day -l kubernetes.io/service-name=web -o wide
Vraćanje Node-a u Ready ne vraća automatski prethodni raspored podova i ne treba ručno „balansirati” klaster brisanjem zdravih podova bez potrebe. Scheduler reaguje na nove zahteve; postojeći zdravi podovi ostaju gde jesu. Ako je cilj ponovna raspodela, koristi se kontrolisan rollout ili alat/politika predviđena za to, uz proveru dostupnosti.
Kriterijum oporavka: Node je stabilno Ready; Lease se obnavlja; kubelet i containerd su aktivni; Deployment ima 3/3 dostupne replike; EndpointSlice ima očekivane spremne adrese; CoreDNS i CNI pod na vraćenom čvoru su zdravi; funkcionalni test nema greške; nema novih nerešenih warning događaja. Tek tada se scenario zatvara.
12. Scenario B – kontrolisana degradacija servisa
Cilj drugog scenarija je da se pokaže razlika između procesa koji radi i instance koja je spremna da prima saobraćaj. Readiness neuspeh uklanja Pod iz Service backend-a, ali kubelet zbog toga ne restartuje kontejner. Liveness neuspeh može izazvati restart i zato se ne zloupotrebljava za zavisnosti ili prolazno opterećenje: pogrešna liveness provera može proizvesti kaskadni kvar.
Pošto referentna slika daje isti /healthz odgovor za sve replike, najbezbednija vežba degradacije koristi privremenu promenu readiness putanje u novom Deployment rollout-u. To utiče na sve nove Podove i zato se rollout strategija i PDB posmatraju. Blast radius ostaje namespace game-day. Pre promene izvesti aktivni Deployment kao dokaz, ali ga ne koristiti kao jedini izvor istine umesto verzionisanog manifesta.
kubectl get deployment web -n game-day -o yaml > "$EVIDENCE_DIR/20-web-before-degradation.yaml"
kubectl patch deployment web -n game-day --type='json' \
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/readinessProbe/httpGet/path","value":"/not-ready"}]'
kubectl rollout status deployment/web -n game-day --timeout=60s || true
kubectl get pods -n game-day -o wide
kubectl get endpointslice -n game-day -l kubernetes.io/service-name=web -o yaml
kubectl describe deployment web -n game-day
kubectl get events -n game-day --sort-by='.metadata.creationTimestamp'
|| true se ovde koristi samo da očekivani timeout ne prekine laboratorijski niz provera; ne znači da se greška ignoriše. Očekuje se da novi Pod ostane Running, ali 0/1 Ready, dok stari spremni podovi ostaju zbog rolling update pravila. Deployment ne završava rollout, a Service treba da zadrži samo spremne endpoint-e. Ako nema nijednog endpoint-a ili korisnički test potpuno otkaže, aktivira se stop kriterijum i odmah se prelazi na rollback.
kubectl run degraded-check -n game-day --rm -i --restart=Never \
--image=busybox:1.36.1 \
-- /bin/sh -c 'for i in 1 2 3 4 5 6 7 8 9 10; do wget -T 2 -qO- http://web/hostname || echo REQUEST_FAILED; done'
12.1. Dijagnostički tok
- Simptom: rollout ne završava, novi Pod je
Runningali nije spreman. - Obim: samo novi ReplicaSet u namespace-u
game-day; Node i sistemski podovi ostaju zdravi. - Dokaz:
kubectl describe podprikazuje readiness probe failure; EndpointSlice ne označava taj Pod kao spreman backend. - Neposredni uzrok: readiness HTTP putanja
/not-readyvraća neuspeh. - Osnovni uzrok: kontrolisana promena Pod template-a bez odgovarajućeg health endpoint-a.
- Posledica: smanjen broj kapaciteta i zaglavljen rollout, ali Service nastavlja da koristi spremne replike.
- Korekcija: povratak verzionisanog manifesta ili
rollout undona prethodnu reviziju.
Za konkretan nespreman Pod, sa admin01 izvršiti read-only proveru:
kubectl get pods -n game-day
kubectl describe pod -n game-day <NAZIV_NESPREMNOG_PODA>
kubectl logs -n game-day <NAZIV_NESPREMNOG_PODA> --since=10m
kubectl get rs -n game-day
kubectl rollout history deployment/web -n game-day
Zamenska vrednost se najpre kopira iz kubectl get pods; ne izvršava se doslovno. U HTML prikazu je znak < escapovan. Nije opravdano restartovati kubelet, CNI ili ceo čvor, jer su dokazi lokalizovali problem u Pod template-u.
13. Rollback degradacije i puna validacija
Mesto: admin01; state-changing. Preferirani rollback je ponovna primena ispravnog, pregledanog i verzionisanog game-day.yaml. rollout undo je dozvoljena laboratorijska alternativa kada je prethodna revizija jasno identifikovana.
kubectl apply -f game-day.yaml
kubectl rollout status deployment/web -n game-day --timeout=180s
kubectl get deployment,replicaset,pods,service,pdb -n game-day -o wide
kubectl get endpointslice -n game-day -l kubernetes.io/service-name=web -o yaml
kubectl get events -n game-day --sort-by='.metadata.creationTimestamp'
Zatim ponoviti funkcionalni test i sačuvati završne dokaze:
kubectl run recovery-check -n game-day --rm -i --restart=Never \
--image=busybox:1.36.1 \
-- /bin/sh -c 'for i in 1 2 3 4 5 6 7 8 9 10; do wget -T 2 -qO- http://web/hostname || exit 1; done'
date -u +%FT%TZ | tee "$EVIDENCE_DIR/90-end-utc.txt"
kubectl get nodes -o wide > "$EVIDENCE_DIR/91-nodes-after.txt"
kubectl get pods -A -o wide > "$EVIDENCE_DIR/92-pods-after.txt"
kubectl get events -A --sort-by='.metadata.creationTimestamp' > "$EVIDENCE_DIR/93-events-after.txt"
kubectl get all,pdb,endpointslice -n game-day -o yaml > "$EVIDENCE_DIR/94-game-day-after.yaml"
Komanda kubectl get all ne obuhvata sve vrste resursa; zato su PDB i EndpointSlice izričito navedeni. Dokazni YAML može sadržati interne IP adrese i metapodatke, pa se pre deljenja klasifikuje i sanitizuje. Hash paketa dokaza omogućava proveru naknadne izmene, ali ne dokazuje istinitost prvobitno prikupljenih podataka.
tar -czf "${EVIDENCE_DIR}.tar.gz" -- "$EVIDENCE_DIR"
sha256sum "${EVIDENCE_DIR}.tar.gz" > "${EVIDENCE_DIR}.tar.gz.sha256"
14. Matrica simptoma i dijagnostičkih grana
| Simptom | Prvi dokaz | Verovatna grana | Ne raditi automatski |
|---|---|---|---|
Node je NotReady ili Unknown | Node conditions, Lease, kubelet journal, VM power state | Kubelet, OS, mreža, runtime ili hipervizor | kubeadm reset i ponovni join |
Pod je Pending | Pod Events i scheduler poruke | Nedovoljan kapacitet, affinity, taint, PVC | Restart containerd-a pre odluke schedulera |
Pod je Running, 0/1 Ready | Probe Events, opis Pod-a, endpoint condition | Readiness konfiguracija ili aplikaciona zavisnost | Brisanje svih podova ili Node restart |
| Service nema endpoint-e | Selector, labels, EndpointSlice, readiness | Pogrešna oznaka ili sve replike nespremne | Nasumična izmena CNI/firewall pravila |
| Endpoint-i postoje, HTTP ne radi | Direktan Pod test, port/targetPort, NetworkPolicy, proxy sloj | Aplikacija, Service mapiranje ili transport | Zaključak da je DNS uzrok bez DNS testa |
| API je nedostupan | cluster-info, readyz, control plane VM i static Pod logovi | Control plane/etcd/mreža; stop kriterijum | Nastavak fault injection-a |
15. RTO, RPO, SLI i dokaz oporavka
Game day ne treba proglasiti uspešnim samo zato što su podovi ponovo zeleni. Unapred se definiše šta se meri. Za stateless demo servis RPO je praktično nula jer nema poslovnih podataka, ali to ne govori ništa o stvarnom StatefulSet-u ili bazi. RTO se meri od dogovorenog početka korisničkog uticaja do potvrđenog povratka funkcionalnog SLI-ja, ne do trenutka kada je operator izvršio poslednju komandu.
| Mera | Početak | Kraj | Dokaz |
|---|---|---|---|
| Vreme detekcije | Fault injection | Prvi tačan signal/alert | UTC vremenska linija i monitoring događaj |
| Vreme trijaže | Prvi signal | Potvrđena komponenta i blast radius | Hipoteza potkrepljena Lease/Node/probe dokazom |
| Vreme oporavka | Početak uticaja | Stabilan funkcionalni test | Niz uspešnih zahteva i zdravi backend-i |
| Greške zahteva | Tokom scenarija | Kraj observation prozora | Broj REQUEST_FAILED i ukupnih zahteva |
| Kapacitet | Pre kvara | Tokom degradacije | Broj Ready replika i EndpointSlice adresa |
| RPO | Poslednji pouzdan podatak | Potvrđeno vraćeno stanje | Za stateful sistem: aplikaciona konzistentnost i probni restore |
16. Retrospektiva bez okrivljavanja
Retrospektiva se održava dok su činjenice sveže, ali tek nakon stabilizacije. Usmerena je na sistem, interfejse, procedure i pretpostavke, a ne na pronalaženje krivca. Ljudska odluka se analizira u kontekstu informacija, ovlašćenja, pritiska i alata koji su bili dostupni u tom trenutku. Svaki zaključak mora razlikovati činjenicu, pretpostavku i naknadnu interpretaciju.
| Celina | Pitanja | Obavezni izlaz |
|---|---|---|
| Očekivanje | Šta smo mislili da će se dogoditi i zašto? | Početna hipoteza i izvor pretpostavke |
| Činjenice | Šta se zaista dogodilo, kojim redosledom? | UTC timeline sa dokazima |
| Detekcija | Koji signal je prvi bio koristan, a koji bučan ili odsutan? | Promena alerta/dashboard-a ili potvrda da nije potrebna |
| Odgovor | Koja odluka je pomogla, šta je usporilo trijažu? | Izmena runbook-a, pristupa ili uloga |
| Otpornost | Da li su PDB, replike, requests i probes radili kako je zamišljeno? | Tehnička akcija sa vlasnikom i kriterijumom prihvatanja |
| Dokazi | Šta nismo mogli da rekonstruišemo? | Logging/audit/retention poboljšanje |
| Rizik | Da li se blast radius zadržao i da li su stop kriterijumi bili dovoljni? | Ažurirana sigurnosna granica naredne vežbe |
Akcija bez vlasnika, roka, prioriteta i proverljivog kriterijuma nije zatvorena akcija. Primer dobre formulacije je: „Platform tim do 15. avgusta dodaje alert za zastareo Node Lease; prihvatanje: u ponovljenoj A1 vežbi alert nastaje u odobrenom pragu i sadrži naziv čvora i link ka runbook-u.” Formulacija „poboljšati monitoring” nije merljiva.
17. Očuvanje ili uklanjanje laboratorijskih resursa
Mogućnost A – očuvanje klastera i workload-a
Klaster se može sačuvati kao poznato dobro okruženje za ponavljanje game day-a. Zadržavaju se verzionisani manifest, brief, sanitizovani dokazni paket, retrospektiva i otvorene akcije. Proverava se da nijedan Node nije ostao cordon-ovan, da nema privremenih taint vrednosti, zaglavljenog rollout-a ili dijagnostičkog Pod-a i da svi resursi imaju vlasnika.
kubectl get nodes
kubectl get deployment,pods,service,pdb -n game-day -o wide
kubectl rollout status deployment/web -n game-day --timeout=180s
kubectl get events -n game-day --sort-by='.metadata.creationTimestamp'
Mogućnost B – uklanjanje samo resursa vežbe
State-changing postupak. Sa admin01 se briše samo namespace game-day. Ovo uklanja namespaced workload, Service, PDB i povezane Podove; ne resetuje klaster i ne uklanja dokazni paket sa administratorske stanice.
kubectl delete namespace game-day
kubectl get namespace game-day
Ako namespace ostane u stanju Terminating, finalizer se ne uklanja naslepo. Identifikuje se resurs ili API servis koji sprečava završetak. Potpuni kubeadm reset nije deo ovog game day-a: kvar čvora i aplikaciona degradacija moraju se oporaviti bez rušenja poznato dobrog klastera.
Administratorske prakse
- Vežba ima vlasnika i change zapis. Obim, hipoteza, blast radius, vreme, stop kriterijumi, komunikacioni kanal i rollback odobravaju se pre fault injection-a.
- Baseline prethodi promeni. API, Node, kube-system, DNS, Service putanja, runtime, vreme, disk i kapacitet proveravaju se dokazima; postojeći kvar odlaže vežbu.
- Jedna greška u jednom trenutku. Svaka state-changing radnja ima UTC vreme, izvršioca, očekivani efekat, validaciju i povratnu komandu.
- PDB se ne tumači kao apsolutna dostupnost. On reguliše dobrovoljne evikcije, ne sprečava hardverski kvar, mrežnu particiju niti loš rolling update.
- Readiness i liveness imaju različite namene. Readiness upravlja prijemom saobraćaja, a liveness restartom. Zavisnost koja je prolazno nedostupna obično nije opravdanje za agresivan liveness restart.
- Dokazi se čuvaju pre korekcije. Node conditions, Lease, Events, EndpointSlice, rollout istorija, kubelet/runtime journal i infrastrukturni događaji korelišu se po vremenu.
- Tajne se isključuju iz paketa. Kubeconfig, Secret sadržaj, tokeni i privatni ključevi ne ulaze u običan tar arhiv niti u Git.
- Oporavak je funkcionalan, ne kozmetički.
ReadyiRunningnisu dovoljni bez DNS, Service, endpoint i korisničkog testa. - Retrospektiva proizvodi merljive promene. Svaka akcija ima vlasnika, rok, prioritet i dokaz prihvatanja u narednoj vežbi.
Završna kontrolna tačka
- Čitalac može da objasni topologiju, blast radius i zašto se u ovoj vežbi ne gasi single control plane.
- Može komandama da dokaže početno zdravlje API-ja, čvorova, kube-system podova, kubelet-a, containerd-a, DNS-a i Service putanje.
- Može da postavi tri replike, requests, probe, Service i
policy/v1PDB i da objasni svaki izbor. - Može da razlikuje cordon, drain, eviction, gašenje Node-a i ponovno uključivanje scheduling-a.
- Može da objasni zašto PDB poštuje dobrovoljnu disrupciju, ali ne sprečava nestanak VM.
- Može da prati Lease, Node condition, taint, Events, Pod raspored i EndpointSlice tokom kvara.
- Može da lokalizuje uzrok na Kubernetes, Linux/runtime ili VMware sloju bez nasumičnog restartovanja.
- Može da vrati kubelet ili VM bez nepotrebnog
kubeadm reset/joinpostupka. - Može da dokaže oporavak Node-a servisnim, sistemskim i funkcionalnim dokazima.
- Može da izazove i protumači readiness degradaciju, uključujući uklanjanje nespremnog backend-a iz EndpointSlice-a.
- Može da izvrši kontrolisan rollback iz verzionisanog manifesta i potvrdi stabilan rollout.
- Može da izmeri detekciju, trijažu, funkcionalni RTO i broj neuspešnih zahteva, uz pravilno ograničenje RPO zaključka.
- Može da napravi sanitizovan dokazni paket, hash i UTC vremensku liniju bez tajni.
- Može da vodi retrospektivu bez okrivljavanja i napiše akciju sa vlasnikom, rokom i kriterijumom prihvatanja.
- Može da očuva poznato dobro stanje ili ukloni samo namespace vežbe bez rušenja klastera.
Zaključak
Otpornost Kubernetes sistema ne nastaje samim brojem replika. Ona zavisi od raspodele podova, realnog kapaciteta preživelih čvorova, kvalitetnih health signala, odgovarajućih disruption budžeta, mreže i skladišta, ali i od sposobnosti tima da brzo razlikuje simptom od uzroka. Game day pretvara te pretpostavke u proverljive tvrdnje. Ako čvor nestane, administrator mora znati šta Node kontroler zaista vidi, kada API stanje može biti zastarelo i kako se korisnički uticaj meri. Ako pod radi ali nije spreman, mora razumeti zašto Service menja skup backend-a bez restartovanja kontejnera.
Najvažnija veština nije izvršenje fault injection komande, već disciplina oko nje: odobren blast radius, poznato dobro početno stanje, jedna promena u jednom trenutku, jasni stop kriterijumi, očuvanje dokaza, hipoteza pre korekcije i puna validacija posle oporavka. Nasumični restart može privremeno ukloniti simptom, ali istovremeno uništiti podatke potrebne da se spreči ponavljanje. Odgovoran operator bira najmanju korekciju koja odgovara potvrđenom uzroku.
Ova laboratorija namerno ostaje u granicama stateless workload-a i jednog worker kvara. Produkcioni game day zahteva dodatne scenarije za HA control plane, etcd, CSI i podatke, DNS, ingress/load balancer, identitet, registrije, spoljne zavisnosti, zone otkaza, backup i probni restore. Svaki takav scenario mora imati sopstveni RPO/RTO, bezbednosnu procenu, vlasnike i povratni plan. Zrelost se ne meri veličinom izazvanog kvara, već količinom pouzdanog znanja i trajnih poboljšanja koja tim iz vežbe dobije.