客户端批量/v1应用与更新与补丁

问题描述 投票:0回答:1

https://pkg.go.dev/k8s.io/client-go/kubernetes/typed/batch/v1 中的 patch、apply 和 update 有什么区别

我正在使用 Kubernetes client-go 并管理 Job 对象。

我遇到过三种更新资源的方法:patch()、apply() 和 update()。

但是,我并不完全清楚它们的差异和最佳用例。

我了解 patch 和 apply 的不同之处在于它们是否执行就地修改。

与这些相比,更新的行为如何? 有人可以解释何时使用补丁、应用或更新吗?最好用实际例子来解释?

此外,在这种情况下使用作业资源时,是否有我应该注意的任何注意事项或最佳实践?

kubernetes kubernetes-go-client
1个回答
0
投票
通用 Kubernetes API 文档中有一个部分“现有资源的更新”。 这说明修改现有对象有三种方式,分别对应这些动词:

Update
    获取一个全新的对象并存储它;但这可能会很庞大,并且如果对象修订号错误,可能会发生冲突
  1. Patch
  2. 仅采用差异并尝试应用它;但您需要构建差异,并且您可能不会注意到并发更改
  3. 服务器端 apply
  4. 获取部分对象并更新这些特定字段,在服务器端跟踪哪些控制器拥有哪些字段;但您无法更新其他进程或控制器拥有的字段
  5. 这三个
  6. client-go
方法对应于这三个动作。 您可以在他们的方法签名中看到这一点:

Update(ctx context.Context, job *batchv1.Job, opts metav1.UpdateOptions)
//                          ^^^^^^^^^^^^^^^^ entire object

Patch(ctx context.Context, name string, pt types.PatchType,
      data []byte, opts metav1.PatchOptions, subresources ...string)
//    ^^^^^^^^^^^ arbitrary patch

Apply(ctx context.Context, job *applyconfigurationsbatchv1.JobApplyConfiguration, opts metav1.ApplyOptions)
//                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                         like batchv1.Job but every field is a pointer

这三个中,
Update()
最容易使用。 您可以

Get()

 一个对象,在控制器代码中修改它,然后 
Update()
 使用更改后的对象。  如果您的系统中有多个参与者,那么您可能会遇到版本冲突。  
retry.RetryOnConflict()
可能会有所帮助,如果这些发生变化,请重复主循环。
Apply()

是一项较新的 Kubernetes 功能(需要 Kubernetes 1.22;截至撰写本文时,当前版本为 1.32,所有现代集群都应该支持它),使用起来需要稍微多一些的工作。 在

metav1.ApplyOptions
中,您必须提供
FieldManager
说明您是谁,并且您必须将
JobApplyConfiguration
 作为单独的对象填写,而不是改变您拥有的对象。
Patch()

要求您构建差异。

如果您使用 

controller-runtime

库(可能通过 Kubebuilder),则其操作会有所不同。 在

client.Writer 接口中, 
Patch()
方法处理“patch”和“apply”动词。 您需要构造一个
client.Patch
对象,但有一些辅助方法可以做到这一点。 对于服务器端应用,似乎没有管理各个字段的选项。
var job batchv1.Job
err := client.Get(ctx, ..., &job)

// Client-side apply: mutate the object, create a diff with the original,
// and Patch()
newJob := job.deepCopy()
modifyJob(newJob)
err = client.Patch(ctx, newJob, client.MergeFrom(job))

// Server-side apply: you don't control the field list
err = client.Patch(ctx, newJob, client.Apply, client.FieldOwner("my-controller"))

在我最近编写的控制器中,我只使用
Update()
。 它工作正常,控制器运行时会在错误时重试,但这意味着我确实在日志中看到频繁的难看的冲突错误。 我也许应该更新它以使用

Patch()

 机制之一,如果您关心其他控制器不修改您的字段,则服务器端应用,如果这对您来说不重要,则应使用计划补丁。
在这种情况下使用职位资源时,我应该注意哪些注意事项或最佳实践?

由于默认情况下作业仅运行一次,因此您实际上无法修改作业中的大多数字段。 只有几个字段在

API 文档
中被明确标记为不可变,但是如果您创建了一个 Job 并且它创建了它的 Pod,则您无法有效地更改 Pod 模板。

© www.soinside.com 2019 - 2024. All rights reserved.