发布
社区首页 >问答首页 >Terraform:如何使用名称空间在Google (GKE)上创建Kubernetes集群?

Terraform:如何使用名称空间在Google (GKE)上创建Kubernetes集群?
EN

Stack Overflow用户
提问于 2018-04-29 15:36:03
回答 1查看 4.1K关注 0票数 2

我想要的是一个可以做以下事情的例子:

  1. 通过Terraform的google_container_cluster在GKE上创建一个Kubernetes集群
  2. ..。并继续在其中创建名称空间,我想是通过kubernetes_namespace

我不确定的是如何连接新创建的集群和命名空间定义。例如,在添加google_container_node_pool时,我可以做一些类似于cluster = "${google_container_cluster.hosting.name}"的事情,但是对于kubernetes_namespace,我没有看到类似的事情。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-30 16:51:45

理论上,可以在K8S (或任何其他)提供程序中引用来自GCP提供程序的资源,就像在单个提供程序的上下文中引用资源或数据源一样。

代码语言:javascript
代码运行次数:0
复制
provider "google" {
  region = "us-west1"
}

data "google_compute_zones" "available" {}

resource "google_container_cluster" "primary" {
  name = "the-only-marcellus-wallace"
  zone = "${data.google_compute_zones.available.names[0]}"
  initial_node_count = 3

  additional_zones = [
    "${data.google_compute_zones.available.names[1]}"
  ]

  master_auth {
    username = "mr.yoda"
    password = "adoy.rm"
  }

  node_config {
    oauth_scopes = [
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring"
    ]
  }
}

provider "kubernetes" {
  host = "https://${google_container_cluster.primary.endpoint}"
  username = "${google_container_cluster.primary.master_auth.0.username}"
  password = "${google_container_cluster.primary.master_auth.0.password}"
  client_certificate = "${base64decode(google_container_cluster.primary.master_auth.0.client_certificate)}"
  client_key = "${base64decode(google_container_cluster.primary.master_auth.0.client_key)}"
  cluster_ca_certificate = "${base64decode(google_container_cluster.primary.master_auth.0.cluster_ca_certificate)}"
}

resource "kubernetes_namespace" "n" {
  metadata {
    name = "blablah"
  }
}

然而,在实践中,由于已知的核心错误打破了跨提供者依赖关系,它可能无法按预期工作,请分别参见https://github.com/hashicorp/terraform/issues/12393https://github.com/hashicorp/terraform/issues/4149

另一种解决办法是:

  1. 首先使用2阶段的应用程序并对GKE集群进行目标,然后是依赖于它的任何东西,即terraform apply -target=google_container_cluster.primaryterraform apply
  2. 将GKE集群配置从K8S配置中分离出来,给它们完全隔离的工作流,并通过远程状态连接它们。

/terraform-gke/main.tf

代码语言:javascript
代码运行次数:0
复制
terraform {
  backend "gcs" {
    bucket  = "tf-state-prod"
    prefix  = "terraform/state"
  }
}

provider "google" {
  region = "us-west1"
}

data "google_compute_zones" "available" {}

resource "google_container_cluster" "primary" {
  name = "the-only-marcellus-wallace"
  zone = "${data.google_compute_zones.available.names[0]}"
  initial_node_count = 3

  additional_zones = [
    "${data.google_compute_zones.available.names[1]}"
  ]

  master_auth {
    username = "mr.yoda"
    password = "adoy.rm"
  }

  node_config {
    oauth_scopes = [
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring"
    ]
  }
}

output "gke_host" {
  value = "https://${google_container_cluster.primary.endpoint}"
}

output "gke_username" {
  value = "${google_container_cluster.primary.master_auth.0.username}"
}

output "gke_password" {
  value = "${google_container_cluster.primary.master_auth.0.password}"
}

output "gke_client_certificate" {
  value = "${base64decode(google_container_cluster.primary.master_auth.0.client_certificate)}"
}

output "gke_client_key" {
  value = "${base64decode(google_container_cluster.primary.master_auth.0.client_key)}"
}

output "gke_cluster_ca_certificate" {
  value = "${base64decode(google_container_cluster.primary.master_auth.0.cluster_ca_certificate)}"
}

在这里,我们通过output公开了所有必要的配置,并使用后端存储状态,以及在远程位置的这些输出,在本例中是GCS。这使我们能够在下面的配置中引用它。

/terraform-k8s/main.tf

代码语言:javascript
代码运行次数:0
复制
data "terraform_remote_state" "foo" {
  backend = "gcs"
  config {
    bucket  = "tf-state-prod"
    prefix  = "terraform/state"
  }
}

provider "kubernetes" {
  host = "https://${data.terraform_remote_state.foo.gke_host}"
  username = "${data.terraform_remote_state.foo.gke_username}"
  password = "${data.terraform_remote_state.foo.gke_password}"
  client_certificate = "${base64decode(data.terraform_remote_state.foo.gke_client_certificate)}"
  client_key = "${base64decode(data.terraform_remote_state.foo.gke_client_key)}"
  cluster_ca_certificate = "${base64decode(data.terraform_remote_state.foo.gke_cluster_ca_certificate)}"
}

resource "kubernetes_namespace" "n" {
  metadata {
    name = "blablah"
  }
}

这里可能不清楚的是,在创建/更新任何K8S资源之前,必须创建/更新集群(如果这种更新依赖于集群的更新)。

采用第二种方法通常都是可取的(即使错误不是一个因素和跨提供者引用时也是如此),因为它减少了爆炸半径并定义了更明确的责任。这类部署通常有一个人/团队负责管理集群,另一个负责管理K8S资源。

当然,可能会有重叠--例如,操作系统希望在一个新的GKE集群之上部署日志和监视基础设施,因此跨提供者依赖关系旨在满足这样的用例。出于这个原因,我建议订阅上述GH发行。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50088355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档