Sari la conținutul principal

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.

notă

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:

  • /livez răspunde cu 200 OK, deoarece procesul API funcționează
  • /readyz răspunde cu 503 Service Unavailable
  • Pod-urile API rămân în starea Running, dar nu mai sunt Ready
  • 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.

Întrebări de urmărit
  • 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?