使用Helm SDK安装Chart卡pending状态,如何通过代码自动处理?
问题根因
- 默认Helm SDK Install接口未配置超时阈值,真实集群环境下资源调度、镜像拉取等耗时操作会导致任务无限卡住
- 缺少安装后状态校验逻辑,无法自动识别pending超时场景并触发重试
- 测试用模拟kubeconfig无实际资源调度逻辑,所以不会触发该问题
实现逻辑
直接基于现有代码做如下改造即可满足需求:
- 初始化Install实例时显式设置3分钟超时,开启Wait配置等待资源就绪
- 安装完成后轮询Release状态,若3分钟后仍处于pending状态则触发重试
- 重试优先走升级逻辑,升级失败则先卸载残留资源再重新安装
- 卸载操作同样开启Wait配置,确保资源完全清理后再执行重装
完整修改代码
import ( "fmt" "log" "os" "time" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/release" "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/util/homedir" ) // 配置常量 const ( installTimeout = 3 * time.Minute maxRetries = 2 // 最大重试次数 ) func main() { kubeConfigPath, err := findKubeConfig() if err != nil { fmt.Printf("获取kubeconfig失败: %v\n", err) return } actionConfig := &action.Configuration{} cfg := cli.New() clientGetter := genericclioptions.NewConfigFlags(false) clientGetter.KubeConfig = &kubeConfigPath if err := actionConfig.Init(clientGetter, "def", "memory", log.Printf); err != nil { fmt.Printf("初始化actionConfig失败: %v\n", err) return } var release *release.Release retryCount := 0 // 重试逻辑 for retryCount < maxRetries { // 先检查是否存在未完成的pending release statusClient := action.NewReleaseStatus(actionConfig) existingRel, err := statusClient.Run("test") if err == nil && existingRel.Info.Status.IsPending() { // 存在pending残留,先卸载 uninstallClient := action.NewUninstall(actionConfig) uninstallClient.Wait = true uninstallClient.Timeout = 1 * time.Minute _, _ = uninstallClient.Run("test") time.Sleep(5 * time.Second) // 等待资源清理完成 } // 初始化安装实例 installClient := action.NewInstall(actionConfig) installClient.ReleaseName = "test" installClient.Namespace = "def" installClient.Wait = true // 等待资源就绪 installClient.Timeout = installTimeout installClient.CreateNamespace = true // 按需开启 // 加载Chart chartPath, err := installClient.ChartPathOptions.LocateChart("./charts/dns", cfg) if err != nil { fmt.Printf("加载Chart路径失败: %v\n", err) retryCount++ continue } // 执行安装 release, err = installClient.Run(chartPath, nil) if err == nil && !release.Info.Status.IsPending() { // 安装成功且状态正常 fmt.Printf("安装成功,Release状态: %s\n", release.Info.Status) break } fmt.Printf("第%d次安装失败/超时,错误: %v,开始重试\n", retryCount+1, err) retryCount++ } if release == nil || release.Info.Status.IsPending() { fmt.Println("多次重试后安装仍失败,已自动清理残留资源") uninstallClient := action.NewUninstall(actionConfig) uninstallClient.Wait = true _, _ = uninstallClient.Run("test") return } fmt.Println("最终安装成功,Release名称: ", release.Name) } func findKubeConfig() (string, error) { env := os.Getenv("KUBECONFIG") if env != "" { return env, nil } path, err := homedir.Expand("~/.kube/config") if err != nil { return "", err } return path, nil }
内容的提问来源于stack exchange,提问作者Jenney
相关产品推荐
相关产品推荐

