Chuyển đến nội dung chính

BÀI 39: INFRASTRUCTURE MIGRATION 2026 — CGROUP V2 VÀ CONTAINERD 2.0

Migration guide 2026: nâng cấp từ cgroup v1 lên v2, containerd 1.x lên 2.0, docker shim removal, nftables kube-proxy. Phát hiện vấn đề tương thích và rollback strategy.

🔒 DevSecOps — Bài 39 BÀI 39: INFRASTRUCTURE MIGRATION 2026 — CGROUP V2 VÀ CONTAINERD 2.0

KUBERNETES: TỪ CƠ BẢN ĐẾN NÂNG CAO

Module 9: Cluster Management

xdev.asia

🎯 Mục tiêu bài học

Hiểu và thực hiện migration từ infrastructure cũ (cgroup v1, containerd 1.x, iptables) lên stack mới 2026 (cgroup v2, containerd 2.0, nftables). Phát hiện breaking changes và xử lý tương thích.

1. Tại sao cần migrate?

Timeline deprecation:

  • Dockershim: removed K8s 1.24 (2022) — phải dùng containerd hoặc CRI-O
  • cgroup v1: deprecated Linux kernel 6.x, Ubuntu 24.04 mặc định cgroup v2
  • iptables kube-proxy: deprecated K8s 1.33, removed planned 1.37
  • IPVS kube-proxy: deprecated K8s 1.35
  • containerd 1.x: EOL, containerd 2.0 GA (2025) với nhiều perf improvements

2. Kiểm tra trước khi migrate

# 1. Kiểm tra cgroup version hiện tại
stat -fc %T /sys/fs/cgroup
# cgroup2fs → cgroup v2 (không cần migrate cgroup)
# tmpfs → cgroup v1 (cần migrate)

2. Kiểm tra container runtime

kubectl get nodes -o wide

CONTAINER-RUNTIME cột: containerd://1.7.x hoặc containerd://2.0.x

3. Kiểm tra kube-proxy mode

kubectl -n kube-system describe configmap kube-proxy | grep mode

mode: "" → iptables (default/legacy)

mode: ipvs → IPVS (deprecated)

mode: nftables → OK 2026

4. Kiểm tra kubelet cgroup driver

ssh worker-1 "sudo cat /var/lib/kubelet/config.yaml | grep cgroupDriver"

cgroupDriver: cgroupfs → cần đổi sang systemd

cgroupDriver: systemd → OK

5. Kiểm tra applications có dùng cgroup v1 APIs

Một số apps dùng /sys/fs/cgroup/cpu/cpu.shares (v1 API)

cgroup v2 dùng /sys/fs/cgroup/cpu.weight (khác!)

grep -r "cpu.shares|memory.limit_in_bytes" /etc/

3. Migration cgroup v1 → v2

# Ubuntu 24.04 đã mặc định cgroup v2
# Nếu đang dùng Ubuntu 22.04 với cgroup v1:

Bước 1: Enable cgroup v2 trong GRUB

vi /etc/default/grub

Thêm vào GRUB_CMDLINE_LINUX:

systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all

update-grub reboot

Bước 2: Verify sau reboot

stat -fc %T /sys/fs/cgroup

cgroup2fs ← thành công

Bước 3: Update containerd config

sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml systemctl restart containerd

Bước 4: Update kubelet

/var/lib/kubelet/config.yaml

cat <<EOF >> /var/lib/kubelet/config.yaml cgroupDriver: systemd EOF systemctl restart kubelet

Bước 5: Kiểm tra pods running bình thường

kubectl get pods -A | grep -v Running

4. Migration containerd 1.x → 2.0

# Migration từng node (không drain cả cluster cùng lúc)

Bước 1: Drain node (move pods sang node khác)

kubectl drain worker-1 --ignore-daemonsets --delete-emptydir-data

Bước 2: Nâng cấp containerd

apt-get update apt-get install -y containerd.io # cài phiên bản mới nhất (2.0.x)

Bước 3: Kiểm tra breaking changes containerd 2.0

- plugins.cri.containerd.default_runtime_name thay đổi

- snapshotter: overlayfs là default (thay native)

containerd config default > /tmp/new-config.toml diff /etc/containerd/config.toml /tmp/new-config.toml

Bước 4: Merge config thủ công

Giữ SystemdCgroup = true

Update sandbox_image nếu cần:

sandbox_image = "registry.k8s.io/pause:3.10"

vim /etc/containerd/config.toml

Bước 5: Restart và verify

systemctl restart containerd containerd --version # 2.0.x crictl info | grep -i runtime

Bước 6: Uncordon node

kubectl uncordon worker-1

Bước 7: Verify pods

kubectl get pods -A -o wide | grep worker-1

5. Migration kube-proxy iptables → nftables

# Xem kube-proxy hiện tại
kubectl -n kube-system get configmap kube-proxy -o yaml

Patch kube-proxy configmap

kubectl -n kube-system patch configmap kube-proxy --patch ' data: config.conf: | apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: nftables nftables: masqueradeAll: false masqueradeBit: 14 minSyncPeriod: 0s syncPeriod: 30s '

Restart kube-proxy pods

kubectl -n kube-system rollout restart daemonset/kube-proxy

Verify

kubectl -n kube-system logs -l k8s-app=kube-proxy | head -20

"Using nftables Proxier"

Verify nftables rules được tạo

nft list ruleset | grep k8s | head -20

6. Xử lý Applications không tương thích cgroup v2

# Vấn đề 1: Java JVM cũ (trước JDK 11u336/17u96) không detect cgroup v2
# Fix: Nâng cấp JVM hoặc thêm flags:
# JAVA_TOOL_OPTIONS: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"

Vấn đề 2: Elasticsearch yêu cầu vm.max_map_count

sysctl -w vm.max_map_count=262144 echo "vm.max_map_count=262144" >> /etc/sysctl.d/k8s.conf

Vấn đề 3: Redis cần disable THP (Transparent Huge Pages)

cat <<EOF > /etc/systemd/system/disable-thp.service [Unit] Description=Disable THP [Service] Type=oneshot ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' [Install] WantedBy=multi-user.target EOF systemctl enable --now disable-thp

Vấn đề 4: Apps dùng /sys/fs/cgroup/memory/memory.limit_in_bytes (v1 API)

cgroup v2 path: /sys/fs/cgroup/memory.max

Fix: sử dụng Downward API để lấy limits từ K8s thay vì đọc cgroup trực tiếp

7. Rollback Strategy

# Nếu migration thất bại — rollback từng bước

Rollback nftables → iptables

kubectl -n kube-system patch configmap kube-proxy --patch '{"data": {"mode": "iptables"}}' kubectl -n kube-system rollout restart daemonset/kube-proxy

Rollback containerd 2.0 → 1.7.x

apt-get install -y containerd.io=1.7.* systemctl restart containerd kubectl uncordon [node-name]

Rollback cgroup v2 → v1

Edit /etc/default/grub

Remove: systemd.unified_cgroup_hierarchy=1 cgroup_no_v1=all

update-grub && reboot

8. Kubernetes Version Upgrade

# Upgrade theo từng minor version (không skip version)
# 1.30 → 1.31 → 1.32 (KHÔNG nhảy từ 1.30 → 1.32)

Bước 1: Upgrade kubeadm trên control plane đầu tiên

apt-get update apt-get install -y kubeadm=1.32.0-1.1 kubeadm upgrade plan # check plan

kubeadm upgrade apply v1.32.0

Bước 2: Upgrade kubelet và kubectl trên control planes

apt-get install -y kubelet=1.32.0-1.1 kubectl=1.32.0-1.1 systemctl daemon-reload && systemctl restart kubelet

Bước 3: Upgrade worker nodes (drain → upgrade → uncordon)

kubectl drain worker-1 --ignore-daemonsets --delete-emptydir-data ssh worker-1 "apt-get install -y kubeadm=1.32.0-1.1 && kubeadm upgrade node" ssh worker-1 "apt-get install -y kubelet=1.32.0-1.1 && systemctl restart kubelet" kubectl uncordon worker-1

Verify

kubectl get nodes kubectl version

Tóm tắt

  • cgroup v2: Ubuntu 24.04 default, đổi cgroupDriver sang systemd
  • containerd 2.0: drain → upgrade → verify → uncordon từng node
  • kube-proxy nftables: patch configmap → restart DaemonSet
  • Luôn có rollback plan trước khi migrate production
  • K8s upgrade: từng minor version, không skip
  • Test trên staging cluster trước khi migrate production