آموزش کوبرنتیز؛ شب یازدهم: Request، Limit و QoS منابع¶
امشب میبینیم کوبرنتیز CPU و Memory را چگونه Schedule میکند، کلاس QoS یک Pod را تشخیص میدهیم و بهشکلی امن خطای کمبود حافظه را ایجاد و عیبیابی میکنیم.
Request و Limit¶
- Request مقداری است که Scheduler برای جایگذاری Pod در نظر میگیرد.
- Limit سقف زمان اجراست که روی Container اعمال میشود.
- CPU فشردهپذیر است؛ عبور از CPU Limit معمولاً باعث Throttling میشود.
- Memory فشردهناپذیر است؛ عبور از Memory Limit میتواند به
OOMKilledمنجر شود.
واحد CPU تعداد Core است: 1000m برابر یک CPU و 100m برابر یکدهم آن است. واحد Memory از جنس Byte است و Mi و Gi واحدهای دودویی هستند. وقتی منظورتان ۱۲۸ مِبیبایت است، 128Mi بنویسید نه 128M. همچنین اگر نیم Core میخواهید، 500m بنویسید؛ 0.5m معنای دیگری دارد.
Scheduler مقدار Request را با ظرفیت Allocatable Node مقایسه میکند، نه مصرف لحظهای. یک Pod کممصرف با Request بزرگ میتواند مانع Schedule شدن Pod دیگری شود.
کلاسهای QoS¶
| کلاس | شرایط |
|---|---|
| Guaranteed | همهٔ Containerها CPU Request/Limit برابر و Memory Request/Limit برابر دارند |
| Burstable | دستکم یک Request یا Limit وجود دارد، اما شرایط Guaranteed برقرار نیست |
| BestEffort | هیچ Containerای Request یا Limit مربوط به CPU و Memory ندارد |
QoS هنگام فشار روی Node بر اولویت Eviction اثر میگذارد، اما تضمین کامل دسترسپذیری نیست.
Manifest آزمایش Memory¶
apiVersion: apps/v1
kind: Deployment
metadata:
name: resource-demo
namespace: course-night-11
spec:
replicas: 1
selector:
matchLabels:
app: resource-demo
template:
metadata:
labels:
app: resource-demo
spec:
containers:
- name: memory-demo
image: polinux/stress
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
resources:
requests:
cpu: 25m
memory: 50Mi
limits:
cpu: 200m
memory: 100Mi
بررسی ظرفیت پیش از آزمایش¶
kubectl get node playground-mj \
-o custom-columns='NAME:.metadata.name,CPU:.status.capacity.cpu,ALLOCATABLE_CPU:.status.allocatable.cpu,MEMORY:.status.capacity.memory,ALLOCATABLE_MEMORY:.status.allocatable.memory'
kubectl describe node playground-mj
kubectl top node 2>/dev/null || echo "metrics-server is not available; continue with API status"
اگر نام Node شما متفاوت است، playground-mj را با نام واقعی خروجی kubectl get nodes جایگزین کنید.
ایجاد امن خرابی OOM¶
در این آزمایش Process میکوشد با Limit برابر ۱۰۰ MiB، مقدار ۱۵۰ MiB حافظه اختصاص دهد:
kubectl create namespace course-night-11
kubectl apply -f app.yaml
kubectl get pods --namespace course-night-11 --watch
پس از مشاهدهٔ Restart، Watch را متوقف و شواهد را جمع کنید:
kubectl get pod --namespace course-night-11 \
-o custom-columns='NAME:.metadata.name,PHASE:.status.phase,RESTARTS:.status.containerStatuses[0].restartCount,LAST_REASON:.status.containerStatuses[0].lastState.terminated.reason,LAST_EXIT:.status.containerStatuses[0].lastState.terminated.exitCode'
kubectl describe pod --namespace course-night-11 -l app=resource-demo
kubectl get pod --namespace course-night-11 -l app=resource-demo \
-o jsonpath='{.items[0].status.qosClass}{"\n"}'
ممکن است Pod وضعیت CrashLoopBackOff نشان دهد، اما وضعیت Container قبلی ریشهٔ اصلی را مشخص میکند: OOMKilled و معمولاً Exit Code برابر ۱۳۷.
تعمیر و مقایسه¶
مقدار --vm-bytes را در app.yaml از 150M به 50M تغییر دهید:
kubectl diff -f app.yaml
kubectl apply -f app.yaml
kubectl rollout status deployment/resource-demo --namespace course-night-11
kubectl get pods --namespace course-night-11
برای مقایسهٔ QoS، مقدار CPU Request را با CPU Limit و Memory Request را با Memory Limit برابر کنید. Apply کنید و مطمئن شوید کلاس به Guaranteed تغییر میکند.
مقدارهای تعمیرشده توصیهٔ Sizing برای محیط تولید نیستند. مقدار درست باید از مصرف اندازهگیریشده، رفتار در Peak، Load Test و Headroom موردنیاز به دست بیاید. Memory Limit نزدیک به مصرف عادی ناپایداری میسازد؛ نبود Limit هم اجازه میدهد یک Workload تمام Node را تهدید کند.
مشاهدهٔ اختیاری CPU¶
اگر Metrics Server نصب است، موقتاً یک CPU Stressor با Limit کوچک اجرا و مصرف را بررسی کنید:
مصرف نزدیک Limit بهتنهایی Throttling را ثابت نمیکند. Metricهایی مانند Throttled Seconds از Runtime یا cAdvisor شواهد قویتری هستند و در بخش Observability دوره بررسی میشوند.
چکلیست پایان¶
- Request، Limit، Scheduling، Throttling و خاتمهٔ OOM را توضیح میدهم.
-
OOMKilledرا از وضعیت Container قبلی تشخیص دادهام. - Workload را تعمیر و ثابت ماندن Restartها را مشاهده کردهام.
- پیکربندیهای QoS از نوع Burstable و Guaranteed را تشخیص دادهام.
- ثبت کردهام چرا مقدارهای این آزمایش، مقدار خودکار محیط تولید نیستند.