如何运行kubectl在Terraform中应用命令

时间:2019-01-08 15:05:45

标签: kubernetes terraform google-kubernetes-engine

我开发了一个Terraform脚本来在GKE上创建一个k8集群。

在成功创建集群之后,我已经设置了要应用于k8集群的yaml文件。

如何在terraform脚本中调用以下命令?

kubectl create <.yaml>

6 个答案:

答案 0 :(得分:24)

您可以使用Terraform kubectl第三方提供商。请按照此处的安装说明进行操作:Kubectl Terraform Provider

然后只需定义一个指向您的YAML文件的kubectl_manifest,例如:

# Get your cluster-info
data "google_container_cluster" "my_cluster" {
  name     = "my-cluster"
  location = "us-east1-a"
}

# Same parameters as kubernetes provider
provider "kubectl" {
  load_config_file       = false
  host                   = "https://${data.google_container_cluster.my_cluster.endpoint}"
  token                  = "${data.google_container_cluster.my_cluster.access_token}"
  cluster_ca_certificate = "${base64decode(data.google_container_cluster.my_cluster.master_auth.0.cluster_ca_certificate)}"
}

resource "kubectl_manifest" "my_service" {
    yaml_body = file("${path.module}/my_service.yaml")
}

这种方法的一大优势是,所有内容都是动态获取的,并且不依赖任何本地配置文件(如果您在CI / CD服务器中运行Terraform或管理多集群环境,这非常重要)。

多对象清单文件

kubectl提供程序还提供了有助于轻松处理具有多个目标的文件的数据源。来自文档kubectl_filename_list

data "kubectl_filename_list" "manifests" {
    pattern = "./manifests/*.yaml"
}

resource "kubectl_manifest" "test" {
    count = length(data.kubectl_filename_list.manifests.matches)
    yaml_body = file(element(data.kubectl_filename_list.manifests.matches, count.index))
}

加分:您可以模板化yaml文件。我将集群名称插值到多资源自动缩放器yaml文件中,如下所示:

resource "kubectl_manifest" "autoscaler" {
  yaml_body = templatefile("${path.module}/autoscaler.yaml", {cluster_name = var.cluster_name })
}

答案 1 :(得分:2)

有两种方法可以实现您想要的工作。

您可以使用Terraform资源 template_file null_resource
请注意,我总是使用 trigger 来运行 kubectl 命令,而总是修改模板(您可能希望将create替换为apply)。

data "template_file" "your_template" {
  template = "${file("${path.module}/templates/<.yaml>")}"
}

resource "null_resource" "your_deployment" {
  triggers = {
    manifest_sha1 = "${sha1("${data.template_file.your_template.rendered}")}"
  }

  provisioner "local-exec" {
    command = "kubectl create -f -<<EOF\n${data.template_file.your_template.rendered}\nEOF"
  }
}

但是也许最好的方法是使用Kubernetes provider
有两种配置方法:

  • 默认情况下,清单将部署在当前上下文(kubectl config current-context
  • 第二种方法是静态定义TLS证书凭据:
provider "kubernetes" {
  host = "https://104.196.242.174"

  client_certificate     = "${file("~/.kube/client-cert.pem")}"
  client_key             = "${file("~/.kube/client-key.pem")}"
  cluster_ca_certificate = "${file("~/.kube/cluster-ca-cert.pem")}"
}

完成此操作后,您可以轻松创建自己的部署。对于基本的广告连播,它就像这样简单:

resource "kubernetes_pod" "hello_world" {
  metadata {
    name = "hello-world"
  }

  spec {
    container {
      image = "my_account/hello-world:1.0.0"
      name  = "hello-world"
    }

    image_pull_secrets  {
      name = "docker-hub"
    }
  }
}

答案 2 :(得分:1)

如果远程 url 托管 yaml 文件,并且 yaml 文件包含多个配置/对象,则可以执行以下操作。

resource "null_resource" "controller_rancher_installation" {

  provisioner "local-exec" {
    command = <<EOT
      echo "Downloading rancher config"
      curl -L https://some-url.yaml -o rancherconfig.yaml
    EOT
  }
}

data "kubectl_path_documents" "rancher_manifests" {
    pattern = "./rancherconfig.yaml"
    depends_on = [null_resource.controller_rancher_installation]
}

resource "kubectl_manifest" "spot_cluster_controller" {
    count     = length(data.kubectl_path_documents.spot_controller_manifests.documents)
    yaml_body = element(data.kubectl_path_documents.spot_controller_manifests.documents, count.index)
}

思路是先下载,再应用。这是基于观察:

  1. pattern = "./rancherconfig.yaml" 不支持远程 url,只支持 本地文件。
  2. "kubectl_manifest" 默认只应用第一个 yaml 文件中的配置/对象。

答案 3 :(得分:0)

最好的方法是使用Kubernetes Terraform提供程序

答案 4 :(得分:0)

您可以使用terraform local-exec执行此操作。

   resource "aws_instance" "web" {
     # ...
     provisioner "local-exec" {
      command = "echo ${aws_instance.web.private_ip} >> private_ips.txt"
     }
   }

参考:https://www.terraform.io/docs/provisioners/local-exec.html

答案 5 :(得分:0)

这里的答案很棒。当您的需求从初始清单演变为一个建议时,您可能希望查看从清单(或可能已经存在)创建头盔图表,并使用terraform头盔提供程序来设置环境值。

https://tech.paulcz.net/blog/getting-started-with-helm/

您会注意到,helm provider的一个优点是易于通过地形环境覆盖和管理值的更改,而不是将其嵌入到清单中。

https://registry.terraform.io/providers/hashicorp/helm/latest/docs/resources/release