Kubernetes v1.35:可变的 PersistentVolume 节点亲和性(Alpha)

PersistentVolume 的节点亲和性 API 可以追溯到 Kubernetes v1.10。 它被广泛用于表示卷可能无法被集群中的所有节点平等访问。 该字段以前是不可变的, 现在在 Kubernetes v1.35(Alpha)中变为可变的。此更改为更灵活的在线卷管理打开了大门。

为什么要使节点亲和性可变?

这就提出了一个明显的问题:为什么现在要使节点亲和性可变? 虽然像 Deployments 这样的无状态工作负载可以自由更改, 并且更改会通过重新创建每个 Pod 自动推出, 但 PersistentVolumes(PV)是有状态的,不能在不丢失数据的情况下轻松重新创建。

然而,存储提供商在发展,存储需求在变化。 最值得注意的是,现在有多个提供商提供区域磁盘。 其中一些甚至支持从区域磁盘到区域存储的实时迁移,而不会中断工作负载。 这种更改可以通过 VolumeAttributesClass API 来表达, 该 API 最近在 1.34 中升级到 GA。 然而,即使卷被迁移到区域存储, 由于 PV 对象中记录的节点亲和性,Kubernetes 仍然阻止将 Pod 调度到其他区域。 在这种情况下,你可能希望将 PV 节点亲和性从:

spec:
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values:
          - us-east1-b

更改为:

spec:
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/region
          operator: In
          values:
          - us-east1

另一个例子是,提供商有时会推出新一代磁盘。 新磁盘并不总是能够附加到集群中的旧节点。 这种可访问性也可以通过 PV 节点亲和性来表达,并确保 Pod 可以被调度到正确的节点。 但是当磁盘升级时,使用此磁盘的新 Pod 仍然可以被调度到旧节点。 为了防止这种情况,你可能希望将 PV 节点亲和性从:

spec:
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: provider.com/disktype.gen1
          operator: In
          values:
          - available

更改为:

spec:
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: provider.com/disktype.gen2
          operator: In
          values:
          - available

所以,它现在是可变的,这是朝着更灵活的在线卷管理迈出的第一步。 虽然这只是从 API 服务器中移除一个验证的简单更改, 但要与 Kubernetes 生态系统良好集成,我们还有很长的路要走。

尝试一下

如果你是 Kubernetes 集群管理员,并且你的存储提供商允许你想要利用的在线更新, 但这些更新会影响卷的可访问性,那么此特性适合你。

请注意,仅更改 PV 节点亲和性实际上不会更改底层卷的可访问性。 在使用此特性之前, 你必须首先在存储提供商中更新底层卷, 并了解更新后哪些节点可以访问该卷。 然后你可以启用此特性并保持 PV 节点亲和性同步。

目前,此特性处于 Alpha 状态。 默认情况下它是禁用的,并且可能会发生变化。 要尝试此特性,请在 APIServer 上启用 MutablePVNodeAffinity 特性门控,然后你可以编辑 PV 的 spec.nodeAffinity 字段。 通常只有管理员可以编辑 PV,请确保你有正确的 RBAC 权限。

更新和调度之间的竞争条件

Pod 外部只有少数几个因素可以影响调度决策,PV 节点亲和性就是其中之一。 通过放宽节点亲和性允许更多节点访问卷是没问题的, 但是当你尝试收紧节点亲和性时,存在竞争条件: 尚不清楚调度器将如何在其缓存中看到修改后的 PV, 因此存在一个小窗口,调度器可能会将 Pod 放置在无法再访问该卷的旧节点上。 在这种情况下,Pod 将卡在 ContainerCreating 状态。

目前正在讨论的一种缓解措施是,如果 PersistentVolume 的节点亲和性被违反,kubelet 将使 Pod 启动失败。 这尚未实现。 因此,如果你现在尝试此特性,请关注使用更新后 PV 的后续 Pod, 并确保它们被调度到可以访问该卷的节点上。 如果你在脚本中更新 PV 并立即启动新 Pod,它可能无法按预期工作。

未来与 CSI(容器存储接口)的集成

目前,修改 PV 的节点亲和性和存储提供商中的底层卷取决于集群管理员。 但手动操作容易出错且耗时。 最终希望将其与 VolumeAttributesClass 集成, 这样非特权用户可以修改他们的 PersistentVolumeClaim(PVC)来触发存储端更新, 并且 PV 节点亲和性会在适当的时候自动更新,无需集群管理员干预。

欢迎用户和存储驱动开发者提供反馈

如前所述,这只是第一步。

如果你是 Kubernetes 用户, 我们想了解你如何使用(或将使用)PV 节点亲和性。 在你的情况下,在线更新它是否有益?

如果你是 CSI 驱动开发者, 你愿意实现此特性吗?你希望 API 是什么样子的?

请通过以下方式提供反馈:

有关此特性的任何询问或具体问题,请联系 SIG Storage 社区

最后修改 June 05, 2026 at 8:31 PM PST: [zh-cn]Add blog: mutable-pv-affinity-alpha (d0653b8032)