diff --git a/README.md b/README.md index 264dde0..cd71c90 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ > ## Внимание: рабочая папка одна > > Для работы используйте **только** [`fullpipe_chain`](fullpipe_chain/) — это пример -> «vDC → Edge → внешние IP → SNAT». Он прогнан на живом стенде (создание и удаление) +> «vDC → Edge → внешние IP → SNAT → Штурвал». Он повторяет рабочую конфигурацию +> стенда (создание, «заморозка» при удалении, усыновление существующих услуг) > и снабжён пошаговой инструкцией. > > Остальные папки репозитория — черновики: могут быть сырыми, содержать неактуальные @@ -18,7 +19,7 @@ git clone https://gitea.services.ngcloud.ru/Nail/tf_examples.git cd tf_examples/fullpipe_chain cp terraform.tfvars.example terraform.tfvars # заполнить значениями из ЛК terraform init -terraform plan # покажет 4 ресурса, ничего не меняет +terraform plan # покажет 5 ресурсов, ничего не меняет terraform apply # подтвердить: yes ``` diff --git a/fullpipe_chain/README.md b/fullpipe_chain/README.md index 6fa4910..e9555f3 100644 --- a/fullpipe_chain/README.md +++ b/fullpipe_chain/README.md @@ -1,14 +1,16 @@ -# vDC → Edge → внешние IP → SNAT +# vDC → Edge → внешние IP → SNAT → Штурвал -Пример поднимает сетевую основу в Nubes: +Пример поднимает всю цепочку в Nubes: - виртуальный датацентр (vDC); -- сетевой шлюз периметра (Edge); +- сетевой шлюз периметра (Edge) с балансировщиком AVI; - внешние IP на организации; -- SNAT на шлюзе. +- SNAT на шлюзе; +- Kubernetes-кластер Штурвал (сервис 150) на этой сети. -Кластер Штурвал сюда **не входит** — он разворачивается долго, отдельным шагом. Организацию создайте заранее в ЛК: Terraform её не создаёт и не удаляет. +Файлы примера повторяют рабочую конфигурацию стенда, включая флаги «заморозки» +при удалении (см. шаг 6) и усыновление уже существующих услуг по имени. **Перед началом:** нужен установленный Terraform 1.5 или новее. Провайдер скачается сам при `terraform init` — отдельно ставить ничего не нужно. @@ -46,7 +48,7 @@ nano terraform.tfvars # подставьте значения из шага ```bash terraform init # один раз — скачает провайдер -terraform plan # покажет, что будет создано (4 ресурса), ничего не меняет +terraform plan # покажет, что будет создано (5 ресурсов), ничего не меняет terraform apply # создаст (подтвердить: yes) ``` @@ -56,8 +58,13 @@ terraform apply # создаст (подтвердить: yes) terraform output # UUID и имена созданных услуг ``` -И в ЛК: появились vDC и Edge, на организации выделены внешние IP, на шлюзе включён SNAT. -Повторный `terraform plan` должен показать `No changes`. +И в ЛК: появились vDC, Edge и кластер Штурвал, на организации выделены внешние IP, +на шлюзе включён SNAT. Повторный `terraform plan` должен показать `No changes`. + +Кластер Штурвала создаётся десятки минут — провайдер ждёт его +(`operation_timeout = "60m"`), а в ЛК он появится со статусом `running`. +Адреса Kubernetes API и Ingress — в `terraform output shturval_state_params` +(поля `kubernetesApiAddress` и `ingressAddress`). ## 6. Удаление @@ -65,9 +72,23 @@ terraform output # UUID и имена созданных услуг terraform destroy ``` -Порядок обратный: SNAT выключается, квота внешних IP обнуляется, затем удаляется шлюз, -а vDC приостанавливается (данные сохраняются). -**Организация не удаляется.** +По умолчанию пример настроен на «заморозку»: ничего не удаляется из облака. + +| Ресурс | Что делает `destroy` | Флаг | +|---|---|---| +| Кластер Штурвал | `suspend`: кластер выключается, данные сохраняются | `suspend_on_destroy = true` | +| vDC | `suspend` | `suspend_on_destroy = true` | +| Edge | не трогается: у эджа нет операции `suspend` | `keep_on_destroy = true` | +| SNAT | не выключается | `keep_on_destroy = true` | +| Квота внешних IP | не меняется: адреса держит кластер | `keep_on_destroy = true` | + +Следующий `terraform apply` усыновит объекты по имени и разморозит кластер и vDC +(`adopt_existing_on_create = true` → `resume`). +**Организация не удаляется никогда.** + +Полное удаление — осознанно: выставьте `keep_on_destroy = false` и +`suspend_on_destroy = false`, порядок — кластер → `count = 0` → SNAT → Edge → vDC +(vDC удаляется только через 14 дней после `suspend`). ## Состав файлов @@ -79,7 +100,8 @@ terraform destroy | `vdc.tf` | виртуальный датацентр | | `edge.tf` | сетевой шлюз периметра (Edge) | | `modifiers.tf` | внешние IP на организации + SNAT на шлюзе | -| `outputs.tf` | UUID и имена созданных услуг | +| `shturval.tf` | Kubernetes-кластер Штурвал: переменные Штурвала, группы воркеров и сам ресурс | +| `outputs.tf` | UUID и имена созданных услуг (vDC, Edge, Штурвал) | | `terraform.tfvars.example` | шаблон значений (копируется в `terraform.tfvars`) | `terraform.tfvars` с токеном никому не передавайте и не коммитьте в git. diff --git a/fullpipe_chain/edge.tf b/fullpipe_chain/edge.tf index 4e22f03..23c7e5e 100644 --- a/fullpipe_chain/edge.tf +++ b/fullpipe_chain/edge.tf @@ -20,4 +20,13 @@ resource "nubes_vc_nsxt" "edge" { main_dns = var.nsxt_main_dns second_dns = var.nsxt_second_dns } + + # «Заморозка»: destroy НЕ удаляет эдж (у платформы для эджа нет операции + # suspend), а только убирает его из состояния. Для полного удаления — + # keep_on_destroy = false (и только когда нет зависимых: vApp, ВМ, кластер). + keep_on_destroy = true + + # Повторный apply усыновляет уже работающий эдж, а не падает с + # «РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (RUNNING)». + adopt_existing_on_create = true } diff --git a/fullpipe_chain/modifiers.tf b/fullpipe_chain/modifiers.tf index 6757f42..c215c2a 100644 --- a/fullpipe_chain/modifiers.tf +++ b/fullpipe_chain/modifiers.tf @@ -27,8 +27,10 @@ resource "nubes_vc_org_ip_allocation" "org_ip" { } ]) - # при destroy: false — квота обнуляется (count=0); true — оставить как есть - keep_on_destroy = false + # «Заморозка»: destroy не трогает квоту внешних IP (кластер Штурвала держит + # адреса, опустить count ниже занятых платформа не даёт). Для полного удаления — false + # (и только после удаления кластера). + keep_on_destroy = true depends_on = [nubes_vc_nsxt.edge] } @@ -39,8 +41,8 @@ resource "nubes_vc_nsxt_snat" "snat" { nsxt_uid = nubes_vc_nsxt.edge.id ip_space_name = var.ip_space_name - # при destroy: false — SNAT выключается (no-needed); true — оставить как есть - keep_on_destroy = false + # «Заморозка»: destroy не выключает SNAT на эдже. Для полного удаления — false. + keep_on_destroy = true # ipSpace должен быть уже выделен на организации depends_on = [nubes_vc_org_ip_allocation.org_ip] diff --git a/fullpipe_chain/outputs.tf b/fullpipe_chain/outputs.tf index d2fcf4b..a8e05da 100644 --- a/fullpipe_chain/outputs.tf +++ b/fullpipe_chain/outputs.tf @@ -30,3 +30,20 @@ output "nsxt_state_params" { description = "Параметры Edge из API (что реально создалось)" value = nubes_vc_nsxt.edge.state_params } + +# --- Штурвал (Kubernetes-кластер, сервис 150) --- + +output "shturval_id" { + description = "UUID созданного кластера Штурвал" + value = nubes_k8s_sthutrval_cluster.shturval.id +} + +output "shturval_name" { + description = "Имя услуги «Kubernetes кластер Штурвал» в ЛК" + value = nubes_k8s_sthutrval_cluster.shturval.resource_name +} + +output "shturval_state_params" { + description = "Параметры кластера из API: адрес Kubernetes API и адрес Ingress — в полях kubernetesApiAddress и ingressAddress" + value = nubes_k8s_sthutrval_cluster.shturval.state_params +} diff --git a/fullpipe_chain/shturval.tf b/fullpipe_chain/shturval.tf new file mode 100644 index 0000000..3547c25 --- /dev/null +++ b/fullpipe_chain/shturval.tf @@ -0,0 +1,168 @@ +# ============================================================================= +# Kubernetes кластер Штурвал — сервис 150, ресурс nubes_k8s_sthutrval_cluster +# (НЕ 148 «Менеджмент Kubernetes кластер Штурвал» — это другой сервис) +# +# Всё, что относится к Штурвалу, лежит ТОЛЬКО в этом файле: переменные, их +# значения по умолчанию и сам ресурс. Чтобы выключить Штурвал — удалить этот +# файл (или закомментировать ресурс). +# +# Значения ниже менять не обязательно: у каждой переменной есть рабочий +# default. Если нужно другое — впишите свою строку `shturval_... = ...` +# в terraform.tfvars (он перекрывает default, см. terraform.tfvars.example). +# +# Порядок (чек-лист из инструкции на услугу в ЛК): +# 1) Организация в Cloud Director — создана вручную в ЛК +# 2) nubes_vc_vdc.vdc — есть (vdc.tf) +# 3) nubes_vc_nsxt.edge — есть, обязательно ALB + AVI VS >= 3 (edge.tf) +# 4) внешние адреса в организации — суммарно >= 3 (modifiers.tf) +# 5) SNAT на Edge — nubes_vc_nsxt_snat (modifiers.tf) +# 6) Kubernetes кластер Штурвал — этот ресурс +# +# Без готовой сети кластер не поднимется: он ходит наружу через SNAT и берёт +# внешние адреса из квоты организации. +# +# Минимальные требования к кластеру: мастер-нод >= 1, воркер-нод >= 1, +# 4 vCPU / 8 GB RAM / 50 GB диска на ноду. +# ============================================================================= + +# --- Переменные Штурвала --- + +variable "shturval_resource_name" { + type = string + default = "shturval-dev" + description = "Имя услуги «Kubernetes кластер Штурвал» в ЛК" +} + +variable "shturval_cluster_name" { + type = string + default = "shturval-dev-00" + description = "Имя кластера внутри Штурвала" +} + +variable "shturval_app_version" { + type = string + default = "2.14.0" + description = "Версия Штурвала (значение по умолчанию платформы — 2.14.0)" +} + +variable "shturval_cp_sizing_policy" { + type = string + default = "TKG 4CPU 8RAM" + description = "Политика размера control plane: 4 vCPU / 8 GB (минимум по инструкции). Должна существовать в ресурсной платформе vDC — список политик берётся из услуги «Виртуальный датацентр»" +} + +variable "shturval_cp_sizing_disk" { + type = number + default = 50 + description = "Диск control plane, ГБ (минимум 50)" +} + +variable "shturval_cp_count" { + type = number + default = 1 + description = "Количество мастер-нод: 1, 3 или 5" +} + +variable "shturval_worker_group_name" { + type = string + default = "workers-shturval-dev" + description = "Имя группы воркеров (уникальное в кластере; допустимы строчные латинские буквы, цифры и дефис)" +} + +variable "shturval_worker_sizing_policy" { + type = string + default = "TKG 4CPU 8RAM" + description = "Политика размера воркеров: 4 vCPU / 8 GB (минимум по инструкции)" +} + +variable "shturval_worker_sizing_disk" { + type = number + default = 50 + description = "Диск воркеров, ГБ (минимум 50)" +} + +variable "shturval_worker_count" { + type = number + default = 1 + description = "Количество воркер-нод (минимум 1)" +} + +# --- Значения, которые собираются из переменных --- + +locals { + # Группы воркеров передаются JSON-строкой ВНУТРЬ услуги как есть, поэтому ключи + # должны быть ровно такими, как в манифесте услуги 150: groupName, sizingPolicy, + # sizingDisk, count, autoscale, labelDeck. + # ВНИМАНИЕ: в сгенерированном примере провайдера (docs → Example) ключи показаны + # в snake_case — это ошибка генератора, платформа на них падает с + # «Cannot invoke method split() on null object» (не находит groupName → null). + shturval_worker_config = jsonencode([ + { + groupName = var.shturval_worker_group_name + sizingPolicy = var.shturval_worker_sizing_policy + sizingDisk = var.shturval_worker_sizing_disk + count = var.shturval_worker_count + autoscale = false # автоскейл выключен + labelDeck = true # разрешить разворачивать услуги из ЛК на этих нодах + } + ]) +} + +# --- Ресурс Штурвала --- + +resource "nubes_k8s_sthutrval_cluster" "shturval" { + resource_name = var.shturval_resource_name + + # Кластер Штурвала живёт в облаке неделями и не пересоздаётся: ресурс должен + # УСЫНОВИТЬ существующий инстанс по имени, а не падать с + # «РЕСУРС С ТАКИМ ИМЕНЕМ УЖЕ СУЩЕСТВУЕТ (RUNNING/SUSPEND)». + # Проверка/adopt выполняются в Create на apply (в plan будет «will be created»). + adopt_existing_on_create = true + + # «Заморозка»: destroy приостанавливает кластер (suspend), а не удаляет. + # Следующий apply усыновит его и разморозит (resume). + suspend_on_destroy = true + + # Штурвал создаётся долго (десятки минут) — поднимаем таймаут ожидания, + # иначе провайдер сдаётся на дефолтных 600 с. + operation_timeout = "60m" + + startup_configuration = { + # vDC и Edge из этого же конфига (обязательные поля) + vdc_uid = nubes_vc_vdc.vdc.id + nsxt_uid = nubes_vc_nsxt.edge.id + + cluster_name = var.shturval_cluster_name + + # Дополнительные возможности кластера (в ЛК — галочки при создании) + ex_logging = true # логи в Loki (без него логи услуг не видны в ЛК) + ex_monitoring = true # метрики в VictoriaMetrics (без него метрик в ЛК нет) + ex_local_csi = true + ex_vip = true + ex_update = true + ex_ingress = true + ex_named_csi = true + } + + cluster_configuration = { + app_version = var.shturval_app_version + } + + control_plane_configuration = { + sizing_policy = var.shturval_cp_sizing_policy + sizing_disk = var.shturval_cp_sizing_disk + count = var.shturval_cp_count + } + + worker_configuration = local.shturval_worker_config + + access_configuration = { + need_external_address_api = true # внешний адрес для Kubernetes API (false недопустим) + access_ip_list_api = jsonencode([]) # пусто = доступ всем + need_external_address_ingress = true # внешний адрес для Ingress + access_ip_list_ingress = jsonencode([]) # пусто = доступ всем + } + + # Кластер поднимается только после готовой сети: vDC -> Edge -> внешние IP -> SNAT + depends_on = [nubes_vc_nsxt_snat.snat] +} diff --git a/fullpipe_chain/terraform.tfvars.example b/fullpipe_chain/terraform.tfvars.example index 4c6f6e0..5cdd82d 100644 --- a/fullpipe_chain/terraform.tfvars.example +++ b/fullpipe_chain/terraform.tfvars.example @@ -51,3 +51,21 @@ nsxt_ip_addr_pool = "10.10.102.0/24" # DNS для машин за шлюзом. nsxt_main_dns = "81.22.46.22" nsxt_second_dns = "185.247.187.77" + +# --- Штурвал (Kubernetes-кластер, сервис 150) --- +# +# Все настройки Штурвала лежат в shturval.tf, у каждой переменной есть рабочий +# default — можно ничего не писать здесь, кластер поднимется с ними. +# Строки ниже — тот же набор значений для наглядности: раскомментируйте ту, +# которую надо поменять. +# +# shturval_resource_name = "shturval-dev" # имя услуги в ЛК +# shturval_cluster_name = "shturval-dev-00" # имя кластера внутри Штурвала +# shturval_app_version = "2.14.0" # версия Штурвала +# shturval_cp_sizing_policy = "TKG 4CPU 8RAM" # минимум 4 vCPU / 8 ГБ +# shturval_cp_sizing_disk = 50 # ГБ, минимум 50 +# shturval_cp_count = 1 # мастер-нод: 1, 3 или 5 +# shturval_worker_group_name = "workers-shturval-dev" # строчные буквы, цифры, дефис +# shturval_worker_sizing_policy = "TKG 4CPU 8RAM" # минимум 4 vCPU / 8 ГБ +# shturval_worker_sizing_disk = 50 # ГБ, минимум 50 +# shturval_worker_count = 1 # воркер-нод, минимум 1 diff --git a/fullpipe_chain/versions.tf b/fullpipe_chain/versions.tf index 193f90d..0aa9250 100644 --- a/fullpipe_chain/versions.tf +++ b/fullpipe_chain/versions.tf @@ -6,7 +6,7 @@ terraform { required_providers { nubes = { source = "tf-registry.containerk8s.services.ngcloud.ru/nubes-dev/nubes" - version = "2.0.21" + version = "2.0.23" } } }