Kubernetes Helm Golang客户端的示例

huangapple go评论84阅读模式
英文:

Samples on kubernetes helm golang client

问题

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

英文:

I want to create a service on kubernetes which manages helm charts on the cluster. It installs charts from a private chart repository. Since I didn't find any documents on how to use helm client api, I was looking for some samples or guidelines for creating a service on top of helm client.

答案1

得分: 17

FOR HELM3

正如其他答案所指出的那样,在Helm 2中,您需要与Tiller进行通信,这会使事情变得复杂。

使用Helm 3更加清晰,因为已经移除了Tiller,Helm客户端直接与Kubernetes API服务器通信。

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

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)
}

希望对您有所帮助!

英文:

FOR HELM3

As other answers pointed, with Helm 2, you need to talk with tiller which complicates stuff.

It is way more clean with Helm 3 since tiller was removed and helm client directly communicates with Kubernetes API Server.

Here is an example code to install a helm chart programmatically with helm3:

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)
}

答案2

得分: 5

由于我花了一些时间来使其工作,这里是一个最简示例(没有错误处理,关于 kube config 的细节被省略...)用于列出发布名称:

package main

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

func main() {
  // 省略获取 kubeConfig 的步骤,参见:https://github.com/kubernetes/client-go/tree/master/examples

  // 获取 Kubernetes 客户端
  client, _ := kubernetes.NewForConfig(kubeConfig)

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

  // 创建 Helm 客户端
  helmClient := helm.NewClient(helm.Host(host))

  // 列出/打印发布
  resp, _ := helmClient.ListReleases()
  for _, release := range resp.Releases {
    fmt.Println(release.GetName())
  }
}

希望对你有帮助!

英文:

Since it took me some time to get this working here is a minimal example (no error handling, left details about kube config, ...) for listing release names:

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())
  }
}

答案3

得分: 4

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

这仅适用于Helm 3

以下是我使用上述资源链接成功的示例。

我还没有找到比递归请求map[string]interface{}更优雅的定义值的方法,所以如果有人知道更好的方法,请告诉我。

值应该大致等同于:
helm install myrelease /mypath --set redis.sentinel.masterName=BigMaster,redis.sentinel.pass="random" ...等等

请注意,与其他答案中的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)
	}

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

    // 从路径加载chart
	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!


    // 在这里安装chart
	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)
    // 这将确认安装过程中设置的值
    log.Println(rel.Config)
}

希望对你有所帮助!

英文:

I was long trying to set up Helm installation with --set values, and I found that the best place to look currently available functionality is official helm documentation example and official Go docs for the client.

This only pertains to Helm 3.

Here's an example I managed to get working by using the resources linked above.

I haven't found a more elegant way to define values rather than recursively asking for the map[string]interface{}, so if anyone knows a better way, please let me know.

Values should be roughly equivalent to:
helm install myrelease /mypath --set redis.sentinel.masterName=BigMaster,redis.sentinel.pass="random" ... etc

Notice the use of settings.RESTClientGetter(), rather than kube.Get, as in other answers. I found kube.Get to be causing nasty conflicts with k8s clients.

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)
}

答案4

得分: 3

我正在寻找相同的答案,因为我现在知道解决方法了,我在这里分享一下。

你要做的是在helm库周围编写一个包装器。

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

  1. 设置Helm环境变量,请参考这里
  2. 接下来使用这个链接。它会返回一个helm客户端(你可能需要在其周围编写一个包装器以适应你的集群设置)。

在获取*helm.Client句柄之后,你可以使用helm的客户端API,参考这里。你只需要使用你需要的API和相应的值。

你可能还需要一些在这里定义的实用函数,比如将图表加载为文件夹/存档/文件。

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

英文:

I was looking for the same answer, since I do know the solution now, sharing it here.

What you are looking for is to write a wrapper around helm library.

First you need a client which speaks to the tiller of your cluster. For that you need to create a tunnel to the tiller from your localhost. Use this (its the same link as kiran shared.) <br>

  1. Setup the Helm environement variables look here
  2. Use this next. It will return a helm client. (you might need to write a wrapper around it to work with your setup of clusters)

After you get the *helm.Client handle, you can use helm's client API given here. You just have to use the one you need with the appropriate values.

You might need some utility functions defined here, like loading a chart as a folder/archive/file.

If you want to do something more, you pretty much locate the method in the doc and call it using the client.

huangapple
  • 本文由 发表于 2017年8月15日 20:19:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/45692719.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定