使用控制器运行时修补对象的正确方法是什么?

And*_*zio 3 kubernetes kubernetes-apiserver

我正在尝试更新对象的 Env 字段,但我不想遍历它们来找出哪些字段已经存在并且需要更新而不是插入(如果没有必要)。我正在使用控制器运行时。

我尝试使用 ApplyPatchType 进行修补,如下所示:
r.Patch(ctx, myDeployment, client.Apply)
其中 client.Apply is here,并且myDeployment*appsv1.Deployment我找到List(...)并修改的。

这失败了415 Unsupported Media Type。我认为它与需要在 YAML 中编码有关(因为类型的值是“application/apply-patch+yaml”

我通过这样做让它工作(r 有一个嵌入式控制器运行时客户端):

newDeploy := dep.DeepCopy()
original := dep.DeepCopy()
// ... (changing newDeploy)
rawObj, _ := apijson.Marshal(newDeploy)
r.Patch(ctx, original, client.ConstantPatch(types.StrategicMergePatchType, rawObj))
Run Code Online (Sandbox Code Playgroud)

但这感觉效率很低,可能有不必要的 DeepCopies,而且我觉得我不必要地编组我的对象。我想我可以以某种方式使用该Patch命令,就像我使用该命令的方式一样Update,我可以只传入已修改状态的对象并获取StrategicMergePatchType(或ApplyPatchType)行为。

在我看来,如果我只想传递修改后的对象并让客户端“弄清楚”要修补什么,我想使用 client.Apply (ApplyPatchType) 行为,因为我认为StrategicMergePatchType 只是用于比较apply(尽管提供整个对象仍然可以是我认为有效的差异)。任何指导表示赞赏!

And*_*zio 6

现在,我得到了我正在寻找的行为,而无需使用client.MergeFrom手动编写合并逻辑:

MergeFrom 创建一个 Patch,该 Patch 使用合并补丁策略以给定对象为基础进行补丁。

相关代码:

r.Patch(ctx, newDeploy, client.MergeFrom(original))

  • 有关文档:https://sdk.operatorframework.io/docs/building-operators/golang/references/client/#patch (2认同)