Noua istorie

Așteptarea: arta subtilă pe care ar trebui să o stăpânești

de Nicolas Fränkel6m2025/04/25
Read on Terminal Reader

Prea lung; A citi

Recent, în timp ce lucram la un atelier intitulat Testing Your Pull Request pe Kubernetes cu GKE și GitHub Actions, m-am confruntat de două ori cu aceeași problemă: serviciul A are nevoie de serviciul B, dar serviciul A începe mai repede decât serviciul B, iar sistemul eșuează.
featured image - Așteptarea: arta subtilă pe care ar trebui să o stăpânești
Nicolas Fränkel HackerNoon profile picture

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ă.Failedstatului .


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/healthKubernetes oferă două opțiuni exclusiveprobăSetări de configurare:httpGetsauexecPrimul 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ă:


./wait-for este un script conceput pentru a sincroniza servicii cum ar fi containerele docker.

./wait-foreste un script conceput pentru a sincroniza servicii cum ar fi containerele docker.shşialpinecompatibilă .


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


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.

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ătorulPodcare 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 oinitContainerUn 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, lainitContainernu se oprește până când baza de date acceptă conexiuni.recommandationscontainer poate porni. Kubernetes nu are nevoie să opreascăPodca ș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.


  • Pipeline-ul aplică un manifest pe partea Kubernetes
  • În următorul pas, el rulează testul
  • Deoarece testul începe înainte de citirea aplicației, acesta eșuează.


Trebuie să așteptăm până când backend-ul este gata înainte de a testa.wait4xSă aşteptăm pentruPodpentru 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
  1. GitHub Action permite executarea unui container. aș fi putut descărca binarul Go în schimb.
  2. Așteptați până când punctul final /sănătate returnează un cod de răspuns 200.

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. .wait4xeste un instrument care poate fi folosit în alte contexte. Acum face parte din centura mea de instrumente.


To go further:


  • Vâlcea4x
  • Deci, trebuie să așteptați câteva resurse Kubernetes?



Publicat inițial la A Java Geek pe 20 aprilie, 2025

Despre Java Geek

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks