How can I create a kubernetes.Clientset directly from a GCP service account JSON key file in Go?

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

How can I create a kubernetes.Clientset directly from a GCP service account JSON key file in Go?

问题

我正在寻找一种在Go中使用服务帐号JSON密钥文件初始化GKE的kubernetes.Clientset的方法。我找到了一些线索,比如这篇博客这个相关的gist,但是那里提到的方法似乎需要列出GCP项目中的所有集群,以创建kubeconfig的内存表示,这并不理想。

英文:

I'm looking for a way to initialise a kubernetes.Clientset for GKE in Go starting from a service account JSON key file. I found a few leads, such as this blog and this associated gist, but the approach outlined there seems to require listing all clusters in a GCP project to create an in-memory representation of the kubeconfig, which isn't ideal.

答案1

得分: 1

使用来自https://github.com/rancher/kontainer-engine的GKE驱动代码作为灵感,我提出了以下方法(避免了对k8s.io/client-go/tools/clientcmd的依赖):

  1. package main
  2. import (
  3. "context"
  4. "encoding/base64"
  5. "fmt"
  6. "io/ioutil"
  7. "log"
  8. "net/http"
  9. "strings"
  10. "golang.org/x/oauth2"
  11. "golang.org/x/oauth2/google"
  12. "google.golang.org/api/container/v1"
  13. "google.golang.org/api/option"
  14. v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  15. "k8s.io/client-go/kubernetes"
  16. "k8s.io/client-go/rest"
  17. )
  18. func getGKEClientset(cluster *container.Cluster, ts oauth2.TokenSource) (kubernetes.Interface, error) {
  19. capem, err := base64.StdEncoding.DecodeString(cluster.MasterAuth.ClusterCaCertificate)
  20. if err != nil {
  21. return nil, fmt.Errorf("failed to decode cluster CA cert: %s", err)
  22. }
  23. config := &rest.Config{
  24. Host: cluster.Endpoint,
  25. TLSClientConfig: rest.TLSClientConfig{
  26. CAData: capem,
  27. },
  28. }
  29. config.Wrap(func(rt http.RoundTripper) http.RoundTripper {
  30. return &oauth2.Transport{
  31. Source: ts,
  32. Base: rt,
  33. }
  34. })
  35. clientset, err := kubernetes.NewForConfig(config)
  36. if err != nil {
  37. return nil, fmt.Errorf("failed to initialise clientset from config: %s", err)
  38. }
  39. return clientset, nil
  40. }
  41. func main() {
  42. gcpServiceAccountKeyFile := "gcp_service_account_key.json"
  43. gkeLocation := "<GKE项目位置>" // 例如:us-east1
  44. gkeClusterName := "<GKE集群名称>"
  45. gkeNamespace := "<GKE集群命名空间>"
  46. data, err := ioutil.ReadFile(gcpServiceAccountKeyFile)
  47. if err != nil {
  48. log.Fatalf("Failed to read GCP service account key file: %s", err)
  49. }
  50. ctx := context.Background()
  51. creds, err := google.CredentialsFromJSON(ctx, data, container.CloudPlatformScope)
  52. if err != nil {
  53. log.Fatalf("Failed to load GCP service account credentials: %s", err)
  54. }
  55. gkeService, err := container.NewService(ctx, option.WithHTTPClient(oauth2.NewClient(ctx, creds.TokenSource)))
  56. if err != nil {
  57. log.Fatalf("Failed to initialise Kubernetes Engine service: %s", err)
  58. }
  59. name := fmt.Sprintf("projects/%s/locations/%s/clusters/%s", creds.ProjectID, gkeLocation, gkeClusterName)
  60. cluster, err := container.NewProjectsLocationsClustersService(gkeService).Get(name).Do()
  61. if err != nil {
  62. log.Fatalf("Failed to load GKE cluster %q: %s", name, err)
  63. }
  64. clientset, err := getGKEClientset(cluster, creds.TokenSource)
  65. if err != nil {
  66. log.Fatalf("Failed to initialise Kubernetes clientset: %s", err)
  67. }
  68. pods, err := clientset.CoreV1().Pods(gkeNamespace).List(ctx, v1.ListOptions{})
  69. if err != nil {
  70. log.Fatalf("Failed to list pods: %s", err)
  71. }
  72. log.Printf("There are %d pods in the namespace", len(pods.Items))
  73. }
英文:

Using the GKE driver code from https://github.com/rancher/kontainer-engine as inspiration, I came up with the following approach (which avoids the dependency on k8s.io/client-go/tools/clientcmd):

  1. package main
  2. import (
  3. &quot;context&quot;
  4. &quot;encoding/base64&quot;
  5. &quot;fmt&quot;
  6. &quot;io/ioutil&quot;
  7. &quot;log&quot;
  8. &quot;net/http&quot;
  9. &quot;strings&quot;
  10. &quot;golang.org/x/oauth2&quot;
  11. &quot;golang.org/x/oauth2/google&quot;
  12. &quot;google.golang.org/api/container/v1&quot;
  13. &quot;google.golang.org/api/option&quot;
  14. v1 &quot;k8s.io/apimachinery/pkg/apis/meta/v1&quot;
  15. &quot;k8s.io/client-go/kubernetes&quot;
  16. &quot;k8s.io/client-go/rest&quot;
  17. )
  18. func getGKEClientset(cluster *container.Cluster, ts oauth2.TokenSource) (kubernetes.Interface, error) {
  19. capem, err := base64.StdEncoding.DecodeString(cluster.MasterAuth.ClusterCaCertificate)
  20. if err != nil {
  21. return nil, fmt.Errorf(&quot;failed to decode cluster CA cert: %s&quot;, err)
  22. }
  23. config := &amp;rest.Config{
  24. Host: cluster.Endpoint,
  25. TLSClientConfig: rest.TLSClientConfig{
  26. CAData: capem,
  27. },
  28. }
  29. config.Wrap(func(rt http.RoundTripper) http.RoundTripper {
  30. return &amp;oauth2.Transport{
  31. Source: ts,
  32. Base: rt,
  33. }
  34. })
  35. clientset, err := kubernetes.NewForConfig(config)
  36. if err != nil {
  37. return nil, fmt.Errorf(&quot;failed to initialise clientset from config: %s&quot;, err)
  38. }
  39. return clientset, nil
  40. }
  41. func main() {
  42. gcpServiceAccountKeyFile := &quot;gcp_service_account_key.json&quot;
  43. gkeLocation := &quot;&lt;GKE Project Location&gt;&quot; // i.e. us-east1
  44. gkeClusterName := &quot;&lt;GKE Cluster Name&gt;&quot;
  45. gkeNamespace := &quot;&lt;GKE Cluster Namespace&gt;&quot;
  46. data, err := ioutil.ReadFile(gcpServiceAccountKeyFile)
  47. if err != nil {
  48. log.Fatalf(&quot;Failed to read GCP service account key file: %s&quot;, err)
  49. }
  50. ctx := context.Background()
  51. creds, err := google.CredentialsFromJSON(ctx, data, container.CloudPlatformScope)
  52. if err != nil {
  53. log.Fatalf(&quot;Failed to load GCP service account credentials: %s&quot;, err)
  54. }
  55. gkeService, err := container.NewService(ctx, option.WithHTTPClient(oauth2.NewClient(ctx, creds.TokenSource)))
  56. if err != nil {
  57. log.Fatalf(&quot;Failed to initialise Kubernetes Engine service: %s&quot;, err)
  58. }
  59. name := fmt.Sprintf(&quot;projects/%s/locations/%s/clusters/%s&quot;, creds.ProjectID, gkeLocation, gkeClusterName)
  60. cluster, err := container.NewProjectsLocationsClustersService(gkeService).Get(name).Do()
  61. if err != nil {
  62. log.Fatalf(&quot;Failed to load GKE cluster %q: %s&quot;, name, err)
  63. }
  64. clientset, err := getGKEClientset(cluster, creds.TokenSource)
  65. if err != nil {
  66. log.Fatalf(&quot;Failed to initialise Kubernetes clientset: %s&quot;, err)
  67. }
  68. pods, err := clientset.CoreV1().Pods(gkeNamespace).List(ctx, v1.ListOptions{})
  69. if err != nil {
  70. log.Fatalf(&quot;Failed to list pods: %s&quot;, err)
  71. }
  72. log.Printf(&quot;There are %d pods in the namespace&quot;, len(pods.Items))
  73. }

huangapple
  • 本文由 发表于 2022年4月12日 10:58:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/71836518.html
匿名

发表评论

匿名网友

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

确定