首页/云/Kubernetes 速查/工作负载 selector 的不可变约束

工作负载 selector 的不可变约束

apps/v1 下 Deployment/StatefulSet/DaemonSet 的 selector 创建后不可修改,且必须匹配 Pod 模板标签;改选择器只能重建对象。

Kubernetes 速查云更新于 2026-10-13

选择器为什么不可变

在 apps/v1 下,Deployment、StatefulSet、DaemonSet 的选择器创建后不能修改。控制器靠选择器认领并管理 Pod,如果允许中途改标签匹配规则,新旧 Pod 的归属会立即错乱,甚至出现两个控制器争抢同一批 Pod。因此这项校验发生在写入阶段,修改直接被拒绝。

基本信息

适用平台Kubernetes 1.16+,apps/v1 为唯一可用版本
报错关键字field is immutable
一致性要求选择器必须匹配 Pod 模板标签
变更方式导出清单改名改标签后新建对象并迁移
相关字段matchLabels 与 matchExpressions

典型使用场景

  • 新项目在设计阶段就规划标签体系,避免上线后再动选择器
  • 合并两个服务的部署对象,需要统一标签维度
  • 历史清单标签命名不规范,迁移时统一到新规范
  • 在控制台直接编辑选择器字段被拒,需要找到可行的替代路径
  • 多集群复制清单前先确认标签与目标集群现有对象不冲突

正确写法

正确写法
spec:
  selector:
    matchLabels:
      app: web          # 必须与下面的模板标签一致
  template:
    metadata:
      labels:
        app: web

被拒现场与迁移做法

被拒现场与迁移做法
kubectl patch deploy/web -p '{"spec":{"selector":{"matchLabels":{"app":"web2"}}}}'
# 返回:field is immutable
kubectl get deploy web -o yaml > web.yaml       # 导出当前清单
# 改名称与选择器后创建新对象
kubectl apply -f web-new.yaml
kubectl scale deploy/web --replicas=0           # 旧对象先缩容再删除

错误类型对照

情况表现处理方式
选择器与模板标签不一致提交即被拒绝,提示验证错误改标签使两处一致后重新提交
就地修改选择器返回字段不可变导出清单改名并改标签,新建对象
匹配表达式写错校验失败或匹配不到 Pod核对 key 与 values 的写法
两个对象选择器重叠争抢同一批 Pod用互不重叠的标签维度区分
删除重建期间原有 Pod 会失去控制器保护,变成孤儿对象。稳妥顺序是先创建新对象、确认新副本就绪,再把旧对象副本降为零并删除。
选择器与模板标签不匹配属于提交阶段就能发现的错误,不会等到运行时才暴露,因此创建失败时优先检查这两处是否一致。

易错点

  • 以为选择器能像镜像那样随时改:字段创建后不可变,只能新建对象再迁移
  • 选择器与模板标签不一致:提交直接被拒,报错文本里通常已指明两处不匹配
  • 迁移时先删旧对象再建新对象:Pod 短暂失去控制器保护,故障时无人自愈
  • 多个工作负载使用重叠的选择器:出现争抢 Pod 的异常现象,日志里能看到对象被反复创建与删除

数据来源与参考

  • Kubernetes 官方文档 · Deployments(Selector 不可变说明)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌