Создание кластера GKE и пространства имен с помощью Terraform

#kubernetes #google-cloud-platform #terraform #google-kubernetes-engine

#kubernetes #google-облачная платформа #terraform #google-kubernetes-engine

Вопрос:

Мне нужно создать кластер GKE, а затем создать пространство имен и установить db через helm в это пространство имен. Теперь у меня есть gke-cluster.tf это создает кластер с пулом узлов и helm.tf , в котором есть поставщик kubernetes и ресурс helm_release. Сначала он создает кластер, но затем пытается установить db, но пространство имен еще не существует, поэтому мне приходится запускать terraform apply снова, и это работает. Я хочу избежать сценария с несколькими папками и запустить terraform apply только один раз. Какова хорошая практика для подобной ситуации? Спасибо за ответы.

Комментарии:

1. Можете ли вы рассказать, как вы создаете свое пространство имен? Связано ли это с kubernetes провайдером?

2. Ресурс @DawidKruk «Пространство имен kubernetes_name»

Ответ №1:

create_namespace Аргумент helm_release resource может вам помочь.

 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. Я получаю эту ошибку. ресурс «helm_release» «arango-crd» { name = «arango-crd» chart = » github.com/arangodb/kube-arangodb/releases/download/1.0.3 /… » create_namespace = true namespace = «prod» } Аргумент с именем «create_namespace» здесь не ожидается.

2. Я протестировал локальную диаграмму с minikube, и она работает. ресурс «helm_release» «arango-crd» { name = «arango-crd» chart = «./kube-arangodb-crd» create_namespace = true namespace = «prod» } Возможно, проблема связана с используемой вами версией TF. Моя версия TF: v0.13.0

Ответ №2:

Решение, опубликованное пользователем adp, правильное, но я хотел бы дать больше информации об использовании Terraform для этого конкретного примера в отношении выполнения одной команды:

  • $ terraform apply --auto-approve .

Основываясь на следующих комментариях:

Можете ли вы рассказать, как вы создаете свое пространство имен? Связано ли это с поставщиком kubernetes? — Давид Крук

ресурс «kubernetes_namespace» — Йозеф Врана

Для этой настройки требуется определенный порядок выполнения. Сначала кластер, затем ресурсы. По умолчанию 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]