In-place Pod Resize
Bài 22 đặt resources.requests/limits lúc tạo pod, và đến giờ mọi cách đổi chúng — sửa Deployment, VPA mode Auto (Bài 40) — đều tạo lại pod. Đó là giả định ngầm suốt series: tài nguyên container là bất biến trong vòng đời pod. In-place pod resize, một tính năng đã chín ở v1.36, phá giả định đó: chỉnh CPU/memory của pod đang chạy mà không tái tạo nó. Bài 40 nhắc tính năng này tồn tại; bài này làm thật và xem nó chạm tới cgroup ra sao.
resizePolicy và subresource resize
Pod khai trước, cho mỗi tài nguyên, việc resize có cần restart container không — qua resizePolicy:
spec:
containers:
- name: c
image: busybox:1.36
command: ["sleep", "100000"]
resizePolicy:
- {resourceName: cpu, restartPolicy: NotRequired}
- {resourceName: memory, restartPolicy: NotRequired}
resources: {requests: {cpu: 100m, memory: 64Mi}, limits: {cpu: 200m, memory: 128Mi}}
NotRequired nghĩa là đổi tài nguyên đó không cần restart — kubelet áp thẳng vào cgroup. Việc đổi đi qua một subresource riêng tên resize (không phải kubectl edit thường), để tách thao tác resize khỏi sửa spec khác. Xem cgroup của pod trên node trước khi resize (đúng cơ chế Bài 64):
ssh worker-0 'D=$(find /sys/fs/cgroup/kubepods.slice -type d -name "*pod<uid>*")
cat $D/cpu.max; cat $D/memory.max'
cpu.max=20000 100000 # 200m
memory.max=134217728 # 128Mi
Resize, kernel đổi tại chỗ
Tăng CPU 200m→500m và memory 128Mi→256Mi qua subresource resize:
kubectl -n resize-demo patch pod rz --subresource resize --patch \
'{"spec":{"containers":[{"name":"c","resources":{"requests":{"cpu":"250m","memory":"128Mi"},"limits":{"cpu":"500m","memory":"256Mi"}}}]}}'
Đọc lại cgroup trên node — giá trị đã đổi, và container không hề restart:
ssh worker-0 'cat $D/cpu.max; cat $D/memory.max'
kubectl -n resize-demo get pod rz -o jsonpath='restarts={.status.containerStatuses[0].restartCount} allocated={.status.containerStatuses[0].resources.limits}'
cpu.max=50000 100000 # 500m — đổi tại chỗ
memory.max=268435456 # 256Mi — đổi tại chỗ
restarts=0 allocated={"cpu":"500m","memory":"256Mi"}
cpu.max và memory.max của cgroup v2 nhảy đúng sang giá trị mới, restartCount vẫn 0, và status...resources báo lượng đã cấp thật. Tiến trình bên trong không gián đoạn — kernel chỉ nới trần cho cgroup đang sống. Đây là điều Bài 40 còn thiếu: VPA right-size bao nhiêu, còn in-place resize áp lượng đó mà không đuổi pod. (VPA tự lái in-place resize thì tới v1.36 vẫn chưa có; phần này là resize thủ công/qua API.)
Hai ràng buộc cần biết
Resize không phải muốn gì cũng được. Thứ nhất, không đổi được QoS class (Bài 22): một pod Burstable không thể resize thành Guaranteed. Thử nâng request lên bằng limit (biến Burstable thành Guaranteed):
kubectl -n resize-demo patch pod rz --subresource resize --patch \
'{"spec":{"containers":[{"name":"c","resources":{"requests":{"cpu":"500m","memory":"256Mi"},"limits":{"cpu":"500m","memory":"256Mi"}}}]}}'
The Pod "rz" is invalid: spec: Invalid value: "Burstable":
Pod QOS Class may not change as a result of resizing
API server từ chối — QoS được suy ra từ quan hệ request/limit (Bài 22) và là thuộc tính ổn định của pod, nên resize không được phép lật nó.
Thứ hai, memory thường cần restartPolicy: RestartContainer. Kernel nới memory.max lên thì dễ, nhưng nhiều ứng dụng đọc giới hạn memory lúc khởi động (JVM heap, các runtime cache) và không tự biết trần đã đổi; với chúng, đặt restartPolicy: RestartContainer cho memory để kubelet restart container áp giá trị mới một cách sạch. CPU thì hầu như luôn NotRequired an toàn vì throttle là động. Nếu node không đủ chỗ cho lượng mới, resize không bị từ chối ngay mà treo — pod mang condition PodResizePending cho tới khi có tài nguyên, khác với pod mới bị Pending ở khâu xếp lịch.
🧹 Dọn dẹp
kubectl delete namespace resize-demo
Resize chỉ đụng một pod thử; xóa namespace là sạch, không thay đổi cấu hình node. Manifest ở github.com/nghiadaulau/kubernetes-from-scratch, thư mục 69-in-place-resize.
Tổng kết
In-place pod resize bỏ giả định "tài nguyên container bất biến trong vòng đời pod": khai resizePolicy cho từng tài nguyên (NotRequired = áp không restart), rồi đổi qua subresource resize. Ta nâng CPU 200m→500m và memory 128Mi→256Mi trên một pod đang chạy, và thấy cgroup v2 trên node (cpu.max, memory.max — Bài 64) đổi đúng giá trị mới với restartCount vẫn 0. Hai ràng buộc: QoS class không đổi được khi resize (API từ chối vì QoS là thuộc tính ổn định suy từ request/limit — Bài 22), và memory thường cần restartPolicy: RestartContainer vì nhiều app đọc giới hạn lúc khởi động; nếu node thiếu chỗ thì resize treo ở PodResizePending. Đây là mảnh ghép "không gián đoạn" cho scale dọc của Bài 40 — VPA tính lượng, in-place resize áp lượng mà không đuổi pod.
Bài 70 sang nhóm tính năng storage vừa graduate ở v1.36: snapshot nhất quán nhiều PVC cùng lúc, mount nội dung OCI image làm volume, và đổi tham số volume động — mở rộng những gì Part IX đã dựng.