Kalau Anda mengelola cluster Kubernetes di atas server Linux yang instalasinya sudah berumur beberapa tahun, ada satu perubahan yang perlu masuk daftar kerja: sejak Kubernetes v1.35, opsi failCgroupV1 bernilai true secara default. Artinya kubelet tidak lagi mau menyala di node yang masih memakai cgroup v1. Node lama yang belum dimigrasi akan berhenti bergabung ke cluster begitu kubelet-nya di-upgrade, dan itu biasanya baru ketahuan saat kubectl get nodes menunjukkan status NotReady di jam-jam sibuk.
Kubernetes sendiri sudah lama mengarah ke sini. Dukungan manajemen cgroup v1 masuk mode maintenance sejak v1.31, sementara cgroup v2 sudah stabil sejak v1.25. Opsi kembali ke cgroup v1 masih tersedia sampai sekarang, tetapi dijadwalkan dicabut pada Kubernetes v1.38. Jadi pertanyaannya bukan lagi "apakah harus migrasi", melainkan "kapan node kita selesai dimigrasi".
Kenapa cgroup v2 lebih dipilih
cgroup v2 memakai satu hierarki terpadu dengan antarmuka yang lebih konsisten dibanding cgroup v1 yang terpecah per controller. Yang paling terasa di lapangan: delegation controller ke pengguna non-root resmi didukung, sehingga container rootless lebih aman. Selain itu beberapa fitur Kubernetes hanya bisa jalan di cgroup v2:
- Memory QoS memakai
memory.highuntuk throttling sertamemory.min/memory.lowuntuk proteksi berlapis. Model ini tidak bisa disediakan cgroup v1. - Pressure Stall Information (PSI) yang melaporkan kontensi CPU, memori, dan I/O di level node, Pod, dan container. PSI butuh cgroup v2, kernel 4.20+, dan
CONFIG_PSI=y. - In-place Pod resize di level Pod (beta di v1.36) butuh penegakan agregat yang akurat, dan itu hanya benar di cgroup v2.
Langkah 1: pastikan kondisi node sekarang
Sebelum menyentuh apa pun, cek tiap node Linux. Satu perintah sudah cukup untuk tahu jawabannya:
stat -fc %T /sys/fs/cgroup/
# cgroup2fs -> sudah cgroup v2
# tmpfs -> masih cgroup v1
Untuk melihat dari sisi Kubernetes, periksa versi kubelet dan runtime di semua node:
kubectl get nodes -o wide
kubectl get --raw "/api/v1/nodes/<nama-node>/proxy/configz" | grep -i cgroup
Langkah 2: cek prasyarat
Migrasi cgroup bukan sekadar ubah satu flag kubelet. Prasyarat yang harus terpenuhi:
- Kernel Linux 5.8 atau lebih baru (5.9+ disarankan bila ingin memakai Memory QoS).
- Instalasi OS benar-benar boot dengan cgroup v2. Distro lama sering masih default ke v1, jadi ikuti dokumentasi distro masing-masing.
- Container runtime yang mendukung cgroup v2: containerd v1.4+, dan gunakan containerd v2.0+ agar cgroup driver terdeteksi otomatis; atau CRI-O v1.20+ (v1.28+ untuk deteksi otomatis).
- Kubelet dan runtime memakai cgroup driver yang sama. Untuk cluster yang dikelola kubeadm, driver
systemdadalah pilihan yang disarankan.
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
Langkah 3: migrasi node satu per satu
- Aktifkan cgroup v2 di level OS, lalu reboot node. Jangan lakukan di semua node sekaligus.
- Drain node agar Pod berpindah dengan rapi:
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data. - Reboot, lalu pastikan
stat -fc %T /sys/fs/cgroup/mengembalikancgroup2fs. - Nyalakan ulang kubelet dan container runtime, cek
systemctl status kubeletserta log runtime. kubectl uncordon <node>, lalu ulangi untuk node berikutnya.
Untuk cluster yang dikelola kubeadm, v1.35 juga memperketat pemeriksaan awal: preflight check SystemVerification mengembalikan error pada kubeadm init, kubeadm join, dan kubeadm upgrade bila mendeteksi cgroup v1 dengan kubelet v1.35 atau lebih baru. Dengan kubelet versi lama, pemeriksaan yang sama hanya memberi peringatan. Artinya kesalahan konfigurasi ketahuan lebih awal, bukan setelah upgrade selesai.
Yang sering terlewat setelah migrasi
- Alat monitoring yang membaca filesystem cgroup langsung. Perbarui ke cAdvisor v0.43.0 atau lebih baru, dan cek kompatibilitas library Java, Node.js, serta automaxprocs versi lama.
- Prediksi nilai
cpu.weight. cgroup v1 memakaicpu.shares, cgroup v2 memakaicpu.weight. crun v1.23 dan runc v1.3.2 memakai formula konversi non-linear baru yang memberi granularitas lebih baik untuk request CPU kecil, sehingga tool yang menghitung nilai weight secara eksak perlu disesuaikan. - Perilaku OOM. Di node cgroup v2, kubelet default
singleProcessOOMKill: falsedan menulismemory.oom.group, jadi satu event OOM mematikan seluruh proses dalam container, bukan menyisakan container multi-proses yang setengah jalan. - Eviction karena page cache. Kubelet menganggap
active_filetidak bisa direklaim, sehingga beban I/O berat bisa memicu eviction Pod. Migrasi ke cgroup v2 tidak otomatis mengubah perhitungan ini; workaround yang didokumentasikan adalah menyamakan memory request dan limit untuk container dengan I/O intensif setelah mengukur nilai yang tepat.
Cek apakah limit benar-benar masuk ke cgroup
Setelah node kembali sehat, jangan berhenti di "Pod Running". Bandingkan nilai yang diminta dengan yang benar-benar berlaku di kernel:
CONTAINER_ID=$(crictl ps \
--label io.kubernetes.pod.namespace=<ns> \
--label io.kubernetes.pod.name=<pod> -q | head -n1)
PID=$(crictl inspect "$CONTAINER_ID" | jq -r '.info.pid')
CGROUP="/sys/fs/cgroup$(awk -F: '$1=="0"{print $3}' /proc/$PID/cgroup)"
cat "$CGROUP/cpu.weight" # dari request CPU, bukan limit
cat "$CGROUP/cpu.max" # limit CPU; "max <period>" berarti tanpa limit
cat "$CGROUP/memory.max" # limit memori; "max" berarti tanpa limit
Perlu diingat: saat runtime memakai driver systemd, info.runtimeSpec.linux.cgroupsPath bukan path direktori di /sys/fs/cgroup, melainkan path unit systemd. Untuk menelusuri hierarki, systemd-cgls /sys/fs/cgroup/kubepods.slice dan systemd-cgtop jauh lebih cepat daripada menebak nama direktori.
Kalau belum sempat migrasi
Override failCgroupV1: false di file konfigurasi kubelet masih bisa dipakai sebagai penunda, tetapi statusnya sementara dan akan dicabut mengikuti kebijakan deprecation Kubernetes. Untuk cluster baru, langsung pakai cgroup v2; untuk cluster lama, jadwalkan migrasi per node sebelum naik ke v1.35 ke atas, karena satu node yang tertinggal sudah cukup membuat kubelet-nya gagal start dengan konfigurasi default.
Sumber: The Shift to cgroup v2 in Kubernetes: What You Need to Know (Kubernetes Blog, 6 Oktober 2026), Dokumentasi cgroups Kubernetes, Dokumentasi container runtimes.
