Recent, în cadrul unui atelier intitulatTestarea solicitării dvs. de retragere pe Kubernetes cu acțiunile GKE și GitHub, M-am confruntat cu aceeași problemă de două ori: serviciul A are nevoie de serviciul B, dar serviciul A începe mai repede decât serviciul B, iar sistemul eșuează.
Așteptări în Kubernetes
Ar putea părea ciudat să aștepți în Kubernetes. Natura auto-vindecătoare a platformei Kubernetes este unul dintre cele mai mari avantaje. Să luăm în considerare două pods: o aplicație Python și o bază de date PostgreSQL.
Aplicația pornește foarte repede și încearcă cu nerăbdare să stabilească o conexiune la baza de date.Între timp, baza de date se inițiază cu datele furnizate; conexiunea eșuează.Failed
statului .
După un timp, Kubernetes solicită starea podului aplicației. Pentru că a eșuat, îl termină și pornește un nou pod. În acest moment, se pot întâmpla două lucruri: podul bazei de date nu este încă gata și se întoarce la pătrat unul, sau este gata, iar aplicația se conectează în cele din urmă.
Pentru a accelera procesul, Kubernetes oferăÎncepe testarea: din
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30
periodSeconds: 10
Cu sonda de mai sus, Kubernetes așteaptă o perioadă inițială de zece secunde înainte de a solicita statutul podului. Dacă eșuează, așteaptă încă zece secunde. Clătiți și repetați de 30 de ori înainte de a eșua definitiv.
S-ar putea să fi observat HTTP/health
Kubernetes oferă două opțiuni exclusiveprobăSetări de configurare:httpGet
sauexec
Primul este potrivit pentru aplicații web, în timp ce al doilea este pentru alte aplicații. înseamnă că trebuie să știm ce fel de container conține podul și cum să-i verificăm starea, cu condiția să poată.Bitnami Helm ChartSe prezintă după cum urmează atunci când este aplicat:
startupProbe:
exec:
command:
- /bin/sh
- -c
- -e
- exec pg_isready -U $PG_USER -h $PG_HOST -p $PG_PORT
Rețineți că cele de mai sus sunt o simplificare, deoarece ignoră cu plăcere numele bazei de date și un certificat SSL.
Sonda de pornire accelerează lucrurile în comparație cu situația implicită dacă o configurați corect. Puteți seta o întârziere inițială lungă și apoi creșteri mai scurte. Cu toate acestea, cu cât sunt mai diverse containerele, cu atât este mai dificil să le configurați, deoarece trebuie să fiți expert în fiecare dintre containerele subiacente.
Ar fi bine să căutăm alternative.
Așteptare4x
Alternativele sunt instrumente al căror accent este pe aşteptare.aşteptareIdeea este simplă.Ideea este simplă:
să./wait-for este un script conceput pentru a sincroniza servicii cum ar fi containerele docker.
să
./wait-for
este un script conceput pentru a sincroniza servicii cum ar fi containerele docker.sh
şialpine
compatibilă .
Iată cum să așteptați un API HTTP:
sh -c './wait-for http://my.api/health -- echo "The api is up! Let's use it"'
A făcut treaba, dar în acel moment, a trebuit să copiați script-ul și să verificați manual pentru actualizări.
Vâlcea4xjoacă același rol, dar este disponibil ca un container de versiune și oferă mai multe servicii de așteptat: HTTP, DNS, baze de date și cozi de mesaje.
Oricare ar fi instrumentul pe care îl folosiţi, îl puteţi folosi în interiorulContainere de inițiere: din
săUn Pod poate avea mai multe containere care rulează aplicații în interiorul său, dar poate avea, de asemenea, unul sau mai multe containere init, care sunt rulate înainte de pornirea containerelor de aplicații.
săContainerele Init sunt containere obișnuite, cu excepția:
să
Fiecare container init trebuie să fie finalizat cu succes înainte de începerea următorului.
să
Un Pod poate avea mai multe containere care rulează aplicații în interiorul său, dar poate avea, de asemenea, unul sau mai multe containere init, care sunt rulate înainte de pornirea containerelor de aplicații.
Containerele Init sunt containere obișnuite, cu excepția:
- Fiecare container init trebuie să fie finalizat cu succes înainte de începerea următorului.
Imaginați-vă următorulPod
care depinde de un PostgreSQLDeployment
: din
apiVersion: v1
kind: Pod
metadata:
labels:
type: app
app: recommandations
spec:
containers:
- name: recommandations
image: recommandations:latest
envFrom:
- configMapRef:
name: postgres-config
Aplicația este Python și pornește destul de repede. Încearcă să se conecteze la baza de date PostgreSQL. Din păcate, baza de date nu a terminat inițializarea, deci conexiunea eșuează, iar Kubernetes repornește podul.
Putem rezolva acest lucru cu oinitContainer
Un container în așteptare:
apiVersion: v1
kind: Pod
metadata:
labels:
type: app
app: recommandations
spec:
initContainers:
- name: wait-for-postgres
image: atkrad/wait4x:3.1
command:
- wait4x
- postgresql
- postgres://$(DATABASE_URL)?sslmode=disable
envFrom:
- configMapRef:
name: postgres-config
containers:
- name: recommandations
image: recommandations:latest
envFrom:
- configMapRef:
name: postgres-config
În stadiul de mai sus, lainitContainer
nu se oprește până când baza de date acceptă conexiuni.recommandations
container poate porni. Kubernetes nu are nevoie să opreascăPod
ca și în configurația anterioară! implică mai puține înregistrări și potențial mai puține alerte.
Când așteptarea devine obligatorie
Mai sus este o ușoară îmbunătățire, dar puteți face fără ea. În alte cazuri, așteptarea devine obligatorie. Am experimentat-o recent atunci când mă pregătesc pentru atelierul menționat mai sus.
- să
- Pipeline-ul aplică un manifest pe partea Kubernetes să
- În următorul pas, el rulează testul să
- Deoarece testul începe înainte de citirea aplicației, acesta eșuează. să
Trebuie să așteptăm până când backend-ul este gata înainte de a testa.wait4x
Să aşteptăm pentruPod
pentru a accepta solicitările înainte de a începe testele:
- name: Wait until the application has started
uses: addnab/docker-run-action@v3 #1
with:
image: atkrad/wait4x:latest
run: wait4x http ${{ env.BASE_URL }}/health --expect-status-code 200 #2
- să
- GitHub Action permite executarea unui container. aș fi putut descărca binarul Go în schimb. să
- Așteptați până când punctul final /sănătate returnează un cod de răspuns 200. să
Concluzie
Sondele de pornire Kubernetes sunt o modalitate excelentă de a evita redeschiderea inutilă atunci când porniți servicii care depind una de cealaltă.initContainer
. .wait4x
este un instrument care poate fi folosit în alte contexte. Acum face parte din centura mea de instrumente.
To go further:
- să
- Vâlcea4x să
- Deci, trebuie să așteptați câteva resurse Kubernetes? să
Publicat inițial la A Java Geek pe 20 aprilie, 2025
Despre Java Geek