场景

当多个服务同时修改kubernetes相同资源时可能发生下面的冲突错误

  • 409 Conflict: 这是最常见的错误,表示请求无法完成,因为该资源已经被其他操作修改。Kubernetes 会返回一个包含详细信息的错误消息。

  • ResourceVersion错误: 当你尝试更新资源时,Kubernetes 会检查资源的版本。如果在更新时,资源的版本已经改变,系统可能会返回一个错误,提示你需要使用最新的版本进行更新。

解决方法

引入重试机制,该支持可使用包
 

"k8s.io/client-go/util/retry"

实现。

// 通过 retry.RetryOnConflict 在冲突时再次尝试
if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
			// 获取待更新的pod
			err := k8s.GetObjectByNamespaceKey(k8s.K8sClient, podk8s.Namespace, podk8s.Name, &podk8s)
			if err != nil {
				return err
			}
			labelsMap := make(map[string]string)
			labelsMap["update_label"] = "new_label"
			
			// 构建更新参数
			patch := map[string]interface{}{
				"metadata": map[string]interface{}{
					"labels": labelsMap,
				},
			}
			// json 话打包
			patchBytes, err := json.Marshal(patch)
			if err != nil {
				
				return err
			}
			// 尝试更新
			err = k8s.K8sClient.Patch(context.Background(), &podk8s, client.RawPatch(types.StrategicMergePatchType, patchBytes))
			if err != nil {
				
				return err
			}
			
			return nil
		}); err != nil {
			
			return err
		}

参数说明

代码中 retry.DefaultBackoff 是 wait.Backoff 结构体。
 

wait.Backoff 是 Go 语言中的一个结构体,通常用于实现重试机制,特别是在与 Kubernetes API 交互时。它提供了一种控制重试延迟的方式,防止在短时间内频繁重试。

参数说明

  1. Duration:

    • 类型: time.Duration
    • 描述: 表示首次重试的延迟时间。
  2. Factor:

    • 类型: float64
    • 描述: 每次重试之间的延迟因子。通常为大于 1 的值,用于计算下一个重试的延迟。
  3. Steps:

    • 类型: int
    • 描述: 表示最大重试次数。重试的次数会受到这个参数的限制。
  4. Cap:

    • 类型: time.Duration
    • 描述: 最大的重试延迟时间。如果计算出的重试延迟超过此值,则使用此值。
       
      backoff := wait.Backoff{
          Duration: 100 * time.Millisecond, // 首次重试延迟
          Factor:   2.0,                     // 每次重试的延迟因子
          Steps:    5,                       // 最大重试次数
          Cap:      5 * time.Second,         // 最大重试延迟
      }

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐