1.模拟client-go更新资源时发生冲突
package main
import (
"context"
"fmt"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func updateDeployLabels(name, namespace, labelKey, labelValue string, busyFlag bool) {
//busyFlag 模拟系统繁忙
kconfig, err := clientcmd.BuildConfigFromFlags("", "config")
if err != nil {
panic(err)
}
clientSet, err := kubernetes.NewForConfig(kconfig)
if err != nil {
panic(err)
}
deployObj, err := clientSet.AppsV1().Deployments(namespace).Get(context.Background(), name, metav1.GetOptions{})
if err != nil {
panic(err)
}
newLabel := map[string]string{
labelKey: labelValue,
}
deployObj.Labels = newLabel
if busyFlag {
time.Sleep(5 * time.Second)
}
newDeployObj, err := clientSet.AppsV1().Deployments(namespace).Update(context.Background(), deployObj, metav1.UpdateOptions{})
if err != nil {
fmt.Println("更新labels错误---------:", err)
} else {
fmt.Println("更新后的labels--------:", newDeployObj.Labels)
}
}
func main() {
go updateDeployLabels("nginx-deployment", "default", "app", "first", true)
updateDeployLabels("nginx-deployment", "default", "app", "second", false)
select {}
}
运行结果:
2.使用RetryOnConflict解决资源冲突
package main
import (
"context"
"fmt"
"k8s.io/client-go/util/retry"
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
)
func updateDeployLabels(name, namespace, labelKey, labelValue string, busyFlag bool) {
//busyFlag 模拟系统繁忙
kconfig, err := clientcmd.BuildConfigFromFlags("", "config")
if err != nil {
panic(err)
}
clientSet, err := kubernetes.NewForConfig(kconfig)
if err != nil {
panic(err)
}
retry.RetryOnConflict(retry.DefaultRetry, func() error {
deployObj, err := clientSet.AppsV1().Deployments(namespace).Get(context.Background(), name, metav1.GetOptions{})
if err != nil {
panic(err)
}
newLabel := map[string]string{
labelKey: labelValue,
}
deployObj.Labels = newLabel
if busyFlag {
time.Sleep(5 * time.Second)
}
newDeployObj, err := clientSet.AppsV1().Deployments(namespace).Update(context.Background(), deployObj, metav1.UpdateOptions{})
if err != nil {
fmt.Println("更新labels错误---------:", err)
} else {
fmt.Println("更新后的labels--------:", newDeployObj.Labels)
}
return err
})
}
func main() {
go updateDeployLabels("nginx-deployment", "default", "app", "first", true)
updateDeployLabels("nginx-deployment", "default", "app", "second", false)
select {}
}
运行结果:
3.DefaultRetry参数
var DefaultRetry = wait.Backoff{
Steps: 5, //表示重试的步数,即在发生错误后尝试的次数
Duration: 10 * time.Millisecond, //表示每次重试之间的间隔时间
Factor: 1.0, // 表示每次重试的时间间隔的增长因子
Jitter: 0.1, //表示随机抖动的因子,即在计算重试时间间隔时,会加入一定的随机性,以避免所有重试操作同一时间进行。
}