Kubernetes 1.37: 10 thay đổi mà mọi Kubernetes Engineer cần biết
Từ KYAML đến việc bắt buộc sử dụng cgroups v1: các tính năng vừa được phát hành và những việc bạn cần thực hiện ngay lúc này.
Kubernetes 1.37 được phát hành vào 26/08/2026. Có 67 cải tiến, trong đó 16 tính năng được nâng lên stable. Có 2 tính năng bị deprecate có thể gây lỗi cluster nếu bỏ qua, cùng một thay đổi liên quan đến SELinux đã bắt đầu khiến pod gặp lỗi âm thầm ở một số cluster áp dụng sớm.
Bài viết sẽ tập trung vào những thay đổi mà engineer cần biết: thay đổi nào quan trọng, tại sao cần quan tâm và cần làm gì trước khi chúng gây vấn đề trên production.
1. KYAML - GA: Cải thiện quy trình làm việc với Kubernetes YAML
KYAML hiện đã được bật mặc định và feature gate đã được loại bỏ.
Output KYAML hiện có trên tất cả lệnh kubectl hỗ trợ flag --output, cung cấp YAML có cấu trúc và kiểu dữ liệu nhất quán hơn so với một số định dạng output trước đây.
Điều này hữu ích cho các engineer xây dựng controller, automation script hoặc GitOps pipeline có xử lý output từ kubectl, giúp giảm các vấn đề liên quan đến việc chuyển đổi kiểu dữ liệu không nhất quán giữa YAML và JSON.
# With KYAML GA — typed output, schema-conformant
kubectl get pod my-pod -o kyaml
# KYAML ensures types conform to the Kubernetes API schema
# Integers are integers, not strings. No more patch surprises.
# KYAML output now available across all --output flag commands
kubectl get deployment my-app -o kyaml
kubectl get service my-svc -o kyaml
kubectl get configmap my-config -o kyaml
2. Metrics API (metrics.k8s.io) chính thức đạt trạng thái GA (General Availability)
API metrics.k8s.io - thành phần cung cấp dữ liệu cho lệnh `kubectl top`, tính năng HPA CPU/Memory autoscaling và hầu hết các hệ thống giám sát - đã chính thức đạt trạng thái GA (Sẵn sàng cho sử dụng rộng rãi) sau nhiều năm ở giai đoạn Beta.
Trạng thái GA đồng nghĩa với việc API được đảm bảo tính ổn định, đáp ứng các kỳ vọng về độ tin cậy theo SLO-level, đồng thời giúp các công cụ sử dụng metrics không còn phải duy trì các cơ chế kiểm tra phiên bản riêng.
# Verify your metrics-server is responding
kubectl top nodes
kubectl top pods --all-namespaces
# The API is now stable — query it directly
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes | jq '.items[0].usage'
# Check API service status
kubectl get apiservice v1beta1.metrics.k8s.io -o yaml
3. Node Declared Features - Xử lý version skew thông minh hơn
Việc vận hành các cluster có nhiều phiên bản khác nhau trong quá trình nâng cấp là một trong những thách thức lớn nhất về mặt vận hành trong Kubernetes. Tính năng "Node Declared Features" (hiện đã đạt trạng thái Ổn định - Stable) đã giải quyết khá tốt vấn đề này.
Giờ đây, các node có thể tự động thông báo các tính năng mà nó hỗ trợ, đã được kiểm soát bằng feature-gated cho control plane. Scheduler và các admission controller sẽ đưa ra quyết định scheduling phù hợp, chỉ phân bổ Pod pod lên những node hỗ trợ các tính năng cần thiết mà không cần quản lý thủ công các taint hay label.
# Pod spec - request a feature-gated capability
# Scheduler will only place this on compatible nodes automatically
apiVersion: v1
kind: Pod
metadata:
name: gpu-workload
spec:
# No manual taints/labels needed anymore for version-skew
# Node Declared Features handles compatibility automatically
containers:
- name: gpu-job
image: nvidia/cuda:12.0-base
resources:
claims:
- name: gpu-resource
resourceClaims:
- name: gpu-resource
spec:
devices:
requests:
- name: gpu
deviceClassName: gpu.example.com
Việc cần làm: Ngừng quản lý thủ công các taint về tính tương thích trong quá trình nâng cấp. Hãy rà soát lại các quy trình (runbook) nâng cấp và loại bỏ các biện pháp xử lý thủ công liên quan đến taint.
4. DRA Improvements - Phân bổ phần cứng ngày càng hoàn thiện
Ba tính năng DRA đã đạt trạng thái GA trong phiên bản 1.37:
Device-level taints và tolerations: cho phép đánh dấu phần cứng là không khả dụng hoặc hiệu năng bị suy giảm mà không cần loại khỏi pool
Resource Claim Status với thông tin network interface chuẩn hóa: cung cấp trạng thái thiết bị theo cấu trúc thống nhất
DRA extended resources: kết nối mô hình extended resources truyền thống với mô hình DRA mới.
Ngoài ra, 4 tính năng mới được đưa vào Alpha: chuẩn bị node tùy chọn, device compatibility groups, thuộc tính numaNode được chuẩn hóa và derived attributes.
5. HPA Tolerance theo từng Workload - Autoscaling chính xác hơn
Per-workload HPA tolerance cho phép bạn tùy chỉnh mức tolerance riêng cho từng HPA, thay vì dùng mặc định 10% của toàn cluster. Giờ đây, một API nhạy cảm với độ trễ và một batch job có thể được scaling theo các cách khác nhau, đúng với yêu cầu thực tế.
Tính năng HPAScaleToZero cũng đã chuyển sang giai đoạn Beta và được kích hoạt mặc định - cho phép giảm số lượng replica xuống mức 0 khi cấu hình `spec.minReplicas` được đặt là 0.
# Latency-sensitive service - tight scaleUp, conservative scaleDown
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: latency-sensitive-api
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleUp:
tolerance: 0.02 # 2% - very responsive scale-up
scaleDown:
tolerance: 0.15 # 15% - conservative scale-down
stabilizationWindowSeconds: 300
---
# Event-driven workload - scale to zero when idle
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: event-consumer
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-processor
minReplicas: 0 # Can now scale to zero (HPAScaleToZero Beta/default)
maxReplicas: 20
metrics:
- type: External
external:
metric:
name: queue_depth
selector:
matchLabels:
queue: "orders"
target:
type: AverageValue
averageValue: "10"
6. SELinuxMount GA — Thay đổi có thể khiến Pod không khởi động
SELinuxMount hiện đã Stable và được bật mặc định. Kubelet sử dụng tùy chọn mount -o context của Linux để áp dụng SELinux label cho toàn bộ volume cùng lúc, giúp cải thiện đáng kể thời gian khởi động đối với các volume lớn.
Thay đổi có thể gây lỗi: Pod chia sẻ volume giữa các container nhưng sử dụng SELinux label khác nhau có thể không khởi động được.
Trước đây, cơ chế relabel đệ quy có thể áp dụng lại label cho từng file. Với cơ chế mount mới, toàn bộ volume chỉ sử dụng một context, nên không thể xử lý các label xung đột.
# THIS WILL BREAK in 1.37 - different SELinux labels on shared volume
spec:
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: writer
securityContext:
seLinuxOptions:
level: "s0:c100,c200" # Context A
volumeMounts:
- name: shared-data
mountPath: /data
- name: reader
securityContext:
seLinuxOptions:
level: "s0:c300,c400" # Context B - CONFLICT - pod fails
volumeMounts:
- name: shared-data
mountPath: /data
---
# FIX: Set SELinux at pod level - all containers inherit same context
spec:
securityContext:
seLinuxOptions:
level: "s0:c100,c200" # Single context for all containers
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: writer
volumeMounts:
- name: shared-data
mountPath: /data
- name: reader
volumeMounts:
- name: shared-data
mountPath: /data
7. Pod Certificates - Native Workload Identity
Tính năng Pod Certificates (đã ổn định) cung cấp cơ chế mTLS chất lượng cao mà không cần sử dụng sidecar hay các CA của bên thứ ba. Các Pod nhận X.509 certificates thông qua podCertificate projected volume; các chứng chỉ này được tự động cấp phát và gia hạn.
apiVersion: v1
kind: Pod
metadata:
name: secure-service
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: workload-cert
mountPath: /var/run/secrets/certs
readOnly: true
volumes:
- name: workload-cert
projected:
sources:
- podCertificate:
signerName: "kubernetes.io/kube-apiserver-client"
expirationSeconds: 3600 # 1 hour - auto-rotated before expiry
Xác minh certificate đã được gắn
kubectl exec secure-service -- \
openssl x509 -in /var/run/secrets/certs/tls.crt -text -noout | \
grep -E "Subject:|Validity|Not After
8. ClusterTrustBundles - Quản lý độ trust của certificate
ClusterTrustBundles (phiên bản ổn định) cung cấp phương thức chuẩn để phân phối các bộ chứng chỉ CA trên toàn cluster. Các Pod tham chiếu đến ClusterTrustBundle để lấy các trusted CA certificate dùng cho việc xác thực peer qua mTLS, đồng thời hỗ trợ tự động cập nhật khi chứng chỉ được thay đổi.
# Define a trust bundle
apiVersion: certificates.k8s.io/v1beta1
kind: ClusterTrustBundle
metadata:
name: internal-ca-bundle
spec:
signerName: "example.com/internal-ca"
trustBundle: |
-----BEGIN CERTIFICATE-----
MIIBpDCCAUqgAwIBAgI... # Your internal CA cert
-----END CERTIFICATE-----
---
# Pod consumes the trust bundle
apiVersion: v1
kind: Pod
metadata:
name: mtls-client
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: ca-bundle
mountPath: /etc/ssl/internal
readOnly: true
volumes:
- name: ca-bundle
projected:
sources:
- clusterTrustBundle:
name: internal-ca-bundle
path: ca-bundle.pem
# Auto-updated when ClusterTrustBundle is rotated
9. cgroups v1 — Kubelet sẽ không khởi động
Đây là một trong những thay đổi quan trọng nhất về mặt vận hành trong Kubernetes 1.37.
Từ Kubernetes 1.37, kubelet mặc định sẽ không khởi động trên các node sử dụng cgroup v1. Flag failCgroupV1 mặc định là true.
Điều đó có nghĩa là các node sử dụng cgroup v1 sẽ không thể tham gia cluster.
# Check if your nodes are on cgroup v1 or v2
stat -fc %T /sys/fs/cgroup/
# cgroup2fs → cgroup v2 (safe to upgrade)
# tmpfs → cgroup v1 (BLOCKED in 1.37)
# Check all nodes in cluster (run from a node or via debug pod)
# systemd-based systems:
cat /proc/cmdline | grep cgroup
# cgroup v1 indicator: systemd.unified_cgroup_hierarchy=0
# Migrate to cgroup v2 on RHEL/CentOS/Fedora
grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"
reboot
# Migrate to cgroup v2 on Ubuntu/Debian
sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"/' \
/etc/default/grub
update-grub && reboot
# Verify after reboot
stat -fc %T /sys/fs/cgroup/
# Expected output: cgroup2fs
Ghi đè khẩn cấp (chỉ mang tính tạm thời — sẽ bị loại bỏ trong phiên bản tương lai):
kubelet --fail-cgroupv1=false
10. kube-dns — Nên lên kế hoạch chuyển đổi
kube-dns không còn là một phần trong các CI pipeline của Kubernetes và cũng không còn được phát triển thêm tính năng mới. Nếu bạn vẫn đang sử dụng kube-dns (thường gặp ở các cluster được triển khai trước năm 2020), nghĩa là bạn đang vận hành một hệ thống hạ tầng DNS không còn được hỗ trợ.
Giải pháp được khuyến nghị là chuyển sang sử dụng CoreDNS. Đối với các cluster có lưu lượng truy cập cao, hãy triển khai thêm NodeLocal DNSCache để tận dụng cơ chế caching tại cấp độ node, giúp giảm đáng kể độ trễ.
# Check your current DNS solution
kubectl get pods -n kube-system | grep -E "coredns|kube-dns"
# If kube-dns is running, check the version
kubectl describe pod -n kube-system -l k8s-app=kube-dns | grep Image
# Verify CoreDNS config after migration
kubectl get configmap -n kube-system coredns -o yaml# NodeLocal DNSCache DaemonSet - for high-traffic clusters
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-local-dns
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: node-local-dns
template:
metadata:
labels:
k8s-app: node-local-dns
spec:
hostNetwork: true
containers:
- name: node-cache
image: registry.k8s.io/dns/k8s-dns-node-cache:1.23.0
args:
- "-localip"
- "169.254.20.10" # Link-local IP for node-local cache
- "-conf"
- "/etc/Corefile"
- "-upstreamsvc"
- "kube-dns"




















