Kubernetes In-Place Pod Resize: CPU & Memori Tanpa Restart

Foto oleh Bernd Dittrich on Unsplash
Ini adalah kemampuan mengubah requests dan limits CPU serta memori sebuah container yang berjalan melalui subresource resize milik pod, biasanya tanpa me-restart pod. Fitur ini membuat resources di spec.containers bersifat mutable untuk CPU dan memori, sehingga requests bisa mengikuti penggunaan nyata alih-alih dibekukan saat pembuatan.
Fitur ini diperkenalkan sebagai alpha di v1.27, lulus ke beta dan aktif secara default di v1.33 (Mei 2025), dan mencapai stabil (GA) di Kubernetes v1.35 pada 19 Desember 2025, di balik feature gate InPlacePodVerticalScaling.
Targetkan subresource resize milik pod, misalnya dengan kubectl patch --subresource resize, dan kirim hanya requests atau limits CPU/memori yang baru. Kubelet mengonfigurasi ulang limits cgroup container secara langsung ketika resizePolicy untuk resource tersebut adalah NotRequired, yang merupakan nilai default.
resizePolicy diatur per resource. NotRequired (default) menerapkan nilai baru ke container yang hidup tanpa restart. RestartContainer me-restart hanya container itu untuk mengambil perubahan, yang dibutuhkan aplikasi yang hanya membaca resource saat startup, seperti heap JVM yang diukur dari limit memorinya.
Mode Recreate lama mengevakuasi dan menjadwalkan ulang pod untuk menerapkan requests baru, yang berarti restart. InPlaceOrRecreate lebih dulu mencoba resize in-place bebas gangguan dan hanya jatuh ke evakuasi jika itu gagal atau node tidak bisa memuatnya. Mode ini lulus ke beta bersamaan dengan GA v1.35 dari in-place resize.

Foto oleh Bernd Dittrich on Unsplash
Ringkasan Utama
Kubernetes in-place pod resize memungkinkan Anda mengubah requests dan limits CPU serta memori sebuah container yang sedang berjalan melalui subresource resize milik pod, biasanya tanpa restart. Diperkenalkan sebagai alpha di v1.27, mencapai beta di v1.33 dan lulus menjadi stabil di v1.35, dan mode InPlaceOrRecreate milik Vertical Pod Autoscaler dibangun di atasnya.
Sepanjang sebagian besar sejarah Kubernetes, requests CPU dan memori sebuah pod praktis dibekukan saat pembuatan. Field spec.containers resources bersifat immutable, jadi satu-satunya cara memberi container lebih banyak memori atau menarik kembali CPU yang menganggur adalah dengan mengganti pod sepenuhnya. Untuk aplikasi web stateless itu bukan masalah. Untuk layanan stateful, batch job yang berjalan lama, atau apa pun yang menyimpan cache di memori, restart berarti downtime nyata dan pekerjaan yang hilang.
Sifat immutable itulah yang membuat penskalaan vertikal begitu kasar. Vertical Pod Autoscaler bisa merekomendasikan angka yang lebih baik, tetapi untuk menerapkannya mode Recreate harus mengevakuasi pod dan membiarkan scheduler membuatnya ulang dengan requests baru. Anda membayar right-sizing dengan gangguan setiap kali. In-place pod resize adalah perubahan yang akhirnya menghapus pajak itu.
Vertical Pod Autoscaler punya empat mode update klasik: Off (hanya merekomendasikan), Initial (menetapkan requests saat pembuatan), dan Recreate atau Auto (aktif memperbarui pod yang berjalan). Masalahnya ada pada cara Recreate menerapkan update — ia mengevakuasi pod ketika requests saat ini berbeda signifikan dari rekomendasi baru, dan pod baru muncul dengan angka yang sudah dikoreksi. Evakuasi menghormati PodDisruptionBudgets, tetapi tetap saja itu sebuah restart.
Untuk berjaga terhadap itu, tim melakukan overprovisioning. Jika Anda tidak bisa mengubah ukuran tanpa restart, Anda meminta puncak yang mungkin pernah Anda butuhkan dan membiarkannya di sana, sehingga node membawa buffer permanen CPU dan memori yang dipesan-tapi-menganggur. Kalikan headroom itu di setiap workload dan Anda membayar kapasitas yang telah dipagari scheduler tetapi tidak dipakai apa pun. In-place resize adalah mekanisme yang akhirnya membuat requests mengikuti kenyataan.
Sejak GA di v1.35, spec.containers resources bersifat mutable untuk CPU dan memori serta merepresentasikan keadaan yang diinginkan; status.containerStatuses resources melaporkan apa yang benar-benar dialokasikan ke container. Anda mendeklarasikan perilaku restart per-resource dengan resizePolicy — setiap entri memasangkan resourceName (cpu atau memory) dengan restartPolicy berupa NotRequired, nilai default, yang menerapkan perubahan ke container yang hidup, atau RestartContainer, yang me-restart hanya container itu untuk mengambil nilai baru.
apiVersion: v1
kind: Pod
metadata:
name: reports-worker
spec:
containers:
- name: worker
image: registry.example.com/reports-worker:2.1.0
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainer
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 512MiNotRequired adalah inti dari semuanya: kubelet mengonfigurasi ulang limits cgroup container yang berjalan secara langsung, tanpa pod baru dan tanpa penjadwalan ulang. RestartContainer ada untuk runtime atau aplikasi yang hanya bisa membaca sebuah resource saat startup — heap JVM yang diukur dari sebuah limit memori adalah kasus klasik. Kebijakan ini berlaku per resource, jadi Anda bisa mengubah CPU secara langsung sambil memaksa restart pada perubahan memori.
Flag kubectl --subresource resize membutuhkan client minimal v1.32. Pada kubectl lama Anda masih bisa mengubah resources melalui API, tetapi pintasan patch dan edit yang praktis terhadap subresource resize tidak akan tersedia — perbarui client-nya, bukan hanya cluster-nya.
Anda tidak mengedit pod secara biasa — Anda menargetkan subresource resize-nya. kubectl patch --subresource resize mengirim hanya requests atau limits baru, dan kubelet merekonsiliasi selisihnya. Dua kondisi status memberi tahu jalannya proses: PodResizePending berarti kubelet belum bisa mengabulkan perubahan (reason Deferred saat bersifat sementara, Infeasible saat node memang tidak bisa memuatnya), dan PodResizeInProgress berarti perubahan diterima dan sedang diterapkan.
# Bump CPU and memory requests on a running pod, no restart
kubectl patch pod reports-worker --subresource resize --patch \
'{"spec":{"containers":[{"name":"worker","resources":{"requests":{"cpu":"500m","memory":"384Mi"}}}]}}'
# Watch the two status conditions the kubelet reports
kubectl get pod reports-worker -o jsonpath='{.status.conditions[?(@.type=="PodResizeInProgress")]}'
# spec.containers[*].resources is the DESIRED state (mutable)
# status.containerStatuses[*].resources is the ACTUAL allocated stateSatu aturan sempat menjebak saya di awal. Sepanjang beta, menurunkan limit memori pada container yang berjalan ditolak mentah-mentah. GA v1.35 mencabut batasan itu: penurunan limit memori kini diizinkan, dan kubelet melakukan pemeriksaan best-effort — ia menerapkan penyusutan hanya jika penggunaan saat ini sudah di bawah limit baru, untuk menghindari OOM kill langsung. Best-effort berarti tidak dijamin, jadi susutkan limit memori dengan hati-hati.
In-place resize mengubah pod yang berjalan, tetapi controller workload tidak mengetahuinya. Jika sebuah Deployment atau VPA-nya kemudian membuat ulang pod itu dari template asli, nilai hasil resize Anda hilang dan pod kembali ke requests di template. Dorong angka yang sudah dikoreksi ke sumber kebenaran Anda — template, atau sebuah objek VPA — atau penjadwalan ulang berikutnya diam-diam mengembalikannya.
Tim autoscaler membangun dua mode VPA baru di atas subresource resize. Keduanya mencoba update in-place bebas gangguan lebih dulu; perbedaannya ada pada fallback-nya:
Kedua pendekatan mencapai tujuan yang sama — pod yang berjalan dengan requests yang tepat — tetapi biaya untuk sampai ke sana sama sekali berbeda:
| Aspek | VPA Recreate (cara lama) | In-place resize |
|---|---|---|
| Gangguan | Pod dievakuasi dan dijadwalkan ulang | Container berjalan dikonfigurasi ulang, biasanya tanpa restart |
| State di memori | Hilang saat evakuasi | Dipertahankan saat kebijakannya NotRequired |
| Cara penerapan | Hapus pod, scheduler membuat ulang | Mengubah resources via subresource resize |
| Overprovisioning | Didorong — restart itu mahal | Berkurang — requests bisa mengikuti penggunaan nyata |
| Kematangan | Stabil bertahun-tahun | GA di Kubernetes v1.35 |
Kesimpulan praktisnya, right-sizing berhenti menjadi peristiwa terjadwal yang mengganggu dan menjadi penyesuaian rutin. Batch job yang kurang meminta memori bisa tumbuh di tengah jalan alih-alih terkena OOM kill dan restart; layanan yang overprovisioned bisa mengembalikan CPU ke node tanpa ada yang menyadarinya.
Jika Anda menjalankan Kubernetes v1.35 atau lebih baru, in-place resize aktif secara default dan layak digunakan dengan sengaja — mulailah dengan menetapkan entri resizePolicy yang masuk akal pada workload stateful dan batch, dan verifikasi RestartContainer di tempat aplikasi hanya membaca limits-nya saat boot. Untuk right-sizing otomatis, uji coba VPA InPlaceOrRecreate di namespace non-kritis dulu, pantau kondisi PodResizePending dan PodResizeInProgress, dan pastikan template atau objek VPA Anda menyimpan requests yang sudah dikoreksi agar tidak ada yang kembali saat penjadwalan ulang berikutnya.
Sumber