13: Strategie aktualizacji Deploymentów

Strategie Aktualizacji Deploymentów w Kubernetes

Cel zadania

Celem zadania jest zrozumienie różnych strategii aktualizacji Deploymentów w Kubernetes oraz ich praktyczne zastosowanie wraz z probe’ami i zarządzaniem zasobami.

Teoria

Strategie aktualizacji w Kubernetes

  • Recreate:
    • Najprostsza strategia
    • Zatrzymuje wszystkie istniejące Pody przed utworzeniem nowych
    • Powoduje przestój aplikacji
    • Dobra dla środowisk testowych lub gdy wymagany jest czysty restart
  • RollingUpdate:
    • Domyślna strategia
    • Stopniowo wymienia stare Pody na nowe
    • Zero-downtime deployment
    • Możliwość konfiguracji przez maxSurge i maxUnavailable
    • Możliwość cofnięcia w przypadku problemów

Przykłady konfiguracji strategii:

# Strategia Recreate
spec:
  strategy:
    type: Recreate    # Wszystkie pody są usuwane przed utworzeniem nowych

# Strategia RollingUpdate
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Ile dodatkowych podów może być utworzonych ponad desired
      maxUnavailable: 0  # Ile podów może być niedostępnych podczas update

Wizualizacja strategii

graph LR
    subgraph REC["Strategia: Recreate"]
        direction TB
        R1["v1 Pod 1 ❌<br/>v1 Pod 2 ❌<br/>v1 Pod 3 ❌"]
        R2["⏸ Przestój"]
        R3["v2 Pod 1 ✅<br/>v2 Pod 2 ✅<br/>v2 Pod 3 ✅"]
        R1 --> R2 --> R3
    end

    subgraph ROLL["Strategia: RollingUpdate"]
        direction TB
        S1["v1 ✅  v1 ✅  v1 ✅"]
        S2["v2 ✅  v1 ✅  v1 ✅"]
        S3["v2 ✅  v2 ✅  v1 ✅"]
        S4["v2 ✅  v2 ✅  v2 ✅"]
        S1 --> S2 --> S3 --> S4
    end

    style REC fill:#ffebee
    style ROLL fill:#e8f5e9
    style R2 fill:#ffcdd2,stroke:#f44336

maxSurge i maxUnavailable — co kontrolują

Parametr Znaczenie Przykład (3 repliki)
maxSurge: 1 Ile dodatkowych Podów ponad replicas może istnieć Przez moment 4 Pody
maxUnavailable: 0 Ile Podów może być niedostępnych Zawsze minimum 3 działające
maxSurge: 2, maxUnavailable: 1 Szybciej, ale agresywniej Przez moment 5 Podów, minimum 2 dostępne

Zadanie 1: Deployment z Recreate

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kuard-deployment-XX
spec:
  replicas: 3
  strategy:
    type: Recreate    # Strategia Recreate - wszystkie pody zostaną usunięte przed utworzeniem nowych
  selector:
    matchLabels:
      app: kuard-XX
  template:
    metadata:
      labels:
        app: kuard-XX
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:1  # Zaczynamy od wersji 1
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /healthy
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

Kroki wdrożenia:

  1. W pierwszym terminalu uruchom monitoring podów:
    kubectl get pods -w
    
  2. W drugim terminalu utwórz deployment:
    kubectl apply -f kuard-deployment-XX.yaml
    
  3. W drugim terminalu wykonaj aktualizację do wersji 2:
    kubectl set image deployment/kuard-deployment-XX kuard=gcr.io/kuar-demo/kuard-amd64:2
    
  4. Sprawdź wersje obrazów:
    kubectl describe pods | grep Image:
    

Zadanie 2: Standardowy RollingUpdate - Bezpieczna aktualizacja krocząca

W tym zadaniu wykorzystamy strategię RollingUpdate z maksymalnym bezpieczeństwem - maxUnavailable=0 oznacza, że zawsze będziemy mieli dostępną pełną liczbę podów, a maxSurge=1 pozwoli na dodanie jednego dodatkowego poda podczas aktualizacji.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kuard-deployment-XX
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Możemy stworzyć 1 dodatkowy pod
      maxUnavailable: 0  # Nie pozwalamy na niedostępność żadnego poda
  selector:
    matchLabels:
      app: kuard-XX
  template:
    metadata:
      labels:
        app: kuard-XX
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:2  # Zaczynamy od wersji 2
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /healthy
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

Kroki testowe:

  1. Usuń poprzedni deployment jeśli istnieje:
    kubectl delete deployment kuard-deployment-XX
    
  2. W pierwszym terminalu uruchom monitoring:
    kubectl get pods -w
    
  3. W drugim terminalu zastosuj konfigurację:
    kubectl apply -f kuard-deployment-XX.yaml
    
  4. W drugim terminalu wykonaj aktualizację do wersji 3:
    kubectl set image deployment/kuard-deployment-XX kuard=gcr.io/kuar-demo/kuard-amd64:3
    
  5. Sprawdź status aktualizacji:
    kubectl rollout status deployment/kuard-deployment-XX
    

Zadanie 3: Szybszy RollingUpdate - Równoległa aktualizacja

W tym zadaniu przyspieszymy proces aktualizacji poprzez pozwolenie na tworzenie większej liczby nowych podów jednocześnie (maxSurge=2).

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kuard-deployment-XX
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2        # Możemy stworzyć 2 dodatkowe pody
      maxUnavailable: 1  # Jeden pod może być niedostępny
  selector:
    matchLabels:
      app: kuard-XX
  template:
    metadata:
      labels:
        app: kuard-XX
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:1
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /healthy
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

Porównanie szybkości obu podejść:

Zadanie 2 (Wolniejsze, ale bezpieczniejsze):

  • maxSurge=1, maxUnavailable=0
  • W każdym momencie mamy minimum 3 działające pody
  • Aktualizacja przebiega sekwencyjnie: +1 nowy, -1 stary
  • Dłuższy czas aktualizacji, ale zero downtime
  • Wymaga więcej zasobów (przez moment 4 pody)

Zadanie 3 (Szybsze, ale bardziej agresywne):

  • maxSurge=2, maxUnavailable=1
  • Możemy mieć przez moment tylko 2 działające pody
  • Aktualizacja przebiega równolegle: +2 nowe, -1 stary
  • Szybszy czas aktualizacji, ale możliwa krótka degradacja wydajności
  • Wymaga jeszcze więcej zasobów (przez moment 5 podów)

Kroki testowe:

  1. Usuń poprzedni deployment jeśli istnieje:
    kubectl delete deployment kuard-deployment-XX
    
  2. W pierwszym terminalu obserwuj:
    kubectl get pods -w
    
  3. W drugim terminalu zastosuj konfigurację:
    kubectl apply -f kuard-deployment-XX.yaml
    
  4. W drugim terminalu wykonaj update do wersji 2:
    kubectl set image deployment/kuard-deployment-XX kuard=gcr.io/kuar-demo/kuard-amd64:2
    
  5. Sprawdź status aktualizacji:
    kubectl rollout status deployment/kuard-deployment-XX
    
  6. Po zakończeniu aktualizacji, wróć do wersji 1:
    kubectl set image deployment/kuard-deployment-XX kuard=gcr.io/kuar-demo/kuard-amd64:1
    
  7. Ponownie sprawdź status:
    kubectl rollout status deployment/kuard-deployment-XX
    

Który wariant wybrać?

  • Zadanie 2 (wolniejszy):
    • Dla krytycznych aplikacji produkcyjnych
    • Gdy nie możemy pozwolić sobie na spadek wydajności
    • Gdy mamy wystarczająco dużo zasobów w klastrze
  • Zadanie 3 (szybszy):
    • Dla środowisk deweloperskich/testowych
    • Gdy priorytetem jest szybkość aktualizacji
    • Gdy aplikacja może obsłużyć chwilowy spadek dostępnych instancji

Przydatne komendy

# Sprawdź status rollout
kubectl rollout status deployment/kuard-deployment-XX

# Historia rolloutów
kubectl rollout history deployment/kuard-deployment-XX

# Cofnij ostatni rollout
kubectl rollout undo deployment/kuard-deployment-XX

# Zatrzymaj trwający rollout
kubectl rollout pause deployment/kuard-deployment-XX

# Wznów zatrzymany rollout
kubectl rollout resume deployment/kuard-deployment-XX

Najczęstsze problemy

Problem Rozwiązanie
Pody nie startują po update Sprawdź logi i probe’y
Update trwa zbyt długo Dostosuj maxSurge i maxUnavailable
Problemy z pamięcią Zweryfikuj resource limits

Dobre praktyki

  1. Zawsze używaj probe’ów
    • Readiness do kontroli ruchu
    • Liveness do sprawdzania zdrowia
  2. Ustawiaj resource limits
    • Requests dla gwarantowanych zasobów
    • Limits dla maksymalnego użycia
  3. Monitoruj proces update’u
    • Używaj kubectl rollout status
    • Obserwuj logi aplikacji

results matching ""

    No results matching ""