【问题标题】:How can a Terraform private provider obtain the kubeconfig of a GKE clusterTerraform 私有提供者如何获取 GKE 集群的 kubeconfig
【发布时间】:2021-11-06 11:09:51
【问题描述】:

我有一个 Terraform 脚本,它通过 google_container_cluster 创建一个 GKE 集群。我还开发了一个私有提供程序,我希望私有提供程序在新集群上调用kubectl。它需要新集群的kubeconfig

获取kubeconfig 的手动方法是调用gcloud container clusters get-credentials。私有提供者可以外壳这个命令。但我宁愿不要打扰本地 CLI 状态。

google_container_cluster 的集群凭据如何传递给我的私有提供商?

【问题讨论】:

    标签: terraform terraform-provider-gcp


    【解决方案1】:

    我找到了一个方法,不知道是不是最好的。

    首先,Terraform 传递它所拥有的关于集群的知识:

    # config
    locals {
      project_id = "my_gcp_project_id"
      region = "us-east4"
    }
    
    # local client token
    data "google_client_config" "client" {}
    
    # the cluster
    data "google_container_cluster" "my_cluster" {
      name     = "my-cluster-name"
      project  = local.project_id
      location = local.region
    }
    
    # send it into the private provider
    data "my-provider-name_the_data_source" "my_provider_data_resource" {
      token = data.google_client_config.client.access_token
      server = "https://${data.google_container_cluster.my_cluster.endpoint}"
      cluster_path = "gke_${local.project_id}_${local.region}_${data.google_container_cluster.my_cluster.name}"
      ca = data.google_container_cluster.my_cluster.master_auth.0.cluster_ca_certificate
    }
    
    

    然后在私有提供者内部,它可以调用kubectl

    func execKubectl(cluster_path string, server string, token string, caBase64 string, kubectlArgs ...string) ([]byte, error) {
        tmpFile, err := ioutil.TempFile(".terraform", "gke")
        if err != nil {
            return nil, err
        }
        defer os.Remove(tmpFile.Name())
    
        caPem, err := base64.StdEncoding.DecodeString(caBase64)
        if err != nil {
            return nil, err
        }
    
        _, err = tmpFile.Write(caPem)
        if err != nil {
            return nil, err
        }
    
        err = tmpFile.Close()
        if err != nil {
            return nil, err
        }
    
        tmpPath, err := filepath.Abs(tmpFile.Name())
        if err != nil {
            return nil, err
        }
    
        allArgs := append([]string{"--certificate-authority=" + tmpPath, "--server=" + server, "--cluster=" + cluster_path, "--token=" + token}, kubectlArgs...)
        cmd := exec.Command("kubectl", allArgs...)
        output, err := cmd.Output()
        if err != nil {
            return nil, err
        }
    
      return output, nil
    }
    

    【讨论】:

    • 我发现的另一种方法是使用get-credentialsgcloud 进行shell,并将KUBECONFIG 环境变量设置为指向临时文件;然后kubectl --kubeconfig=${KUBECONFIG} 工作。这不会干扰默认的.kube/config,它可能更可靠,但速度较慢。
    • 我将集群设置移动到Provider() 以避免跨数据/资源重复。它运作良好。 (他们必须是Optional: true
    猜你喜欢
    • 2021-05-24
    • 2021-05-01
    • 2020-07-24
    • 2019-12-24
    • 2020-01-30
    • 1970-01-01
    • 2020-05-04
    • 2020-08-16
    • 2019-07-08
    相关资源
    最近更新 更多