Kubernetes Helm Golang客户端示例

12

我希望在 Kubernetes 上创建一个服务,管理集群上的 Helm Charts。它从私有 Chart 仓库安装 Charts。由于我没有找到如何使用 Helm 客户端 API 的文档,因此我正在寻找一些示例或指南,以便在 Helm 客户端之上创建服务。


如果您所说的是这个文件,那么您可以通过命令行使用-h选项运行它,并从源代码中探索实现。 - user378704
4个回答

17

针对Helm3

正如其他答案所指出的,使用Helm 2需要与Tiller进行交互,这使事情变得更加复杂。

由于删除了Tiller,使用Helm 3要干净得多,因为Helm客户端直接与Kubernetes API服务器通信。

以下是使用Helm3以编程方式安装Helm图表的示例代码:

package main

import (
    "fmt"
    "os"

    "helm.sh/helm/v3/pkg/action"
    "helm.sh/helm/v3/pkg/chart/loader"
    "helm.sh/helm/v3/pkg/kube"
    _ "k8s.io/client-go/plugin/pkg/client/auth"
)

func main() {
    chartPath := "/tmp/my-chart-0.1.0.tgz"
    chart, err := loader.Load(chartPath)
    if err != nil {
        panic(err)
    }

    kubeconfigPath := "/tmp/my-kubeconfig"
    releaseName := "my-release"
    releaseNamespace := "default"
    actionConfig := new(action.Configuration)
    if err := actionConfig.Init(kube.GetConfig(kubeconfigPath, "", releaseNamespace), releaseNamespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
        fmt.Sprintf(format, v)
    }); err != nil {
        panic(err)
    }

    iCli := action.NewInstall(actionConfig)
    iCli.Namespace = releaseNamespace
    iCli.ReleaseName = releaseName
    rel, err := iCli.Run(chart, nil)
    if err != nil {
        panic(err)
    }
    fmt.Println("Successfully installed release: ", rel.Name)
}

根据文档,Configuration 类上未定义 Init 方法。 - Ishan Khare
@Aisuko,请看下面我的回复。通过 map[string]interface{} 您可以将参数传递给 Run 函数,如果这些是您的安装值。 - LemurPwned
@turkenh 如何获取已部署图表的列表?我想存储图表的详细信息,如名称、修订版本、图表等。我正在使用HELM3进行图表部署。 - Luffy
@Luffy 你应该使用 list action这里 你可以找到如何在go中使用一个action,即使我们还没有需要list action。 - turkenh
@LemurPwned,您下面的示例有助于传递--set值,但我们还需要传递一个yml文件(-f values.yaml),我们该如何做到这一点?是否有一种类似于安装值的方式也可以传递文件? - Lucifer007
显示剩余2条评论

5

由于我花了一些时间才使其工作,因此这是一个最小示例(没有错误处理,留下有关kube配置的详细信息等),用于列出发布名称:

package main

import (
  "k8s.io/client-go/kubernetes"
  "k8s.io/helm/pkg/helm"
  "k8s.io/helm/pkg/helm/portforwarder"
)

func main() {
  // omit getting kubeConfig, see: https://github.com/kubernetes/client-go/tree/master/examples

  // get kubernetes client
  client, _ := kubernetes.NewForConfig(kubeConfig)

  // port forward tiller
  tillerTunnel, _ := portforwarder.New("kube-system", client, config)

  // new helm client
  helmClient := helm.NewClient(helm.Host(host))

  // list/print releases
  resp, _ := helmClient.ListReleases()
  for _, release := range resp.Releases {
    fmt.Println(release.GetName())
  }
}

1
答案中缺少的一个关键要素是:host := fmt.Sprintf("127.0.0.1:%d", tillerTunnel.Local)。请参阅链接 - B.Z.
当然,如果尝试从集群内部访问Tiller,则无需进行端口转发。只需使用默认值host := "tiller-deploy.kube-system.svc:44134"即可。 - B.Z.
如何安装版本发布?有什么提示吗? - teone
@rabenhorst 如何获取已部署图表的列表?我想存储图表的详细信息,如名称、版本、图表等。我正在使用HELM3进行图表部署。 - Luffy
@Luffy 这整个线程都是关于使用tiller作为集群侧组件的helm2。也许你可以看一下官方helm3 CLI是如何做到的:https://github.com/helm/helm/blob/master/pkg/action/list.go - rabenhorst
在运行inCluster时,请确保运行此代码的Pod或Job具有pods/portforward创建权限。 - Tidhar Klein Orbach

4

我曾长时间尝试使用--set值设置Helm安装,发现目前可用功能的最佳参考是官方Helm文档示例客户端官方Go文档

这仅适用于Helm 3

以下是我使用上述资源成功实现的示例:

除了递归请求map[string]interface{}之外,我没有找到更优雅地定义值的方法,因此如果有人知道更好的方法,请告诉我。

值应大致相当于:
helm install myrelease /mypath --set redis.sentinel.masterName=BigMaster,redis.sentinel.pass="random" ... etc

请注意,与其他答案中的kube.Get不同,此处使用了settings.RESTClientGetter()。 我发现kube.Get会与k8s客户端发生冲突。

package main

import (
    "log"
    "os"

    "helm.sh/helm/v3/pkg/action"
    "helm.sh/helm/v3/pkg/chart/loader"
    "helm.sh/helm/v3/pkg/cli"
    "helm.sh/helm/v3/pkg/release"
)

func main(){
    chartPath := "/mypath"
    namespace := "default"
    releaseName := "myrelease"

    settings := cli.New()

    actionConfig := new(action.Configuration)
    // You can pass an empty string instead of settings.Namespace() to list
    // all namespaces
    if err := actionConfig.Init(settings.RESTClientGetter(), namespace,
        os.Getenv("HELM_DRIVER"), log.Printf); err != nil {
        log.Printf("%+v", err)
        os.Exit(1)
    }

    // define values
    vals := map[string]interface{}{
        "redis": map[string]interface{}{
            "sentinel": map[string]interface{}{
                "masterName": "BigMaster",
                "pass":       "random",
                "addr":       "localhost",
                "port":       "26379",
            },
        },
    }

    // load chart from the path 
    chart, err := loader.Load(chartPath)
    if err != nil {
        panic(err)
    }

    client := action.NewInstall(actionConfig)
    client.Namespace = namespace
    client.ReleaseName = releaseName
    // client.DryRun = true - very handy!


    // install the chart here
    rel, err := client.Run(chart, vals)
    if err != nil {
        panic(err)
    }

    log.Printf("Installed Chart from path: %s in namespace: %s\n", rel.Name, rel.Namespace)
    // this will confirm the values set during installation
    log.Println(rel.Config)
}

3

我也曾经在寻找同样的答案,现在我知道了解决方法并在此分享。

你需要编写一个helm库的包装器。

首先,您需要创建一个与集群tiller通信的客户端。为此,您需要从本地主机到tiller创建一个隧道。使用这个(这是Kiran共享的相同链接)。

  1. 设置Helm环境变量,请查看此处
  2. 接下来使用这个。它将返回一个helm客户端。(您可能需要编写一个包装器来使其适用于您的集群设置)

获取* helm.Client句柄后,您可以使用helm的客户端API,参见此处。您只需使用适当的值使用所需的API即可。

您可能需要定义一些实用程序函数此处,例如将图表加载为文件夹/存档文件。

如果您想做更多的事情,您可以在文档中找到所需方法,并使用客户端调用它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接