求助, k8s 资源更新问题

2023-06-21 14:27:19 +08:00
 birdhk

我使用 informer 监听 k8s 资源,当用户更新 k8s 资源时,我发现有更新操作就去更新一遍资源以达到覆盖用户更新的目的,但是这样会使更新请求一次又一次进入队列,成了一个循环,如何解决呢?

1602 次点击
所在节点    Kubernetes
10 条回复
lozzow
2023-06-21 15:29:44 +08:00
我不会,但是是不是可以加一个标签下次监听到直接放行
KaynW
2023-06-21 15:44:16 +08:00
要有出队条件, 比如发现已经有了你期望的 label 就把这个事件从队列里丢出去而不是再次更新
bigpigB
2023-06-21 16:36:08 +08:00
您可以通过在更新资源之前进行一些判断和比较来避免循环更新的问题。以下是几种可能的解决方法:

使用资源版本( Resource Version )或修改时间戳:在监听到资源更新时,获取当前资源的版本或修改时间戳,并与上次处理的版本或时间戳进行比较。只有当它们不相等时,才执行更新操作。这样可以确保只有真正发生变化的资源才会被更新。

使用标记字段( Annotation )或标签( Label ):为每个资源添加一个特定的标记字段或标签,在触发更新操作时检查该字段或标签是否已设置。如果已设置,则跳过更新;否则,进行更新并设置标记字段或标签。

使用状态字段:为每个资源添加一个表示状态的字段,例如“已更新”。当接收到资源更新事件时,先检查该字段的值,如果已经标记为“已更新”,则跳过更新操作;否则,进行更新并将字段值更新为“已更新”。

延迟更新或批量更新:在监听到资源更新后,不立即执行更新操作,而是延迟一段时间或等待一定数量的更新事件积累后进行批量更新。这样可以避免频繁的单个更新请求。

根据您的具体需求和代码实现,选择适合的方法来避免循环更新问题。
bigpigB
2023-06-21 16:36:33 +08:00
以下是一个使用资源版本( Resource Version )进行判断的示例代码片段,以避免循环更新问题:

go
import (
"fmt"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
)

// 在 Informer 的事件处理函数中调用此方法进行更新操作
func updateResource(clientSet *kubernetes.Clientset, obj interface{}) {
resource, ok := obj.(cache.Resource)
if !ok {
fmt.Println("Invalid resource object")
return
}

// 获取当前资源的版本
currentVersion := resource.GetObjectMeta().GetResourceVersion()

// TODO: 根据自己的需求,获取上次处理的版本或时间戳
lastVersion := "some_last_version"

// 比较当前版本与上次处理的版本
if currentVersion != lastVersion {
// 执行更新操作

// 更新完后,更新上次处理的版本为当前版本
lastVersion = currentVersion

// TODO: 在这里执行你的更新逻辑
}
}
idblife
2023-06-21 16:51:33 +08:00
argocd 了解一下
Frankcox
2023-06-21 16:53:05 +08:00
client-go 的 Update 方法会返回更新后的信息,获取到 ResourceVersion ,比较下 ResourceVersion 来看该更新操作是否已处理。
另外,不清楚你覆盖更新的具体操作,不过这个情景下可以考虑写个 Admission Control 。利用 Mutate 处理资源的 Update 的操作。
Tinet
2023-06-21 17:00:09 +08:00
当用户更新 k8s 资源时,我发现有更新操作就去更新一遍资源以达到覆盖用户更新的目的。
这个不就是 Admission Control 做的事吗,感觉你技术选型错了
birdhk
2023-06-21 17:12:56 +08:00
谢谢各位。我是在写一个同步功能,用户在 host 集群创建了资源,我就把资源同步创建到 member 集群,但是不允许用户在 member 集群修改和删除。所以用户要修改只能修改 host 集群上的资源,然后我去 member 集群修改。所以用户修改的时候我会用 host 集群的资源覆盖掉用户的更新。
feedcode
2023-06-21 19:13:51 +08:00
正如 7 楼所说,你应该用 MutatingWebhookConfiguration , 更新的时候返回 patch 后的 object
feedcode
2023-06-21 19:18:16 +08:00
如果你自己实现 go 代码困难,可以看下 kyverno 或者 Open Policy Agent , 然后写 patch 逻辑

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/950635

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX