Reziliență și persistență
În această secțiune provocăm controlat două tipuri de defect: dispariția unei replici stateless și indisponibilitatea temporară a componentei stateful.
Pregătirea datelor
Asigurați-vă că sesiunea port-forward este activă:
kubectl port-forward service/ticketing-api -n cc-lab3 8080:80
În alt terminal, creați un tichet:
curl -X POST http://localhost:8080/tickets \
-H 'Content-Type: application/json' \
-d '{"title":"Test de persistență","priority":"high","reporter":"student"}'
Verificați că tichetul există:
curl http://localhost:8080/tickets
Experimentul 1: dispariția unui Pod API
Listați replicile:
kubectl get pods -n cc-lab3 -l app=ticketing-api
Ștergeți una dintre ele:
kubectl delete pod \
"$(kubectl get pod -n cc-lab3 -l app=ticketing-api -o jsonpath='{.items[0].metadata.name}')" \
-n cc-lab3
Urmăriți reconcilierea:
kubectl get pods -n cc-lab3 -l app=ticketing-api -w
Deployment-ul creează o replică nouă pentru a reveni la starea dorită de două Pod-uri. Datele nu se pierd deoarece ele nu erau stocate în Pod-ul API.
Dacă a fost șters Pod-ul folosit de port-forward, comanda se va opri. Porniți
din nou sesiunea înainte de următorul experiment.
Experimentul 2: indisponibilitatea PostgreSQL
Pentru a păstra defectul suficient de mult încât să îi observăm efectele, scalăm temporar StatefulSet-ul la zero:
kubectl scale statefulset/postgres --replicas=0 -n cc-lab3
După câteva secunde, inspectați API-ul:
kubectl get pods -n cc-lab3 -l app=ticketing-api
kubectl get endpointslices -n cc-lab3 \
-l kubernetes.io/service-name=ticketing-api -o yaml
Comparați cele două endpoint-uri, folosind sesiunea port-forward deja activă:
curl -i http://localhost:8080/livez
curl -i http://localhost:8080/readyz
Comportamentul așteptat este:
/livezrăspunde cu200 OK, deoarece procesul API funcționează/readyzrăspunde cu503 Service Unavailable- Pod-urile API rămân în starea
Running, dar nu mai suntReady - Service-ul nu mai trebuie să trimită trafic normal către aceste replici
- containerele API nu sunt repornite doar pentru că baza de date este temporar indisponibilă.
Acesta este motivul pentru care dependența PostgreSQL aparține readiness probe, nu liveness probe.
Recuperarea
Reporniți instanța PostgreSQL:
kubectl scale statefulset/postgres --replicas=1 -n cc-lab3
kubectl rollout status statefulset/postgres -n cc-lab3
kubectl wait --for=condition=Ready pod \
-l app=ticketing-api -n cc-lab3 --timeout=120s
Verificați din nou:
curl http://localhost:8080/readyz
curl http://localhost:8080/tickets
kubectl get pods,pvc -n cc-lab3
Tichetul creat înaintea opririi trebuie să existe. Pod-ul postgres-0 a fost
recreat, dar PVC-ul data-postgres-0 a fost păstrat și reatașat.
Experiment rapid: ștergerea directă a Pod-ului
Acum puteți observa și self-healing-ul StatefulSet-ului:
kubectl delete pod postgres-0 -n cc-lab3
kubectl get pods -n cc-lab3 -w
StatefulSet-ul recreează un Pod cu același nume și îl asociază aceluiași PVC.
- De ce API-ul rămâne live, dar devine unready?
- De ce liveness nu trebuie să verifice automat toate dependențele externe?
- Ce anume persistă: Pod-ul, PVC-ul sau datele de pe PersistentVolume?
- Ar fi suficient acest setup pentru PostgreSQL high-availability?