Экспорт вашего кластера GKE в Terraform Cloud: руководство с проблемами и решениями

Экспорт вашего кластера GKE в Terraform Cloud: руководство с проблемами и решениями

10 февраля 2023 г.

Всем привет. В этой статье я расскажу о нашем пути в ANNA Money от использования нашей установки Kubernetes в GCP до управляемого сервиса Kubernetes от Google и GKE. Первоначально мы перенесли наши тестовые среды через веб-консоль GCP, что было легко, но не воспроизводимо. Перед переносом нашей производственной среды мы осознали важность следования принципу IaC Infrastructure-as-Code и документирования нашей настройки с помощью кода.

Нам нужно было решить следующие проблемы:

  1. Было обеспечено, чтобы существующий кластер GKE не был сломан или отключен во время процесса.
  2. Создание точной копии кластера идемпотентным способом, который можно было бы легко повторить.

Доступны следующие варианты: использовать модуль Ansible или Terraform для описания кластера.

Выбор основывался на личных предпочтениях, и Terraform был выбран по двум причинам:

  1. Использование Terraform Cloud для управления различными средами;
  2. Инструмент Terraform CLI, который позволяет экспортировать существующие конфигурации GCP в файлы Terraform (включая не только GKE, но и сети, DNS и другие).

Первоначально конфигурация тестового кластера GKE была экспортирована с помощью Terraformer с помощью следующей простой команды:

terraformer import google --resources=gke --connect=true --regions=${REGION_GKE_CLUSTER} --projects=${PROJECT_ID}

<цитата>

По умолчанию интерфейс командной строки Terraformer создает папки для каждой экспортируемой службы по пути /generated/{provider}/{service}. Однако у вас есть возможность изменить структуру файлов с помощью параметров командной строки или переместить файлы в другое место.

==Если вы новичок в Terraform, вам необходимо загрузить соответствующий подключаемый модуль для вашего провайдера и поместить его в нужное место:==

$HOME/.terraform.d/plugins/darwin_amd64

После импорта мы должны получить такую ​​структуру файлов и папок:

terraform
└── test
    ├── backend.tf
    ├── container_cluster.tf
    ├── container_node_pool.tf
    ├── output.tf
    └── provider.tf

После процесса экспорта использовалась локальная серверная часть, и был создан файл terraform.tfstate для хранения текущего состояния кластера GKE. Спецификации кластера хранились в файле container_cluster.tf, а информация о пуле узлов — в файле container_node_pool.tf.

Для локальной проверки экспортированной конфигурации использовалась команда terraform plan, а с помощью команды apply были внесены небольшие изменения, которые были успешно реализованы. Поскольку проблем не возникло, конфигурация была запущена в облаке с помощью веб-консоли Terraform Cloud. Создано новое рабочее пространство, а экспортированная конфигурация связана с репозиторием GitHub.

<цитата>

Рабочие пространства полезны для организации инфраструктуры, подобно конфигурациям сборки в CI. Они содержат конфигурацию Terraform, значения переменных, секреты, историю выполнения и информацию о состоянии.

Мы обновили файл provider.tf, чтобы передавать переменные секретов через движок Terraform Cloud, и добавили секреты в рабочую область:

variable "google_service_account" {}

terraform {
  required_providers {
    google = {
      source      = "hashicorp/google"
      version     = ">=4.51.0"
    }
  }
}

provider "google" {
  project     = "{{YOUR GCP PROJECT}}"
  credentials = "${var.google_service_account}"
  region      = "us-central1"
  zone        = "us-central1-c"
}

К сожалению, произошла случайная утечка конфиденциальных данных, когда код был отправлен в целевой репозиторий в папке ./gke/test. Утечка была обнаружена в файле состояния Terraform, где свойство master_auth.0.cluster_ca_certificate содержало закодированный сертификат. Чтобы решить эту проблему, файл состояния был удален, была сделана принудительная отправка, и в будущем были предприняты дополнительные меры предосторожности.

Новая проблема возникла после удаления файла состояния. Terraform Cloud разработал план воссоздания существующего кластера, вместо того, чтобы признать его существование. Это показало, что простого переноса существующей конфигурации в облако недостаточно, и сначала необходимо перенести серверную часть.

Чтобы выполнить миграцию, были предприняты следующие шаги:

  1. Создайте токен пользователя API;
  2. Создайте файл ./terraformrc в домашнем каталоге пользователя и заполните его следующим образом.

javascript учетные данные "app.terraform.io" { токен = "{{ токен }}" 3. Измените конфигурацию серверной части с локальной на удаленную.

javascript терраформировать { бэкэнд "удаленный" { имя хоста = "app.terraform.io" организация = {{ORG_NAME_IN_TERRAFORM_CLOUD }} рабочие области { имя = "gke-тест" } } 4. И запустите команду terraform init, чтобы передать состояние в облако.

<цитата>

Внимание! Если вы запускаете план в удаленной рабочей области, рекомендуется пересоздать рабочую область перед инициализацией из-за возможности ошибок с неправильным сохранением состояния

После того, как шаги были выполнены правильно, результатом стал план без каких-либо изменений:

Plan: 0 to add, 0 to change, 0 to destroy.

Кроме того, могут быть небольшие изменения, но эти изменения не должны влиять на существующий кластер:

+ min_master_version      = "1.24.8-gke.401"

Для нас было крайне важно не нарушить работу тестовых сред, поэтому мы позаботились о том, чтобы внесенные изменения не вызвали никаких проблем.

На вкладке состояния присутствовали два состояния: исходное состояние и состояние после первого плана в очереди:

First state in Terraform Cloud run tab

На вкладке запуска была доступна полная история выполнения:

Terraform Cloud complete execution history tab

В качестве бонуса проверки GitHub были интегрированы с запросами на вытягивание (PR):

Github Actions with terraform cloud status

Кроме того, нажав на ссылку Подробности, мы смогли просмотреть ожидаемый план и убедиться, что все идет так, как мы планировали:

Впоследствии мы создали кластер GKE для внутренней инфраструктуры с помощью Terraform, минуя пользовательский интерфейс GCP. Как обсуждалось ранее, нашей целью было программное управление нашей инфраструктурой. Для этого мы создали еще одну папку в нашем репозитории GitHub, скопировали и изменили конфигурацию из тестового кластера и создали новую рабочую область в Terraform Cloud. Рабочая область была правильно настроена путем указания соответствующей папки в настройках рабочей области.

Далее мы настроим папку на автоматическое действие триггера VCS:

Мы попытались составить план и выполнить его, однако все пошло не так гладко, как мы надеялись. Обнаружена ошибка:

Error: error creating NodePool: googleapi: Error 409: Already exists

on container_node_pool.tf line 1, in resource "google_container_node_pool" "anna-prod_default-pool":
   1: resource "google_container_node_pool" "anna-prod_default-pool" {

После открытия консоли Google Cloud Platform мы обнаружили, что пул по умолчанию был успешно создан. Мы попытались решить проблему, удалив кластер и создав его заново, но это не сработало. Мы даже пытались удалить пул узлов вручную, но безуспешно. Похоже, мы допустили ошибку, полагаясь на нашу предыдущую успешную конфигурацию вместо того, чтобы проконсультироваться с официальная документация. Это привело к нашим трудностям, которые очень интересно объяснялись в документации.

# We can't create a cluster with no node pool defined, 
# but we want to only use
# separately managed node pools. 
# So we create the smallest possible default
# node pool and immediately delete it.
remove_default_node_pool = true
initial_node_count = 1

Мы попробовали другой подход и решили не определять пул узлов по умолчанию, вместо этого используя свойства в конфигурации кластера. Это решение сработало для нас.

Чтобы улучшить ситуацию, мы настроили интеграцию со Slack через облачную веб-консоль и начали получать уведомления.

Terraform Cloud slack notify configuration

И начали получать уведомления:

Example notification in Slack from Terraform Cloud


Что мы сделали?

Мы использовали интерфейс командной строки Terraformer для экспорта существующей конфигурации GKE. Затем мы очистили и проверили экспортированную конфигурацию, создали рабочее пространство в Terraform Cloud, настроили его, переместили в него состояние и настроили интеграцию с GitHub и Slack. Мы позаботились о том, чтобы не сломать существующий кластер при тестировании более значительных изменений. Мы определили новый кластер в другом рабочем пространстве в рамках того же проекта GitHub и устранили проблемы, создав его через Terraform, а не через веб-консоль.

Что мы наконец получили?

В результате теперь у нас есть инфраструктура в виде кода для наших кластеров GKE и бесплатное удобное облачное решение для нашей небольшой команды. Внесение изменений в инфраструктуру теперь безопасно, надежно и предсказуемо.

Что сейчас холодно?

Однако существуют ограничения в уведомлениях на уровне организации в Terraform Cloud. Мы должны рассмотреть возможность упрощения процесса, например перенести конфигурацию сети GCP в Terraform.


Оригинал