Балансировщик нагрузки: Application Load Balancer в Yandex Cloud

Рейтинг: 52.3% · 11 голосов
Подробный курс по Terraform и OpenTofu на примерах Yandex Cloud: ресурсы и провайдеры, состояние и бэкенды, модули, циклы и условия HCL, секреты и Lockbox, тестирование, CI/CD и командная работа. С актуализацией на 2026 (Terraform 1.3-1.10, OpenTofu).
Ответить
Аватара пользователя
Vlad_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Балансировщик нагрузки: Application Load Balancer в Yandex Cloud

Сообщение Vlad_DevOps »

Оглавление курса (47)
  1. Что такое инфраструктура как код и зачем она нужна
  2. Категории инструментов IaC: чем отличаются Ansible, Packer, Kubernetes и Terraform
  3. Чем Terraform отличается от Ansible, Pulumi и CloudFormation
  4. Как работает Terraform под капотом и кто такой OpenTofu
  5. Установка Terraform и OpenTofu, подготовка Yandex Cloud
  6. Первый ресурс: разворачиваем виртуальную машину в Yandex Cloud
  7. Веб-сервер на ВМ: метаданные, user-data и группы безопасности
  8. Переменные ввода и выходные значения в Terraform
  9. Кластер ВМ: группа экземпляров Yandex Compute Instance Group
  10. Балансировщик нагрузки: Application Load Balancer в Yandex Cloud (вы здесь)
  11. Состояние Terraform: что такое tfstate и чем опасен локальный файл
  12. Удалённое хранилище состояния: бэкенд на Yandex Object Storage
  13. Изоляция состояния: рабочие области против раскладки по папкам
  14. Источники данных и terraform_remote_state: связываем компоненты
  15. Модули Terraform: переиспользуем инфраструктуру
  16. Входные, локальные и выходные переменные модуля
  17. Версионирование модулей и подводные камни
  18. Циклы в Terraform: параметр count
  19. Циклы в Terraform: for_each по множествам и картам
  20. Выражения for и строковые директивы
  21. Условная логика: count-трюк, for_each и директива if
  22. Встроенные функции, типы и выражения HCL
  23. Развёртывание без простоя: create_before_destroy
  24. Подводные камни Terraform и рефакторинг с блоком moved
  25. Управление секретами: основы и типы
  26. Инструменты управления секретами: Yandex Lockbox, Vault, SOPS
  27. Аутентификация провайдера и секреты: сервисные аккаунты и OIDC
  28. Секреты в ресурсах и состоянии, ephemeral-значения
  29. Провайдеры Terraform: установка, версии, required_providers
  30. Несколько копий одного провайдера: alias и мультизона
  31. Несколько провайдеров и аккаунтов: configuration_aliases
  32. Terraform, Docker и Kubernetes: Managed Kubernetes в Yandex Cloud
  33. Код Terraform промышленного уровня: почему это долго
  34. Мелкие компонуемые модули вместо монолита
  35. Тестируемые модули и проверки: validation, precondition, postcondition
  36. Версионирование, публикация модулей и Terragrunt
  37. Ручное тестирование Terraform и очистка ресурсов
  38. Автоматические тесты на Terratest: модульные тесты
  39. Интеграционные и сквозные тесты, пирамида тестирования
  40. Нативный terraform test и статический анализ
  41. Внедрение Terraform в команде: процессы и культура
  42. Конвейер развёртывания прикладного кода
  43. Конвейер инфраструктурного кода и золотое правило Terraform
  44. Стиль, ревью и CI/CD-инструменты: Atlantis, TACOS, policy as code
  45. Что нового в Terraform 1.3-1.10: моды, импорт, провайдер-функции, Stacks
  46. OpenTofu в 2026: чем живёт форк и как мигрировать
  47. Сертификация HashiCorp Terraform Associate и карьера
Одна виртуалка - это всегда лотерея. Она упадет в самый неподходящий момент: ночью перед релизом, в чёрную пятницу, ровно когда ты ушёл в отпуск. Поэтому в проде приложение всегда живёт минимум в нескольких экземплярах, а перед ними стоит балансировщик нагрузки, который раскидывает трафик и сам выкидывает мёртвые инстансы из ротации. В Yandex Cloud за это отвечает Application Load Balancer (L7, разбирается в HTTP) и Network Load Balancer (L4, работает на уровне TCP/UDP).

Загвоздка в том, что ALB - это не один ресурс, а целая гирлянда из пяти связанных кубиков. Если кликать руками в консоли, легко запутаться и забыть, что куда подключено. Тут и раскрывается вся сила подхода инфраструктура как код: ты описываешь цепочку один раз в HCL, а terraform сам выстраивает граф зависимостей и создаёт ресурсы в правильном порядке. Это, пожалуй, самая многоресурсная практика всего курса по terraform, и именно на ней лучше всего видно, ради чего вообще нужен IaC.

Из чего собирается ALB: пять кубиков

Давай разберём цепочку снизу вверх, от железа к точке входа. Каждый следующий ресурс ссылается на id предыдущего - это и есть тот самый граф зависимостей, который terraform строит автоматически.
  • yandex_alb_target_group - группа целей. Это просто список IP-адресов и подсетей, куда в итоге полетит трафик. Сами бэкенды.
  • yandex_alb_backend_group - группа бэкендов. Оборачивает target group, добавляет порт, веса и - самое важное - healthcheck. Именно здесь балансировщик решает, жив инстанс или его пора выкинуть.
  • yandex_alb_http_router - HTTP-роутер. Контейнер для правил маршрутизации. Сам по себе пустой.
  • yandex_alb_virtual_host - виртуальный хост. Привязывается к роутеру и описывает маршруты: какой путь в какую backend group отправлять.
  • yandex_alb_load_balancer - сам балансировщик. У него есть listener (на каком порту слушать) и allocation_policy (в каких зонах поднять инстансы ALB).
Поток запроса читается слева направо: клиент стучится в listener балансировщика, тот передаёт запрос http-роутеру, роутер по virtual host подбирает маршрут, маршрут указывает на backend group, а та раскидывает трафик по живым целям из target group. Звучит как матрёшка, но в коде всё прозрачно.

Изображение

Собираем цепочку в HCL

Будем считать, что сеть, подсеть и инстанс-группа (yandex_compute_instance_group) у тебя уже есть из прошлых уроков. У инстанс-группы удобно то, что она сама умеет регистрировать свои виртуалки в target group: достаточно блока application_load_balancer внутри неё, и target group наполнится автоматически. Но чтобы лучше понять механику, соберём target group явно и руками.

Начнём с целей и бэкендов:

Код: Выделить всё

resource "yandex_alb_target_group" "web" {
  name = "web-targets"

  target {
    subnet_id  = yandex_vpc_subnet.app-a.id
    ip_address = yandex_compute_instance.web-1.network_interface.0.ip_address
  }

  target {
    subnet_id  = yandex_vpc_subnet.app-a.id
    ip_address = yandex_compute_instance.web-2.network_interface.0.ip_address
  }
}

resource "yandex_alb_backend_group" "web" {
  name = "web-backend-group"

  http_backend {
    name             = "web-http"
    weight           = 1
    port             = 80
    target_group_ids = [yandex_alb_target_group.web.id]

    healthcheck {
      timeout  = "2s"
      interval = "5s"
      http_healthcheck {
        path = "/health"
      }
    }
  }
}
Обрати внимание на target_group_ids - это список, и внутри он ссылается на id target group. Вот первое ребро графа зависимостей. healthcheck здесь обязателен по смыслу: timeout и interval - строки с единицами времени ("2s", "5s"), а http_healthcheck.path - путь, который ALB будет дёргать. Если ответ не 200 (точнее, не входит в expected_statuses), цель считается больной и трафик на неё не пойдёт.

Дальше - роутер и виртуальный хост:

Код: Выделить всё

resource "yandex_alb_http_router" "main" {
  name = "main-router"
}

resource "yandex_alb_virtual_host" "main" {
  name           = "main-vhost"
  http_router_id = yandex_alb_http_router.main.id

  route {
    name = "all-traffic"
    http_route {
      http_route_action {
        backend_group_id = yandex_alb_backend_group.web.id
        timeout          = "5s"
      }
    }
  }
}
Virtual host через http_router_id привязан к роутеру, а внутри route через backend_group_id ссылается на backend group. Ещё два ребра. Маршруты матчатся по порядку сверху вниз, и если первым поставить http_match с prefix "/", он перехватит вообще всё - остальные маршруты станут мёртвым грузом. Помни об этом, когда будешь добавлять правила.

И наконец сам балансировщик:

Код: Выделить всё

resource "yandex_alb_load_balancer" "main" {
  name       = "main-alb"
  network_id = yandex_vpc_network.main.id

  allocation_policy {
    location {
      zone_id   = "ru-central1-a"
      subnet_id = yandex_vpc_subnet.app-a.id
    }
  }

  listener {
    name = "http-listener"
    endpoint {
      address {
        external_ipv4_address {}
      }
      ports = [80]
    }
    http {
      handler {
        http_router_id = yandex_alb_http_router.main.id
      }
    }
  }
}
Здесь listener слушает порт 80 на внешнем IPv4 (пустой блок external_ipv4_address означает "выдай адрес автоматически"), а handler через http_router_id замыкает цепочку на роутер. allocation_policy говорит, в каких зонах поднять узлы самого ALB - это управляемый сервис, но физически он где-то живёт.

Запускай привычную пару terraform plan apply. В plan ты увидишь, как terraform насчитал порядок: сначала target group и роутер, потом backend group и virtual host, и только в конце load balancer. Ты нигде не писал depends_on - граф вывелся сам из ссылок на .id. Это ядро всей идеи terraform plan apply: ты декларируешь связи, движок выводит последовательность.

Проверяем балансировку

После apply забери внешний IP из вывода (добавь output с listener-адресом или глянь в консоли). Дальше простой тест в цикле:

Код: Выделить всё

for i in $(seq 1 10); do
  curl -s http://<ALB_IP>/ | grep -i hostname
done
Если твоё приложение отдаёт имя хоста, ответы будут чередоваться между web-1 и web-2 - значит балансировка живая. Теперь руками погаси одну виртуалку или сломай ей /health. Через пару healthcheck-интервалов ALB перестанет слать туда трафик, и весь curl поедет на оставшуюся. Подними обратно - цель вернётся в ротацию сама. Вот ради этого всё и затевалось.

Альтернатива попроще: Network Load Balancer (L4)

Если тебе не нужна маршрутизация по путям и хостам, а надо просто раскидать TCP-трафик, ALB избыточен. Бери Network Load Balancer - там кубиков всего два: yandex_lb_target_group (внимание, это другой ресурс, не alb-шный) и yandex_lb_network_load_balancer.

Код: Выделить всё

resource "yandex_lb_network_load_balancer" "main" {
  name = "main-nlb"

  listener {
    name = "tcp-listener"
    port = 80
    external_address_spec {
      ip_version = "ipv4"
    }
  }

  attached_target_group {
    target_group_id = yandex_lb_target_group.web.id

    healthcheck {
      name = "http"
      http_options {
        port = 80
        path = "/health"
      }
    }
  }
}
Здесь healthcheck живёт прямо в attached_target_group, interval и timeout - это числа в секундах, а не строки (важная разница с ALB, легко обжечься). NLB дешевле и проще, но не умеет читать HTTP-заголовки, делать редиректы и раскидывать по URL. Выбор простой: нужен L7-роутинг - ALB, нужна голая скорость и TCP - NLB.

Типичные грабли
  • Забыл healthcheck или указал не тот path. Если /health отдаёт 404, ALB считает все цели больными и возвращает 502 на любой запрос. Балансировщик есть, а трафик в никуда.
  • Перепутал alb_target_group и lb_target_group. Это разные ресурсы для разных балансировщиков. В ALB - yandex_alb_target_group, в NLB - yandex_lb_target_group. Скрестить их не выйдет.
  • Строки против чисел в таймаутах. В ALB interval и timeout - строки "5s", в NLB - числа 5. Provider честно ругнётся, но новички теряют на этом время.
  • Маршрут "/" первым. Поставил prefix "/" в начало route - и все последующие маршруты не работают, потому что матч идёт по порядку.
  • Security group закрыта. Если на балансировщик или на инстансы не открыт нужный порт в security group, healthcheck не пройдёт и трафик не пойдёт. Это не ошибка terraform, а сетевой нюанс, который ловится не сразу.
  • destroy в неверном порядке. Иногда удаление ALB подвисает, потому что target group ещё держится инстанс-группой. terraform destroy обычно разруливает сам, но если ругается - проверь, не цепляется ли group за target group через свой блок application_load_balancer.
Мини-лаба
  • Подними 2-3 инстанса (или возьми инстанс-группу из прошлого урока) с простейшим веб-сервером, отдающим hostname на /.
  • Собери полную цепочку ALB: target group -> backend group с healthcheck -> http router -> virtual host -> load balancer.
  • Сделай terraform plan и найди в выводе порядок создания. Убедись, что ты нигде не писал depends_on вручную.
  • После apply прогони curl в цикле и убедись, что ответы чередуются между инстансами.
  • Сломай /health на одной цели, подожди и проверь, что трафик уехал на здоровую. Почини - и убедись, что цель вернулась.
  • Для сравнения собери NLB на тех же целях (через yandex_lb_target_group) и почувствуй, насколько он короче.
  • В конце обязательно сделай terraform destroy и проверь по консоли, что ничего не осталось висеть и капать деньгами.
Контрольные вопросы
  • В каком порядке ссылаются друг на друга пять ресурсов ALB и почему terraform создаёт их именно так, без явного depends_on?
  • Зачем backend group нужен healthcheck и что произойдёт с трафиком, если он начнёт падать на всех целях сразу?
  • Чем yandex_alb_target_group отличается от yandex_lb_target_group и когда выбирать NLB вместо ALB?
  • Почему маршрут с prefix "/" опасно ставить первым в списке route виртуального хоста?
Итог: что запомнить

ALB в Yandex Cloud - это цепочка из пяти ресурсов, где каждый ссылается на id соседа: target group -> backend group -> http router -> virtual host -> load balancer. Healthcheck в backend group - сердце всей конструкции, без него балансировщик слепой. terraform сам строит граф зависимостей из ссылок на .id, поэтому порядок создания и удаления выводится автоматически - это и есть наглядная демонстрация смысла terraform state и terraform plan apply. Если L7-роутинг не нужен, бери NLB из двух кубиков. И всегда делай destroy после лабы: балансировщик с публичным IP - это деньги на счётчике.

P.S. про инструмент. Весь HCL из урока одинаково работает и в terraform, и в opentofu - это форк terraform под открытой лицензией MPL 2.0 под крылом Linux Foundation, тогда как terraform с версии 1.6 живёт под BSL 1.1. Для модулей terraform и провайдера yandex разницы по этому уроку нет, можешь смело набирать tofu вместо terraform в командах. Что выбрать для команды - отдельный разговор, но синтаксис инфраструктуры как код у них общий.
👍3 ❤️2 🔥 😄 🤔
Аватара пользователя
plbwws
Сообщения: 1
Зарегистрирован: 15 май 2026, 12:01

Re: Балансировщик нагрузки: Application Load Balancer в Yandex Cloud

Сообщение plbwws »

Спасибо, наконец дошло зачем тут virtual host отдельно от роутера, в консоли я их вечно путал. Вопрос: а если у меня инстанс группа сама регает цели в target group, мне руками блок target вообще не нужен получается?
👍 ❤️ 🔥1 😄 🤔
Аватара пользователя
birddog4638
Сообщения: 1
Зарегистрирован: 16 май 2026, 14:13

Re: Балансировщик нагрузки: Application Load Balancer в Yandex Cloud

Сообщение birddog4638 »

Поймал ровно ту граблю с таймаутами, в ALB строки а в NLB числа. Полдня тупил на ошибке провайдера пока не перечитал этот абзац. Healthcheck path тоже сначала забыл и ловил 502, теперь ясно.
👍 ❤️1 🔥 😄 🤔
Ответить
← Предыдущая глава
Кластер ВМ: группа экземпляров Yandex Compute Instance Group
Следующая глава →
Состояние Terraform: что такое tfstate и чем опасен локальный файл

Все главы курса «Terraform: инфраструктура как код на Yandex Cloud»

Поделиться темой: ✈ Telegram VK
  • Похожие темы
Похожие запросы: управление секретами в terraform yandex lockbox

Вернуться в «Terraform: инфраструктура как код на Yandex Cloud»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя