Golang的Helm包 - 命名空间问题解决方案

Golang的Helm包 - 命名空间问题解决方案 大家好,我正在尝试使用Golang中的helm包来删除发布版本,但指定命名空间会导致程序panic退出,并出现以下信息(从journalctl获取):“service: Main process exited, code=exited, status=2/INVALIDARGUMENT”

我可以使用以下代码列出某个命名空间中的发布版本:

err := actionConfig.Init(settings.RESTClientGetter(), "my-namespace", os.Getenv("HELM_DRIVER"), nil)

releaseList := action.NewList(actionConfig)
releases, err := releaseList.Run()

并且我能看到该命名空间中的所有发布版本。但是,当使用相同的配置来初始化卸载操作时:

	deleter := action.NewUninstall(actionConfig)
	_, err := deleter.Run("my-release-name")

正是在调用 .Run() 方法时我遇到了panic。

如果我不指定命名空间,而是使用以下配置:

actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), nil) 

它不会引起panic,但无法在默认命名空间中找到对应的发布版本名称。

我应该怎么做才能从正确的命名空间中正确删除它?

非常感谢!


另外,我设法调试出以下信息:

level":"DEBUG","msg":"Debug","format":"Ignoring delete failure for %q %s: %v","v":["my-release-name",{"Group":"networking.k8s.io","Version":"v1","Kind":"Ingress"},{"ErrStatus":{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"ingresses.networking.k8s.io \"my-release-name\" not found","reason":"NotFound","details":{"name":"my-release-name","group":"networking.k8s.io","kind":"ingresses"},"code":404}}]}

更多关于Golang的Helm包 - 命名空间问题解决方案的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

有报告指出,在初始化过程中指定命名空间并不总是按预期工作,尤其是在执行卸载操作时。即使你指定了不同的命名空间,卸载操作仍可能默认使用 default 命名空间。

更多关于Golang的Helm包 - 命名空间问题解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在卸载操作时命名空间配置不一致。在Helm Go SDK中,action.NewUninstall 默认使用 actionConfig.KubeClient 的命名空间配置,但你的初始化方式可能导致命名空间未正确传递。

以下是正确的解决方案:

package main

import (
    "context"
    "log"
    "os"

    "helm.sh/helm/v3/pkg/action"
    "helm.sh/helm/v3/pkg/cli"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {
    // 1. 创建settings
    settings := cli.New()
    
    // 2. 获取REST客户端配置
    restConfig, err := clientcmd.BuildConfigFromFlags("", settings.KubeConfig)
    if err != nil {
        log.Fatal(err)
    }
    
    // 3. 创建Kubernetes客户端
    kubeClient, err := kubernetes.NewForConfig(restConfig)
    if err != nil {
        log.Fatal(err)
    }
    
    // 4. 初始化action配置并显式设置命名空间
    actionConfig := new(action.Configuration)
    namespace := "my-namespace" // 指定目标命名空间
    
    // 使用带命名空间的初始化
    if err := actionConfig.Init(
        settings.RESTClientGetter(),
        namespace,
        os.Getenv("HELM_DRIVER"),
        log.Printf,
    ); err != nil {
        log.Fatal(err)
    }
    
    // 5. 显式设置KubeClient的命名空间
    if actionConfig.KubeClient != nil {
        actionConfig.KubeClient.Namespace = namespace
    }
    
    // 6. 执行卸载操作
    uninstall := action.NewUninstall(actionConfig)
    uninstall.Timeout = 300 // 设置超时时间
    
    // 7. 运行卸载
    resp, err := uninstall.Run("my-release-name")
    if err != nil {
        log.Fatalf("卸载失败: %v", err)
    }
    
    log.Printf("成功卸载: %v", resp.Info)
}

或者使用更简洁的方法,通过环境变量设置默认命名空间:

package main

import (
    "os"
    "helm.sh/helm/v3/pkg/action"
    "helm.sh/helm/v3/pkg/cli"
)

func main() {
    // 设置环境变量强制指定命名空间
    os.Setenv("HELM_NAMESPACE", "my-namespace")
    
    settings := cli.New()
    
    actionConfig := new(action.Configuration)
    if err := actionConfig.Init(
        settings.RESTClientGetter(),
        "my-namespace", // 确保这里与HELM_NAMESPACE一致
        os.Getenv("HELM_DRIVER"),
        nil,
    ); err != nil {
        panic(err)
    }
    
    // 创建卸载操作
    uninstall := action.NewUninstall(actionConfig)
    
    // 显式设置DryRun为false(如果是测试可以设为true)
    uninstall.DryRun = false
    
    // 执行卸载
    _, err := uninstall.Run("my-release-name")
    if err != nil {
        panic(err)
    }
}

对于你遇到的Ingress资源找不到的问题,这是因为Helm在删除时尝试清理所有资源。可以添加资源清理策略:

// 创建卸载配置
uninstall := action.NewUninstall(actionConfig)

// 设置清理选项
uninstall.DisableHooks = false // 根据需要设置
uninstall.KeepHistory = false
uninstall.Wait = true
uninstall.Timeout = 300

// 执行卸载
_, err := uninstall.Run("my-release-name")
if err != nil {
    // 检查是否为资源未找到错误
    if !strings.Contains(err.Error(), "not found") {
        panic(err)
    }
    // 如果是资源未找到,可以继续执行
    log.Println("部分资源未找到,继续卸载流程")
}

确保你的kubeconfig有正确的上下文和命名空间权限:

// 验证命名空间访问权限
func verifyNamespaceAccess(actionConfig *action.Configuration, namespace string) error {
    if actionConfig.KubeClient == nil {
        return fmt.Errorf("kubeclient未初始化")
    }
    
    // 尝试列出命名空间中的pod来验证访问权限
    _, err := actionConfig.KubeClient.KubernetesClientSet.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{Limit: 1})
    return err
}

这些方法应该能解决你的命名空间问题和panic问题。

回到顶部