使用Golang Kubernetes client为Secret打标签无现有标签时失败如何解决
报错信息翻译:服务端因请求存在错误拒绝了本次请求
问题根因
你当前使用的是JSONPatchType类型的补丁操作,JSON Patch的add操作要求指定路径的父层级必须存在。当目标Secret没有任何自定义标签时,/metadata/labels字段本身就不存在,直接写入/metadata/labels/test子路径会被K8s APIServer直接拒绝。当你提前手动添加过任意标签后,/metadata/labels路径已存在,所以补丁可以执行成功。
解决方案
推荐使用更适合字段合并的MergePatchType类型实现需求,无需判断原有标签是否存在,也不会覆盖已有的其他标签,修改后的代码如下:
type secret struct { namespace string name string } func main() { k8sClient := k8CientInit() vaultSecret := secret{ namespace: "default", name: "centos-secretstorage", } vaultSecret.patchSecret(k8sClient) } // 合并补丁结构,也可以直接构造JSON字符串 type mergePatchPayload struct { Metadata struct { Labels map[string]string `json:"labels"` } `json:"metadata"` } func (p *secret) patchSecret(k8sClient *kubernetes.Clientset) { // 构造合并补丁,仅新增test标签,原有标签会完整保留 payload := mergePatchPayload{} payload.Metadata.Labels = map[string]string{ "test": "empty", } payloadBytes, _ := json.Marshal(payload) // 改用MergePatchType类型执行补丁操作 emptyres, emptyerr := k8sClient.CoreV1().Secrets(p.namespace).Patch(p.name, types.MergePatchType, payloadBytes) if emptyerr != nil { log.Fatal(emptyerr.Error()) } fmt.Println(emptyres.Labels) }
如果你必须使用JSONPatchType实现,需要先查询目标Secret的元数据,判断labels字段是否存在:
- 若不存在,先执行
add操作创建/metadata/labels路径,值为{"test":"empty"} - 若已存在,直接执行原有逻辑添加
/metadata/labels/test路径即可
内容的提问来源于stack exchange,提问作者popopanda
相关产品推荐
相关产品推荐

