DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

Kubernetes Secret 更新报 type: field is immutable:先查同名旧对象

Kubernetes Secret 的 type 更新被拒绝时,先核对同名旧对象和使用者。区分类型不可变与数据不可变,选择新对象并受控迁移引用,保留凭据恢复边界。

提交 type: kubernetes.io/service-account-token 的 Secret,API 返回 type: Invalid value: "kubernetes.io/service-account-token": field is immutable。先查看同一命名空间中是否已经有同名 Secret,以及它实际的 type。更新不能把一个已有的 Opaque Secret 原地转换成另一种类型。

这里处理错误字段明确指向 type 的情况。immutable: true 导致 data 不能改变,是另一项约束;改成 stringData、重新做 Base64 编码或增加账户权限,都不会解除类型更新限制。

判断是新建,还是正在覆盖已有对象

先确认部署目标。以下 namespace 和名称均为示例,这条检查只输出名称、类型和 UID,不展示凭据内容:

kubectl config current-context
kubectl -n team-app get secret app-token \
  -o jsonpath='{.metadata.name}{"\t"}{.type}{"\t"}{.metadata.uid}{"\n"}'

将现有 type 与最终提交的清单比较。kubectl apply、Helm 或控制器提交同名资源时,可能实际进行更新;本地文件看起来是完整的新对象,也不能证明 API 正在新建。

如果现有对象由其他控制器或部署系统管理,还要在受控环境查看其管理信息与使用者,避免生成器不断把不同类型写回同一个名称。涉及完整 Secret 清单的检查应限制访问,不把 data 当作已脱敏内容公开。

没有找到同名对象时,继续确认错误里记录的名称、命名空间和实际发布过程,检查是否在读取后又被另一控制器创建。不要凭一次空查询就认定这项类型校验失效,也不要删除整个空间试错。

名称与账户关联是两件事

ServiceAccount token Secret 通过 metadata.annotations 中的 kubernetes.io/service-account.name 关联已有账户。Secret 的名称不必等于 ServiceAccount 名称;换一个未占用的名字后可以创建,并不能证明两者必须同名。

对于当前 Kubernetes,通常应先评估是否根本需要长期 Secret。TokenRequest 和 Pod 投射令牌可以提供有期限的凭据,不依赖修改已有 Secret 的 type。如果工具支持这些方式,按其正式配置接入;不要为修复类型冲突再添加长期凭据。

必须兼容长期令牌时,先完成权限与泄露风险评估,再在正确命名空间为已存在的账户选择一个未占用的新名称。以下只说明对象结构,不包含实际令牌:

apiVersion: v1
kind: Secret
metadata:
  name: app-reader-legacy-token
  namespace: team-app
  annotations:
    kubernetes.io/service-account.name: app-reader
type: kubernetes.io/service-account-token

annotations 要在 metadata 内,且账户必须在同一命名空间。相关控制器随后填入 token 等字段;提交被接受并不代表令牌已经填入,也不证明应用会自动使用新名称。不要自己编造 token 值填入示例。

先迁移使用者,再处置旧 Secret

新建对象之前保存旧配置、凭据版本和各个引用关系。确认旧 Secret 是业务密码、仓库凭据还是其他用途,不为了本次令牌需求覆盖它的内容。新 Secret 的类型还会带来相应的数据字段要求,不能只把一个名称换到任意类型上。

通过原部署或凭据管理入口更新实际使用者的引用,安排滚动替换或重新加载。用环境变量接收 Secret 的进程不会因为对象更新就自动改变已有环境;新名称也不会自动替换旧 Pod 的引用。

确实只能保留原名称时,删除后重建属于有影响的迁移:原凭据可能在间隙不存在,现有使用者和管理控制器的行为也要核对。先备份、排空或停止依赖者并安排恢复流程,不把 kubectl replace --force 当成无中断的类型转换,更不能批量删除所有 Secret。

长期令牌可能不会过期或轮换,创建、分发、废止都需要纳入凭据管理。新令牌泄露后,换一下 Base64 表示不会撤销它;废止操作也需确认不会影响其他仍在使用同一凭据的客户端。

验收应同时确认新对象类型正确、必要字段已填入、应用使用预期凭据完成原来的访问,并且旧对象的依赖未被误伤。类型错误消失但返回 Unauthorized 或 Forbidden 时,再分别核对令牌有效性、受众与授权,不继续改 type。

回退优先恢复使用者的原引用与部署配置,并确认旧凭据仍被服务接受。已经删除的 token Secret、撤销的凭据或已更换的外部密码,不能仅靠重建同名对象恢复原来的有效状态;按事先保存的恢复方案处理。