Kubernetes v1.35 计划于 2025 年 12 月 17 日发布

📋 目录

🗑️ 废弃功能

移除 cgroup v1 支持

cgroup v2 支持使用统一的控制组层次结构并改进了资源隔离,为现代功能奠定了基础。Kubernetes 自 v1.25 以来对 cgroup v2 的支持已经稳定,使得传统的 cgroup v1 可以被移除。

影响范围:

  • 在只支持 cgroup v1 的 Linux 节点上,kubelet 将无法启动
  • 管理员必须将节点迁移到启用了 cgroup v2 的系统

实际场景:

  • 如果集群运行在较旧的 Ubuntu 18.04 或 CentOS 7 系统上,升级到 v1.35 前需要先将操作系统升级到 Ubuntu 20.04+ 或 CentOS 8+,这些系统默认启用了 cgroup v2
  • 可通过 grep cgroup /proc/filesystems 命令检查当前系统的 cgroup 版本支持情况

弃用 kube-proxy 的 ipvs 模式

ipvs 和 iptables 陪伴了 Kubernetes 很多年,ipvs 最初被采用是为了提高负载均衡的性能,但由于技术复杂性让 ipvs 和其他 kube-proxy 模式之间保持功能一致性变得困难,这造成了巨大的技术债务。

Kubernetes 项目计划在 v1.35 版本后开始尝试弃用 kube-proxy ipvs 模式,以简化 kube-proxy 代码库。

当前状态:

  • 现在 kube-proxy 使用 ipvs 启动时会打印警告信息:
    The ipvs proxier is now deprecated and may be removed in a future release. Please use 'nftables' instead.
    

迁移建议:

  • 对于大规模集群(如超过 5000 个 Service),建议迁移到 nftables 模式
  • 迁移过程可通过修改 kube-proxy 的 ConfigMap,将 mode: ipvs 改为 mode: nftables,然后滚动重启 kube-proxy Pod 来完成
  • 无需重启节点:在以 nftables 模式重新启动时,kube-proxy 会删除现有的所有 iptables 或 ipvs 规则

停止 containerd v1.y 支持

Kubernetes SIG Node 社区已正式商定了 containerd v1.X 的最终支持时间表。Kubernetes v1.35 是提供此支持的最后一个版本。

重要警告:

  • 必须将 Kubernetes 升级到 1.36 版本,你需要将 containerd 升级到 2.0 版本
  • 可以监控 kubelet_cri_losing_support 指标来确定集群中是否有任何节点使用即将不受支持的 containerd 版本

检查与升级示例:

# 检查当前 containerd 版本
containerd --version

# 如果版本为 1.x,需要升级到 2.0+
# 在 Ubuntu/Debian 系统上
apt-get update && apt-get install containerd.io=2.0.*

# 验证升级后的版本
containerd --version
# 输出应显示: containerd containerd.io 2.0.x

✨ 新增功能

节点功能声明 (新功能)

在调度 Pod 时,Kubernetes 使用 labels、taints 和 tolerations 来匹配 workload 与 node。然而,由于控制平面和节点之间的版本偏差,这可能导致 Pod 被调度到缺少所需功能的节点上,从而导致运行时失败。

节点声明功能框架将引入一个标准机制,让节点声明其支持的 Kubernetes feature。节点通过新的 .status.declaredFeatures 字段将其可以支持的功能信息发布到控制平面。

示例场景:
假设某个新功能只在 Kubernetes 1.35+ 的节点上可用。通过节点声明功能,调度器可以确保需要该功能的 Pod 只被调度到支持它的节点上,即使集群中混合运行着不同版本的节点。

实际应用示例:

# 节点自动声明支持的功能
apiVersion: v1
kind: Node
metadata:
  name: worker-node-1
status:
  declaredFeatures:
  - name: "UserNamespaces"
    version: "v1.35"
  - name: "ImageVolumes"
    version: "v1.31"

---
# Pod 可以通过 nodeSelector 或 nodeAffinity 选择具有特定功能的节点
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  nodeSelector:
    feature.node.kubernetes.io/UserNamespaces: "true"
  containers:
  - name: app
    image: myapp:latest

Pod 资源就地更新 (GA)

Kubernetes 正在将 Pod 资源的原地更新功能升级为正式发布(GA)。此功能允许用户在不重启 Pod 或容器的情况下调整 CPU 和内存资源。

功能演进:

  • v1.27: alpha 版本引入
  • v1.33: 升级到 beta
  • v1.35: 目标升级到稳定版(GA)

示例用法:

# 无需重启 Pod,直接更新资源限制
kubectl set resources deployment/my-app --limits=cpu=2,memory=2Gi

实际业务场景:
假设你运行着一个数据处理服务,在业务高峰期需要更多资源。

# 原始 Pod 配置
apiVersion: v1
kind: Pod
metadata:
  name: data-processor
spec:
  containers:
  - name: processor
    image: data-processor:v1
    resources:
      requests:
        memory: "1Gi"
        cpu: "500m"
      limits:
        memory: "2Gi"
        cpu: "1"
# 使用 kubectl patch 原地更新资源,Pod 不会重启
kubectl patch pod data-processor --type='json' -p='[
  {"op":"replace","path":"/spec/containers/0/resources/limits/memory","value":"4Gi"},
  {"op":"replace","path":"/spec/containers/0/resources/limits/cpu","value":"2"}
]'

Pod 证书 (beta)

在运行微服务时,Pod 通常需要强大的加密身份来使用双向 TLS(mTLS)相互认证。虽然 Kubernetes 提供了 Service Account 令牌,但这些令牌是为向 API 服务器进行身份验证而设计的,而不是用于通用工作负载身份。

新功能:
KEP-4317 旨在启用这种原生工作负载身份。它通过允许 kubelet 通过投影卷为 Pod 请求和挂载证书,为保护 Pod 到 Pod 的通信开辟了各种可能性。

实际配置示例:

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: pod-certificates-example
spec:
  restartPolicy: OnFailure
  automountServiceAccountToken: false
  containers:
  - name: main
    image: debian
    command: ['sleep', 'infinity']
    volumeMounts:
    - name: spiffe-credentials
      mountPath: /run/workload-spiffe-credentials
  volumes:
  - name: spiffe-credentials
    projected:
      sources:
      - podCertificate:
          signerName: "row-major.net/spiffe"
          keyType: ED25519
          credentialBundlePath: credentialbundle.pem

应用程序代码可以从 /run/workload-spiffe-credentials/credentialbundle.pem 读取私钥和证书链,并将它们用作 mTLS 客户端证书以对外部 API 进行身份验证。

污点支持数值比较 (新功能)

Kubernetes 正在通过添加数值比较运算符(如 Gt(大于)和 Lt(小于))来增强污点和容忍度。

新功能:
通过此更改,Pod 可以使用容忍度"选择加入"满足特定数值阈值的节点。

示例用法:

tolerations:
- key: "sla"
  operator: "Gt"
  value: "950"
  effect: "NoExecute"

这个例子表示 Pod 只能调度到 SLA 污点值大于 950 的节点上。

实际业务场景:

# Spot nodes with 80% SLA get a repelling taint
apiVersion: v1
kind: Node
metadata:
  name: spot-node-1
spec:
  taints:
  - key: node.kubernetes.io/sla
    value: "800"
    effect: NoSchedule

---
# Cost-optimized workload explicitly tolerates SLA > 750
apiVersion: v1
kind: Pod
spec:
  tolerations:
  - key: node.kubernetes.io/sla
    operator: Gt
    value: "750"
    effect: NoSchedule

---
# Critical workload will not be scheduled until a suitable high reliability node has capacity
apiVersion: v1
kind: Pod
metadata:
  name: critical-workload
spec:
  tolerations:
  - key: node.kubernetes.io/sla
    operator: Gt
    value: "950"
    effect: NoSchedule

用户命名空间 (beta3)

在运行 Pod 时,您可以使用 securityContext 来降低权限,但 Pod 内的容器通常仍以 root(UID 0)身份运行。这种简单性带来了重大挑战,因为容器 UID 0 直接映射到主机的 root 用户。

新功能:
KEP-127 专门允许对 Linux 用户命名空间的原生支持。它通过隔离容器和主机用户/组 ID,为 Pod 安全开辟了各种可能性。

工作原理示例:

  • 容器内:进程认为自己是 UID 0(root)
  • 主机上:该进程实际上映射到 UID 100000(非特权用户)

功能演进:

  • v1.25: alpha 版本发布
  • v1.30: beta 版本
  • 持续通过 beta 成熟度发展

实际安全场景:

apiVersion: v1
kind: Pod
metadata:
  name: secure-web-app
spec:
  hostUsers: false  # 启用用户命名空间隔离
  containers:
  - name: nginx
    image: nginx:latest
    securityContext:
      runAsUser: 0   # 容器内以 root 运行
      runAsGroup: 0

支持将 OCI 镜像挂载为卷 (beta2, enable by default)

在配置 Pod 时,您经常需要为容器捆绑数据、二进制文件或配置文件。在此增强功能之前,人们通常将这类数据直接包含在主容器镜像中,或者需要自定义 init 容器来下载文件并解压到 emptyDir 中。

新功能:
Kubernetes v1.31 添加了对 image 卷类型的支持,允许 Pod 以声明方式从 OCI 注册表中的纯数据工件拉取并解压到卷中。

实际应用示例 - AI 模型推理服务:

apiVersion: v1
kind: Pod
metadata:
  name: ai-inference
spec:
  containers:
  - name: inference-server
    image: tensorflow/serving:latest
    volumeMounts:
    - name: model-volume
      mountPath: /models
      readOnly: true
    env:
    - name: MODEL_PATH
      value: /models/resnet50
  volumes:
  - name: model-volume
    image:
      reference: myregistry.io/ml-models/resnet50:v2.1
      pullPolicy: IfNotPresent

kube-scheduler 支持 gang scheduling (alpha)

在 Kubernetes 中调度大型工作负载一直是一个挑战。当你需要运行分布式训练任务、批处理作业或其他多 Pod 应用时,传统的逐个 Pod 调度方法可能导致资源浪费、死锁和低效。

新功能:
spec.workload 字段将被添加到 Pod 资源中。

示例配置:

apiVersion: v1
kind: Pod
spec:
  workload:
    name: job-1
apiVersion: batch/v1
kind: Job
metadata:
  name: job-1
spec:
  completions: 100
  parallelism: 100
  completionMode: Indexed
  template:
    spec:
      workload:
        name: job-1
      restartPolicy: OnFailure
      containers:
      - name: ml-worker
        image: awesome-training-program:v1
        command: ["python", "train.py"]
        resources:
          limits:
            nvidia.com/gpu: 1
        env:
        - name: JOB_COMPLETION_INDEX
          valueFrom:
            fieldRef:
              fieldPath: "metadata.annotations['batch.kubernetes.io/job-completion-index']"
apiVersion: scheduling/v1alpha1
kind: Workload
metadata:
  namespace: ns-1
  name: job-1
spec:
  podGroups:
  - name: "pg1"
    policy:
      gang:
        minCount: 100

DRA 设备健康检查自定义超时时间

设备健康状况标记为"unknown"的超时时间可通过 grpc message DeviceHealth 中的 health_check_timeout_seconds 字段进行配置。

配置示例:

message DeviceHealth {
  // The name of the resource pool this device belongs to.
  string pool_name = 1;
  
  // The unique name of the device within the pool.
  string device_name = 2;
  
  // Health status of the device.
  string health_status = 3;
  
  // Timestamp of when this health status was last determined by the plugin.
  int64 last_updated_timestamp = 4;
  
  // Health check timeout duration in seconds for this device.
  int64 health_check_timeout_seconds = 5;
}

Envfiles:容器环境变量支持从 initContainer 文件挂载 (beta)

Kubernetes 提供了使用 ConfigMap 和 Secret 在容器内设置环境变量,这会造成集群中存在过多的 configmap。KEP 3721 支持从文件实例化容器的环境变量。

示例配置:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  initContainers:
  - name: setup-envfile
    image: registry.k8s.io/busybox
    command: ['sh', '-c', 'echo "CONFIG_VAR=HELLO" > /data/config.env']
    volumeMounts:
    - name: config
      mountPath: /data
  containers:
  - name: use-envfile
    image: registry.k8s.io/distroless-app
    env:
    - name: CONFIG_VAR
      valueFrom:
        fileKeyRef:
          path: config.env
          volumeName: config
          key: CONFIG_VAR
  restartPolicy: Never
  volumes:
  - name: config
    emptyDir: {}

本文档基于 Kubernetes v1.35 发布前的功能预览整理,具体功能以正式发布版本为准。

更多推荐