K8S运算符出现"对象已修改"错误

import "sigs.k8s.io/controller-runtime"

关于这种错误有很多讨论.主要的答案是"发生这个问题是因为我在try 更新时有旧版本的对象." 但我也有几个问题.在我的操作符中,对于某些场景,我需要在一次"协调"调用期间更新Pod的注释两次.当然,我经常收到关于"对象已被修改"的错误.

问:我想知道'r.Get()'和'r.Update()'在哪里获取/更新对象?从本地缓存,还是API服务器?

1:我以为‘r.Get()’是从‘cache’中获取对象,而‘r.Update()’是要缓存的更新对象,对吗?如果是这样,为什么我会得到这个错误?如果pod对象是由于运算符以外的其他原因更改的,我将永远无法在当前的协调过程中更新我的pod对象?(因为缓存对象是本地的,它已经与API服务器不同步.)为什么重试一段时间可以获得最新的对象?

import "sigs.k8s.io/controller-runtime"

var pod corev1.Pod
if err := r.Get(ctx, req.NamespacedName, &pod); err != nil {
    if !apierrors.IsNotFound(err) {
        log.Error(err, "unable to get pod")
        return ctrl.Result{}, err
    }
}

if err := r.Update(ctx, &pod); err != nil {
    log.Error(err, "unable to update chaosctl status")
    return ctrl.Result{}, err
}

2:如果‘r.Get()’是从API服务器获取对象,则‘r.Update()’也更新API服务器.为什么我需要对更新对象进行一些重试?

推荐答案

当您在Kubernetes控制器中使用r.Get()和r.Update()时,与API服务器的交互涉及本地缓存和API服务器本身.

一百:

R.Get()函数从本地缓存中检索对象(如果它存在);否则,它从API服务器获取它. 如果对象存在于本地缓存中,则立即返回该对象.如果没有,则向API服务器发出获取对象的请求,然后将检索到的对象存储在本地缓存中以供后续使用. R.Update():

函数r.Update()更新本地缓存和API服务器中的对象. 如果对象在最初检索后已在本地缓存中进行了修改,则对API服务器的更新操作可能会失败,并出现冲突错误.当缓存中对象的版本与API服务器上的版本不匹配时,就会发生这种情况,这表明其他人同时修改了该对象.

可以有策略来处理它-

  1. Optimistic Concurrency Control (OCC):-更新前的匹配版本.
  2. retry-retry-
    retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
        return r.Update(ctx, pod)
    })
    if retryErr != nil {
        return retryErr
    }

Go相关问答推荐

GORM Find方法中缺少字段

未对GoFr中的所有请求进行跟踪

为什么 `go mod` 占用了另一个磁盘上的空间而不是我的 GOPATH?

日志(log)文件不在 golang 的日志(log)目录中

无法在go中为docker容器写入有效的挂载路径

Golang chromedp Dockerfile

Global Thread-local Storage 在 Go 中的可行性和最佳实践

regex.ReplaceAll 但如果替换则添加相同数量的字符

使用 GO 在侧 tar 文件中提取 tar 文件的最快方法

如何在自定义验证函数中获取 struct 名称

对所有标志进行 ORing 的简短方法

同时调用应该只获取一次数据

GRPC 反向代理混淆 GRPC 和 GRPC-Web

在 connect-go 拦截器中修改响应体

在 Go 中将指针传递给函数的正确方法是什么,以便我可以读取和/或修改指针表示的值?

将 CSVExport 函数传递给处理程序 Gin

使用 xml.Name 将 xml 解组为 [] struct

防止在 Go 公用文件夹中列出目录

如何将实际上是类型为 reflect.Int32 的类型切片的 interface{} 转换为 int32 的切片?

Go/Golang:如何从 big.Float 中提取最低有效数字?