Terraform: Как создать кластер Kubernetes в Google Cloud (GKE) с пространствами имен? - PullRequest
0 голосов
/ 29 апреля 2018

Я приведу пример, который будет делать следующее:

  1. Создание кластера Kubernetes на GKE через Terraform google_container_cluster
  2. ... и продолжить создание в ней пространств имен, я полагаю, через kubernetes_namespace

В чем я не уверен, так это в том, как связать вновь созданный кластер и определение пространства имен. Например, при добавлении google_container_node_pool я могу сделать что-то вроде cluster = "${google_container_cluster.hosting.name}", но я не вижу ничего похожего для kubernetes_namespace.

1 Ответ

0 голосов
/ 30 апреля 2018

Теоретически можно ссылаться на ресурсы от провайдера GCP в K8S (или любом другом) провайдере так же, как вы ссылаетесь на ресурсы или источники данных в контексте одного провайдера.

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/12393 и https://github.com/hashicorp/terraform/issues/4149 соответственно.

Альтернативное решение будет:

  1. Используйте 2-ступенчатое применение и цель сначала кластер GKE, затем все, что от него зависит, то есть terraform apply -target=google_container_cluster.primary, а затем terraform apply
  2. Отделение конфигурации кластера GKE от конфигураций K8S, предоставление им полностью изолированного рабочего процесса и подключение их через удаленное состояние .

/terraform-gke/main.tf

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 s и используем backend для сохранения состояния вместе с этими выходами в удаленном местоположении, GCS в этом случае. Это позволяет нам ссылаться на него в конфигурации ниже.

/terraform-k8s/main.tf

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 (если такое обновление зависит от обновлений кластера).


Выбор 2-го подхода обычно целесообразен в любом случае (даже если / если ошибка не была фактором и сработали ссылки между поставщиками), так как он уменьшает радиус взрыва и определяет более четкую ответственность. Для такого развертывания (IMO) характерно, что один человек / группа отвечает за управление кластером, а другой - за управление ресурсами K8S.

Хотя, безусловно, могут быть совпадения - например, Операторы хотят развернуть инфраструктуру ведения журналов и мониторинга поверх нового кластера GKE, поэтому зависимости между поставщиками направлены на удовлетворение таких случаев использования. По этой причине я бы рекомендовал подписаться на проблемы GH, упомянутые выше.

...