使用Terraform创建GKE集群和名称空间

时间:2020-09-07 18:43:08

标签: kubernetes google-cloud-platform terraform google-kubernetes-engine

我需要创建GKE集群,然后创建名称空间,并通过头盔将db安装到该名称空间。现在,我有了gke-cluster.tf,它使用节点池和helm.tf创建了集群,该集群具有kubernetes提供程序和helm_release资源。它首先创建集群,但随后尝试安装db,但命名空间尚不存在,因此我必须再次运行terraform apply才能工作。我想避免使用多个文件夹的情况,并且只运行一次terraform apply。这样的现场调查有什么好的做法?感谢您的回答。

2 个答案:

答案 0 :(得分:4)

create_namespace资源的helm_release参数可以为您提供帮助。

create_namespace - (Optional) Create the namespace if it does not yet exist. Defaults to false.

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

或者,您可以定义namespace资源和helm_release之间的依赖关系,如下所示:

resource "kubernetes_namespace" "prod" {
  metadata {
    annotations = {
      name = "prod-namespace"
    }

    labels = {
      namespace = "prod"
    }

    name = "prod"
  }
}
resource "helm_release" "arango-crd" { 
  name = "arango-crd" 
  chart = "./kube-arangodb-crd"
  namespace = "prod"  

  depends_on = [ kubernetes_namespace.prod ]
}

答案 1 :(得分:1)

由用户adp发布的解决方案是正确的,但我想就运行命令方面针对此特定示例使用Terraform提供更多见解:

  • $ terraform apply --auto-approve

基于以下评论:

您能告诉您如何创建名称空间吗? kubernetes提供者吗? -戴维德·克鲁克

资源“ kubernetes_namespace”-Jozef Vrana

此设置需要特定的执行顺序。首先是集群,然后是资源。默认情况下,Terraform将尝试同时创建所有资源。使用参数depends_on = [VALUE]至关重要。

下一个问题是kubernetes提供者将在过程开始时尝试从~/.kube/config获取凭据。它不会等待群集配置获得实际的凭据。它可以:

  • 没有.kube/config时失败
  • 获取错误群集的凭据。

有持续的功能请求来解决这种用例(也有一些解决方法):

例如:

# Create cluster
resource "google_container_cluster" "gke-terraform" {
  project = "PROJECT_ID"
  name     = "gke-terraform"
  location = var.zone
  initial_node_count = 1
}

# Get the credentials 
resource "null_resource" "get-credentials" {

 depends_on = [google_container_cluster.gke-terraform] 
 
 provisioner "local-exec" {
   command = "gcloud container clusters get-credentials ${google_container_cluster.gke-terraform.name} --zone=europe-west3-c"
 }
}

# Create a namespace
resource "kubernetes_namespace" "awesome-namespace" {

 depends_on = [null_resource.get-credentials]

 metadata {
   name = "awesome-namespace"
 }
}

假设您之前配置了集群以进行工作,但没有删除它:

  • 已获取Kubernetes集群的凭据。

  • Terraform将创建一个名为gke-terraform

    的集群
  • Terraform将运行本地命令以获取gke-terraform群集的凭据

  • Terraform将创建一个名称空间(使用旧信息):

    • 如果您在.kube/config中配置了另一个集群,它将在该集群中创建一个名称空间(先前的名称)
    • 如果您删除了先前的群集,它将尝试在该群集中创建一个名称空间,并且会失败(上一个)
    • 如果您没有.kube/config,它将一开始就失败

重要!

使用“ helm_release”资源似乎在供应资源时获得了凭据,而不是在一开始!

如前所述,您可以使用helm provider来在群集上置备资源,以避免出现上述问题。

运行单个命令以创建集群并在其上配置资源的示例:

variable zone {
  type = string
  default = "europe-west3-c"
}

resource "google_container_cluster" "gke-terraform" {
  project = "PROJECT_ID"
  name     = "gke-terraform"
  location = var.zone
  initial_node_count = 1
}

data "google_container_cluster" "gke-terraform" { 
  project = "PROJECT_ID"
  name     = "gke-terraform"
  location = var.zone
}

resource "null_resource" "get-credentials" {

 # do not start before resource gke-terraform is provisioned
 depends_on = [google_container_cluster.gke-terraform] 

 provisioner "local-exec" {
   command = "gcloud container clusters get-credentials ${google_container_cluster.gke-terraform.name} --zone=${var.zone}"
 }
}


resource "helm_release" "mydatabase" {
  name  = "mydatabase"
  chart = "stable/mariadb"
  
  # do not start before the get-credentials resource is run 
  depends_on = [null_resource.get-credentials] 

  set {
    name  = "mariadbUser"
    value = "foo"
  }

  set {
    name  = "mariadbPassword"
    value = "qux"
  }
}

使用上述配置将产生:

data.google_container_cluster.gke-terraform: Refreshing state...
google_container_cluster.gke-terraform: Creating...
google_container_cluster.gke-terraform: Still creating... [10s elapsed]
<--OMITTED-->
google_container_cluster.gke-terraform: Still creating... [2m30s elapsed]
google_container_cluster.gke-terraform: Creation complete after 2m38s [id=projects/PROJECT_ID/locations/europe-west3-c/clusters/gke-terraform]
null_resource.get-credentials: Creating...
null_resource.get-credentials: Provisioning with 'local-exec'...
null_resource.get-credentials (local-exec): Executing: ["/bin/sh" "-c" "gcloud container clusters get-credentials gke-terraform --zone=europe-west3-c"]
null_resource.get-credentials (local-exec): Fetching cluster endpoint and auth data.
null_resource.get-credentials (local-exec): kubeconfig entry generated for gke-terraform.
null_resource.get-credentials: Creation complete after 1s [id=4191245626158601026]
helm_release.mydatabase: Creating...
helm_release.mydatabase: Still creating... [10s elapsed]
<--OMITTED-->
helm_release.mydatabase: Still creating... [1m40s elapsed]
helm_release.mydatabase: Creation complete after 1m44s [id=mydatabase]