09: Resources, Limits i QoS
Zarządzanie zasobami w Kubernetes: Resources, Limits i QoS
Cel zadania
Celem zadania jest zrozumienie jak działają limity zasobów w Kubernetes, co się dzieje gdy pod przekroczy przydzielone limity oraz jak działa Quality of Service (QoS).
Teoria
Resources w Kubernetes
- Requests: Minimalna ilość zasobów, której pod potrzebuje
- Limits: Maksymalna ilość zasobów, której pod nie może przekroczyć
- CPU: Mierzony w jednostkach CPU (1 CPU = 1 vCPU/Core)
- Można używać milicore (m), np. 100m = 0.1 CPU
- Memory: Mierzona w bajtach
- Można używać sufixów: Ki, Mi, Gi
- Przykład: 256Mi, 1Gi
Quality of Service (QoS) Classes
- Guaranteed
- Requests = Limits dla CPU i pamięci
- Najwyższy priorytet, najmniejsza szansa na usunięcie
- Burstable
- Requests < Limits
- Średni priorytet
- BestEffort
- Brak zdefiniowanych Requests i Limits
- Najniższy priorytet, pierwsze do usunięcia
Diagram: Klasy QoS i priorytet
graph TB
subgraph QOS["Klasy QoS — priorytet przy braku zasobów"]
G["🟢 Guaranteed<br/>requests = limits<br/>Najwyższy priorytet"]
B["🟡 Burstable<br/>requests < limits<br/>Średni priorytet"]
BE["🔴 BestEffort<br/>brak requests/limits<br/>Najniższy priorytet — usuwany pierwszy"]
end
BE -->|"brak zasobów → evict"| B
B -->|"brak zasobów → evict"| G
style G fill:#e8f5e9,stroke:#4caf50
style B fill:#fff3e0,stroke:#ff9800
style BE fill:#ffebee,stroke:#f44336
Requests vs Limits — co oznaczają
graph LR
subgraph AXIS["Zasoby CPU/Memory"]
REQ["requests<br/>Gwarantowane minimum<br/>(Scheduler rezerwuje)"]
USE["Rzeczywiste użycie<br/>aplikacji"]
LIM["limits<br/>Twarde maksimum<br/>(przekroczenie → OOM Kill)"]
end
REQ -->|"aplikacja może użyć więcej"| USE
USE -->|"ale nie więcej niż"| LIM
style REQ fill:#e8f5e9
style LIM fill:#ffebee
Zadanie 1: Pod z gwarantowanymi zasobami (QoS: Guaranteed)
apiVersion: v1
kind: Pod
metadata:
name: kuard-guaranteed-XX
spec:
containers:
- name: kuard
image: gcr.io/kuar-demo/kuard-amd64:1
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "64Mi"
cpu: "100m"
Zadanie 2: Pod z elastycznymi zasobami (QoS: Burstable)
apiVersion: v1
kind: Pod
metadata:
name: kuard-burstable-XX
spec:
containers:
- name: kuard
image: gcr.io/kuar-demo/kuard-amd64:1
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
Zadanie 3: Pod bez limitów (QoS: BestEffort)
apiVersion: v1
kind: Pod
metadata:
name: kuard-besteffort-XX
spec:
containers:
- name: kuard
image: gcr.io/kuar-demo/kuard-amd64:1
Zadanie 4: Test OOM (Out of Memory)
apiVersion: v1
kind: Pod
metadata:
name: kuard-oom-XX
spec:
containers:
- name: kuard
image: gcr.io/kuar-demo/kuard-amd64:1
resources:
requests:
memory: "50Mi"
cpu: "100m"
limits:
memory: "100Mi"
cpu: "200m"
Kroki testowe:
Potrzebujesz do tego zadania dwóch terminali
- W pierwszym terminalu uruchom monitoring podów:
kubectl get pods -w - W drugim terminalu utwórz pod:
kubectl apply -f kuard-oom-XX.yaml
Po utworzeniu poda zobaczysz w pierwszym terminalu:
NAME READY STATUS RESTARTS AGE
kuard-oom-XX 1/1 Running 0 5s
- W drugim terminalu uruchom port forwarding:
kubectl port-forward pod/kuard-oom-XX 8080:8080 -
Otwórz http://localhost:8080 i przejdź do zakładki Memory
-
Kliknij kilka razy przycisk “Grow” aby zwiększyć zużycie pamięci powyżej 100Mi
- W pierwszym terminalu zobaczysz moment restartu:
NAME READY STATUS RESTARTS AGE kuard-oom-XX 1/1 Running 0 30s kuard-oom-XX 0/1 Error 0 45s # Pod napotkał błąd kuard-oom-XX 0/1 CrashLoopBackOff 0 47s # Kubernetes próbuje zrestartować pod kuard-oom-XX 1/1 Running 1 55s # Pod został zrestartowany - Sprawdź status poda:
kubectl describe pod kuard-oom-XX
W sekcji stanu kontenera zobaczysz:
Containers:
kuard:
State: Running
Started: Wed, 04 Dec 2024 22:14:42 +0100
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Started: Wed, 04 Dec 2024 22:14:28 +0100
Finished: Wed, 04 Dec 2024 22:14:30 +0100
Ready: True
Restart Count: 2
Kluczowe informacje:
Last State: TerminatedzReason: OOMKilled- potwierdza, że kontener został zabity z powodu przekroczenia limitu pamięciExit Code: 137- standardowy kod wyjścia dla procesu zabitego przez OOM KillerRestart Count- pokazuje ile razy kontener został zrestartowany
Sprawdzanie QoS Class
kubectl get pod kuard-guaranteed-XX -o yaml | grep qosClass
kubectl get pod kuard-burstable-XX -o yaml | grep qosClass
kubectl get pod kuard-besteffort-XX -o yaml | grep qosClass
Najczęstsze problemy
| Problem | Rozwiązanie |
|---|---|
| Pod ciągle się restartuje | Sprawdź logi i sekcję Last State w describe pod |
| Pod nie startuje | Sprawdź czy node ma wystarczające zasoby |
| Aplikacja działa wolno | Zwiększ requests/limits dla CPU |
| Pod został usunięty | Sprawdź QoS Class i dostępne zasoby na nodzie |
Dobre praktyki
- Zawsze definiuj requests i limits
- Pomaga w planowaniu zasobów
- Chroni przed przeciążeniem node’a
- Monitoruj zużycie zasobów
- Używaj narzędzi jak Prometheus i Grafana
- Regularnie sprawdzaj metryki
- Dobierz odpowiednią klasę QoS
- Dla krytycznych aplikacji używaj Guaranteed
- Dla mniej ważnych możesz użyć Burstable
- BestEffort tylko dla najmniej ważnych zadań
- Testuj limity
- Sprawdź jak aplikacja zachowuje się przy różnych limitach
- Testuj scenariusze OOM
- Monitoruj restarty podów
Podsumowanie
- Resources pomagają efektywnie zarządzać zasobami klastra
- QoS Classes określają priorytety podów
- OOM Kill jest widoczny w statusie kontenera (
Last State) i kodzie wyjścia (137) - Właściwe ustawienie limitów jest kluczowe dla stabilności aplikacji