2

我知道关于 google_container_cluster 的幂等性,Terraform google 提供商的 Github 上有类似的问题;但是,似乎没有一个与我的简单示例相匹配。任何应用 Terraform 计划的尝试都希望破坏并重新创建我的集群,这是一个 6 分钟以上的操作。

集群没有明显的变化,但是terraform状态提示集群的id是集群的名字,但是计算的是新的id;因此,必须重新创建集群。我可以防止这种情况吗?

我正在按照推荐的示例来设置集群:使用remove_initial_node_pool=trueand定义集群initial_node_count=1,然后创建一个显式节点池作为依赖资源。我还尝试使用初始节点池创建默认集群。我没有指定其他人与幂等性问题相关的任何其他属性(例如 master_ipv4_cidr_block)。

这是基本的 Terraform 设置。我正在使用 Terraform v0.11.13 和 provider.google v2.6.0。

provider "google" {
  project     = "${var.google_project}"
  region      = "${var.google_region}"
  zone        = "${var.google_zone}"
}

resource "google_container_cluster" "cluster" {
  project                  = "${var.google_project}"
  name                     = "${var.cluster_name}"
  location                 = "${var.google_region}"

  remove_default_node_pool = true
  initial_node_count       = 1

  master_auth {
    username = ""
    password = ""
  }

  timeouts {
    create = "20m"
    update = "15m"
    delete = "15m"
  }

}

resource "google_container_node_pool" "cluster_nodes" {
  name       = "${var.cluster_name}-node-pool"
  cluster    = "${google_container_cluster.cluster.name}"
  node_count = "${var.cluster_node_count}"

  node_config {
    preemptible  = "${var.preemptible}"
    disk_size_gb = "${var.disk_size_gb}"
    disk_type    = "${var.disk_type}"
    machine_type = "${var.machine_type}"
    oauth_scopes = [
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
      "https://www.googleapis.com/auth/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append",
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/cloud-platform",
    ]
  }

  timeouts {
    create = "20m"
    update = "15m"
    delete = "15m"
  }
}

output "cluster_ca_certificate" {
  value = "${google_container_cluster.cluster.master_auth.0.cluster_ca_certificate}"
}

output "host" {
  value = "${google_container_cluster.cluster.endpoint}"
}

provider "kubernetes" {
  host                   = "${google_container_cluster.cluster.endpoint}"
  client_certificate     = "${base64decode(google_container_cluster.cluster.master_auth.0.client_certificate)}"
  client_key             = "${base64decode(google_container_cluster.cluster.master_auth.0.client_key)}"
  cluster_ca_certificate = "${base64decode(google_container_cluster.cluster.master_auth.0.cluster_ca_certificate)}"
}

等等。未显示用于启用 Helm 服务帐户的服务帐户和集群角色绑定以及 Helm 版本。我不认为这些在这里重要。

如果我做terraform apply两次,第二次调用想要销毁并创建一个新集群。什么都没有改变,所以这不应该发生。
这通常是可以的,除了我倾向于看到来自 terraform 提供程序的大量超时,并且必须重新申请,这让我无处可去,因为重新申请会导致集群被破坏和重新创建。

输出terraform apply如下所示:

terraform-gke$ terraform apply
data.template_file.gke_values: Refreshing state...
google_container_cluster.cluster: Refreshing state... (ID: test-eric)

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
-/+ destroy and then create replacement

Terraform will perform the following actions:

-/+ google_container_cluster.cluster (new resource required)
      id:                                              "test-eric" => <computed> (forces new resource)
      additional_zones.#:                              "3" => <computed>
      addons_config.#:                                 "1" => <computed>
      cluster_autoscaling.#:                           "0" => <computed>
      cluster_ipv4_cidr:                               "10.20.0.0/14" => <computed>
      enable_binary_authorization:                     "" => <computed>
      enable_kubernetes_alpha:                         "false" => "false"
      enable_legacy_abac:                              "false" => "false"
      enable_tpu:                                      "" => <computed>
      endpoint:                                        "34.66.113.0" => <computed>
      initial_node_count:                              "1" => "1"
      instance_group_urls.#:                           "0" => <computed>
      ip_allocation_policy.#:                          "0" => <computed>
      location:                                        "us-central1" => "us-central1"
      logging_service:                                 "logging.googleapis.com" => <computed>
      master_auth.#:                                   "1" => "1"
      master_auth.0.client_certificate:                "" => <computed>
      master_auth.0.client_certificate_config.#:       "1" => "0" (forces new resource)
      master_auth.0.client_key:                        <sensitive> => <computed> (attribute changed)

4

2 回答 2

3

因此,归根结底,这是一个提供程序错误,但它是由 1.11.x 和 1.12.x 版本之间 Kubernetes 主服务的行为变化引起的,谷歌最近推出了 GKE 节点的默认设置。它在 Terraform Google 提供商的 Github 问题中被捕获为#3369

解决方法是告诉 Terraform 忽略master_auth和中的更改network

resource google_container_cluster cluster {
  master_auth {
    username = ""
    password = ""
  }
  # Workaround for issue 3369 (until provider version 3.0.0?)
  # This is necessary when using GKE node version 1.12.x or later.
  # It is possible to make GKE use node version 1.11.x as an
  # alternative workaround.
  lifecycle {
    ignore_changes = [ "master_auth", "network" ]
  }
}

nb,也许是为了帮助其他人解决同样的问题......很难在网络和 Github 等地方搜索此类问题的相关答案,因为作者使用许多不同的术语来描述 Terraform 所展示的那种行为。此问题有时也被描述为 Terraform 幂等性和 Terraform 更改的问题。

于 2019-05-21T13:46:18.583 回答
0

您似乎已从基本(用户名/密码)切换到 TLS 授权,因为根据您的日志,您生成了新证书并强制使用新集群。

于 2019-05-20T21:10:13.333 回答