[Документация Yandex Cloud](../../../../index.md) > [Yandex Smart Web Security](../../../index.md) > [Практические руководства](../../index.md) > [Миграция сервисов с балансировщика NLB на L7-балансировщик ALB для подключения защиты Smart Web Security](../index.md) > [Балансировщик NLB как целевой ресурс для ALB](index.md) > Terraform

# Миграция сервисов с внешнего балансировщика NLB на L7-балансировщик ALB с целевым ресурсом — внутренним сетевым балансировщиком NLB с помощью Terraform

# Миграция сервисов с внешнего балансировщика NLB на L7-балансировщик ALB с целевым ресурсом — внутренним сетевым балансировщиком NLB с помощью Terraform


{% note warning %}

Часть ресурсов, необходимых для прохождения практического руководства, доступны только в [регионе Россия](../../../../overview/concepts/region.md).

{% endnote %}


Чтобы мигрировать сервис с сетевого балансировщика на L7-балансировщик:

1. [Ознакомьтесь с рекомендациями по миграции сервисов](#recommendations).
1. [Создайте внутренний сетевой балансировщик для Ingress-контроллера NGINX](#create-internal-nlb).
1. [Создайте инфраструктуру](#deploy). На этом этапе вы подключите профиль безопасности Smart Web Security к виртуальному хосту L7-балансировщика.
1. [Проверьте работу L7-балансировщика](#test).
1. [Мигрируйте пользовательскую нагрузку с сетевого балансировщика на L7-балансировщик](#migration-nlb-to-alb).

## Рекомендации по миграции сервисов {#recommendations}

1. Подключите защиту от DDoS-атак на уровне L3-L4 ([модель OSI](https://ru.wikipedia.org/wiki/Сетевая_модель_OSI)). Она станет дополнением к защите на уровне L7, которую после миграции обеспечит [Yandex Smart Web Security](../../../index.md).

    Чтобы подключить защиту на уровне L3-L4:

    1. Перед миграцией [зарезервируйте статический публичный IP-адрес с защитой от DDoS-атак](../../../../vpc/operations/enable-ddos-protection.md#enable-on-reservation) и используйте этот адрес для обработчика L7-балансировщика. Если для сетевого балансировщика публичный IP с защитой уже есть, его можно сохранить при миграции. В противном случае IP-адрес придется поменять на защищенный.

    1. Настройте порог для срабатывания механизмов защиты, который будет соответствовать объему легитимного трафика на защищаемый ресурс. Для настройки такого порога обратитесь в [техническую поддержку](https://kz.center.yandex.cloud/support).

    1. [Задайте](../../../../vpc/operations/adjust-mtu-ddos-protection.md) значение MTU равным `1450` на целевых ресурсах за балансировщиком. Подробнее в разделе [MTU и TCP MSS](../../../../vpc/concepts/mtu-mss.md).

1. Проводите миграцию в часы наименьшей пользовательской нагрузки. Если вы решили сохранить публичный IP-адрес, то во время миграции ваш сервис будет недоступен, пока этот IP-адрес переносится с сетевого балансировщика на L7-балансировщик. Обычно это занимает несколько минут.

1. При использовании L7-балансировщика запросы на бэкенды приходят с IP-адресом источника из диапазона внутренних IP-адресов подсетей, указанных при создании L7-балансировщика. Исходный IP-адрес источника запроса (пользователя) фигурирует в заголовке `X-Forwarded-For`. Если необходимо логировать публичные IP-адреса пользователей на веб-сервере, [измените его конфигурацию](../../../../troubleshooting/application-load-balancer/how-to/getting-external-src-ip-in-x-forwarded-for-headers.md).

1. Перед миграцией определите минимальное количество ресурсных единиц для настройки [автомасштабирования](../../../../application-load-balancer/concepts/application-load-balancer.md#lcu-scaling) в L7-балансировщике.

    Количество ресурсных единиц выберите на основе анализа нагрузки на ваш сервис по следующим показателям:

    * количество запросов в секунду (RPS);
    * количество одновременных активных соединений;
    * количество новых соединений в секунду;
    * объем трафика в секунду.

## Создайте внутренний сетевой балансировщик для Ingress-контроллера NGINX {#create-internal-nlb}

1. Создайте внутренний сетевой балансировщик для Ingress-контроллера NGINX. Выберите вариант, который соответствует способу первоначального развертывания вашего Ingress-контроллера NGINX:

    {% list tabs %}

    * С помощью Helm-чарта

        1. В файле `values.yaml`, который вы использовали для первоначальной конфигурации Ingress-контроллера NGINX, добавьте параметры конфигурации для внутреннего сетевого балансировщика. Остальные параметры в файле оставьте без изменений.

            ```bash
            controller:
              service:
                external:
                  enabled: true
                internal:
                  enabled: true
                  annotations:
                    yandex.cloud/load-balancer-type: internal
                    yandex.cloud/subnet-id: <идентификатор_подсети_для_IP-адреса_внутреннего_сетевого_балансировщика>
                  loadBalancerIP: <IP-адрес_обработчика_внутреннего_сетевого_балансировщика>
                  externalTrafficPolicy: Local
            ```

        1. Примените изменения конфигурации Ingress-контроллера NGINX с помощью команды:

            ```bash
            helm upgrade <имя_Ingress-контроллера_NGINX> -f values.yaml <чарт_для_Ingress-контроллера_NGINX> -n <пространство_имен>
            ```

    * С помощью манифеста

        1. Создайте YAML-файл, в котором опишите ресурс `Service`:

            ```bash
            apiVersion: v1
            kind: Service
            metadata:
              name: <имя_ресурса>
              namespace: <пространство_имен>
              annotations:
                yandex.cloud/load-balancer-type: internal
                yandex.cloud/subnet-id: <идентификатор_подсети_для_IP-адреса_внутреннего_сетевого_балансировщика>
            spec:
              type: LoadBalancer
              externalTrafficPolicy: Local
              loadBalancerIP: <IP-адрес_обработчика_внутреннего_сетевого_балансировщика>
              ports:
              - port: <80_или_другой_номер_порта_для_HTTP>
                targetPort: <80_или_другой_номер_порта_пода_Ingress-контроллера_NGINX_для_HTTP>
                protocol: TCP
                name: http
              - port: <443_или_другой_номер_порта_для_HTTPS>
                targetPort: <443_или_другой_номер_порта_пода_Ingress-контроллера_NGINX_для_HTTPS>
                protocol: TCP
                name: https
              selector:
                <селекторы_подов_Ingress-контроллера_NGINX>
            ```

        1. Примените изменения с помощью команды:

        ```bash
        kubectl apply -f <файл_с_ресурсом_Service>
        ```

    {% endlist %}

1. Дождитесь создания внутреннего сетевого балансировщика и появления соответствующего ему объекта `Service`. Посмотреть информацию о сервисах вы можете с помощью команды:

    ```bash
    kubectl get service
    ```

## Создайте инфраструктуру для L7-балансировщика {#deploy}

1. Если у вас еще нет Terraform, [установите его](../../../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform).
1. [Получите данные для аутентификации](../../../../tutorials/infrastructure-management/terraform-quickstart.md#get-credentials). Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
1. [Настройте и инициализируйте провайдер](../../../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Чтобы не создавать конфигурационный файл с настройками провайдера вручную, [скачайте его](https://github.com/yandex-cloud-examples/yc-terraform-provider-settings/blob/main/provider.tf).
1. Поместите конфигурационный файл в отдельную рабочую директорию и [укажите значения параметров](../../../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider). Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.

1. Скачайте в ту же рабочую директорию файл конфигурации в зависимости от используемого протокола:
    * `HTTP` — файл конфигурации [alb-int-nlb-http.tf](https://github.com/yandex-cloud-examples/yc-nlb-alb-internal-lb-migration/blob/main/alb-int-nlb-http.tf).
    * `HTTPS` — файл конфигурации [alb-int-nlb-https.tf](https://github.com/yandex-cloud-examples/yc-nlb-alb-internal-lb-migration/blob/main/alb-int-nlb-https.tf).

    В этих файлах описаны:

    * [подсети](../../../../vpc/concepts/network.md#subnet) для L7-балансировщика;
    * [группа безопасности](../../../../vpc/concepts/security-groups.md) для L7-балансировщика;
    * статический адрес для L7-балансировщика;
    * импорт TLS-сертификата в Certificate Manager (если используется протокол `HTTPS`);
    * профиль безопасности Smart Web Security;
    * целевая группа, группа бэкендов и HTTP-роутер для L7-балансировщика;
    * L7-балансировщик.

1. В конфигурационном файле укажите значения переменных:

    * `domain_name` — имя домена вашего сервиса.
    * `network_id` — идентификатор сети, в которой находятся виртуальные машины из целевой группы сетевого балансировщика нагрузки.
    * `ip_address_int_nlb` — внутренний IP-адрес [созданного ранее](#create-internal-nlb) внутреннего сетевого балансировщика.
    * `certificate` (если используется протокол `HTTPS`) — путь к файлу самоподписанного пользовательского сертификата.
    * `private_key` (если используется протокол `HTTPS`) — путь к файлу с закрытым ключом.

1. Проверьте корректность файлов конфигурации Terraform с помощью команды:

    ```bash
    terraform validate
    ```

    Если в файлах конфигурации есть ошибки, Terraform на них укажет.

1. Создайте необходимую инфраструктуру:

    1. Выполните команду для просмотра планируемых изменений:
    
       ```bash
       terraform plan
       ```
    
       Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
    
    1. Если вас устраивают планируемые изменения, внесите их:
       1. Выполните команду:
    
          ```bash
          terraform apply
          ```
    
       1. Подтвердите изменение ресурсов.
       1. Дождитесь завершения операции.

    В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в [консоли управления](https://console.yandex.cloud).

1. В консоли управления перейдите в каталог, в котором создан L7-балансировщик.
1. Перейдите в сервис **Application Load Balancer**.
1. Дождитесь, когда L7-балансировщик перейдет в статус `Active`.
1. Укажите настройки автомасштабирования в L7-балансировщике:

    1. В консоли управления нажмите на имя нужного балансировщика.
    1. Нажмите ![image](../../../../_assets/console-icons/ellipsis.svg) и выберите **Редактировать**.
    1. В блоке **Настройки автомасштабирования** укажите ограничения на количество [ресурсных единиц](../../../../application-load-balancer/concepts/application-load-balancer.md#lcu-scaling).
    1. Нажмите кнопку **Сохранить**.

## Проверьте работу L7-балансировщика {#test}

1. В [консоли управления](https://console.yandex.cloud) перейдите в созданный L7-балансировщик и слева выберите **Проверки состояния**. Убедитесь, что все проверки состояния L7-балансировщика показывают состояние `HEALTHY`.

1. Протестируйте запрос к сервису через L7-балансировщик. Например, одним из способов:
   
   * В файле `hosts` на рабочей станции добавьте запись `<публичный_IP-адрес_L7-балансировщика> <имя_домена_сервиса>`. Удалите запись после тестирования.
   * Выполните запрос с помощью [cURL](https://curl.se/) в зависимости от типа протокола:
   
       ```bash
       curl http://<имя_домена_сервиса> \
           --resolve <имя_домена_сервиса>:<порт_сервиса>:<публичный_IP-адрес_L7-балансировщика>
       ```
   
       ```bash
       curl https://<имя_домена_сервиса> \
           --resolve <имя_домена_сервиса>:<порт_сервиса>:<публичный_IP-адрес_L7-балансировщика>
       ```

## Мигрируйте пользовательскую нагрузку с внешнего сетевого балансировщика на L7-балансировщик {#migration-nlb-to-alb}

Выберите один из вариантов миграции:

* [Сохранить публичный IP-адрес для вашего сервиса](#save-public-ip).
* [Не сохранять публичный IP-адрес для вашего сервиса](#not-save-public-ip).

### Сохранить публичный IP-адрес для вашего сервиса {#save-public-ip}

1. Если у внешнего сетевого балансировщика используется динамический публичный IP-адрес, [сделайте его статическим](../../../../vpc/operations/set-static-ip.md).

1. Удалите внешний сетевой балансировщик. Выберите вариант, который соответствует способу первоначального развертывания вашего Ingress-контроллера NGINX:

    {% list tabs %}

    * С помощью Helm-чарта

        1. В файле `values.yaml`, который вы использовали для конфигурации Ingress-контроллера NGINX, в секции `controller.service.external` установите значение параметра `enabled: false`. Остальные параметры в файле оставьте без изменений.

            ```bash
            controller:
              service:
                external:
                  enabled: false
                ...
            ```

        1. Примените изменения конфигурации Ingress-контроллера NGINX с помощью команды:

            ```bash
            helm upgrade <имя_Ingress-контроллера_NGINX> -f values.yaml <чарт_для_Ingress-контроллера_NGINX> -n <пространство_имен>
            ```

    * С помощью манифеста

        Удалите ресурс `Service` для внешнего сетевого балансировщика с помощью команды:

        ```bash
        kubectl delete service <имя_ресурса_Service_для_внешнего_сетевого_балансировщика>
        ```

    {% endlist %}

1. Дождитесь удаления внешнего сетевого балансировщика для Ingress-контроллера NGINX и удаления соответствующего ему объекта `Service`. Посмотреть информацию о сервисах вы можете с помощью команды:

    ```bash
    kubectl get service
    ```

    После этого ваш сервис не будет доступен через внешний сетевой балансировщик.

1. В L7-балансировщике назначьте обработчику публичный IP-адрес, который ранее был у внешнего сетевого балансировщика:

    1. Откройте конфигурационный файл, который вы использовали для создания L7-балансировщика (`alb-int-nlb-http.tf` или `alb-int-nlb-https.tf`).

    1. Измените в описании балансировщика значение параметра `address` в блоке `listener.endpoint.address.external_ipv4_address`:

        ```hcl
        resource "yandex_alb_load_balancer" "<имя_балансировщика>" {
          ...
          listener {
            ...
            endpoint {
              address {
                external_ipv4_address {
                  address = <публичный_IP-адрес_сервиса>
                }
              }
              ports = [ <порт_сервиса> ]
            }
          }
        }
        ```

        Где `address` — это публичный IP-адрес, который ранее был у сетевого балансировщика.

    1. Примените изменения:

        1. В терминале перейдите в директорию с конфигурационным файлом.
        1. Проверьте корректность конфигурации с помощью команды:
        
           ```bash
           terraform validate
           ```
        
           Если конфигурация является корректной, появится сообщение:
        
           ```bash
           Success! The configuration is valid.
           ```
        
        1. Выполните команду:
        
           ```bash
           terraform plan
           ```
        
           В терминале будет выведен список ресурсов с параметрами. На этом этапе изменения не будут внесены. Если в конфигурации есть ошибки, Terraform на них укажет.
        1. Примените изменения конфигурации:
        
           ```bash
           terraform apply
           ```
        
        1. Подтвердите изменения: введите в терминале слово `yes` и нажмите **Enter**.

1. После изменения IP-адреса восстановится доступность вашего сервиса через L7-балансировщик. Наблюдайте за пользовательской нагрузкой, поступающей на L7-балансировщик, на графиках [статистики работы балансировщика](../../../../application-load-balancer/operations/application-load-balancer-get-stats.md).

1. Удалите освободившийся статический публичный IP-адрес, который был выбран при создании L7-балансировщика.

    1. Откройте конфигурационный файл, который вы использовали для создания L7-балансировщика (`alb-int-nlb-http.tf` или `alb-int-nlb-https.tf`).

    1. Удалите из файла описание ресурса `yandex_vpc_address`:

        ```hcl
        resource "yandex_vpc_address" "static-address" {
          description = "Static public IP address for the Application Load Balancer"
          name        = "alb-static-address"
          external_ipv4_address {
            zone_id                  = "ru-central1-a"
            ddos_protection_provider = "qrator"
          }
        }
        ```

    1. Примените изменения:

        1. В терминале перейдите в директорию с конфигурационным файлом.
        1. Проверьте корректность конфигурации с помощью команды:
        
           ```bash
           terraform validate
           ```
        
           Если конфигурация является корректной, появится сообщение:
        
           ```bash
           Success! The configuration is valid.
           ```
        
        1. Выполните команду:
        
           ```bash
           terraform plan
           ```
        
           В терминале будет выведен список ресурсов с параметрами. На этом этапе изменения не будут внесены. Если в конфигурации есть ошибки, Terraform на них укажет.
        1. Примените изменения конфигурации:
        
           ```bash
           terraform apply
           ```
        
        1. Подтвердите изменения: введите в терминале слово `yes` и нажмите **Enter**.

### Не сохранять публичный IP-адрес для вашего сервиса {#not-save-public-ip}

1. Чтобы мигрировать пользовательскую нагрузку с внешнего сетевого балансировщика на L7-балансировщик, в DNS-сервисе, обслуживающем публичную зону вашего домена, измените значение A-записи для доменного имени сервиса на публичный IP-адрес L7-балансировщика. Если публичная зона домена была создана в [Yandex Cloud DNS](../../../../dns/index.md), то измените запись [по инструкции](../../../../dns/operations/resource-record-update.md).

    {% note info %}

    Миграция нагрузки может выполняться долго, так как распространение изменений в записи DNS зависит от времени жизни записи (TTL) и количества звеньев цепочки DNS-запросов.

    {% endnote %}

1. По мере распространения изменений в записи DNS наблюдайте за ростом запросов, поступающих на L7-балансировщик, на графиках [статистики работы балансировщика](../../../../application-load-balancer/operations/application-load-balancer-get-stats.md).

1. Наблюдайте за снижением нагрузки на внешний сетевой балансировщик с помощью [метрик балансировщика](../../../../monitoring/metrics-ref/network-load-balancer-ref.md) `processed_bytes` и `processed_packets`. Для визуализации этих метрик можно [создать дашборд](../../../../monitoring/operations/dashboard/create.md). Если нагрузка на сетевом балансировщике долгое время отсутствует, то перенос на L7-балансировщик завершен.

1. (Опционально) После переноса пользовательской нагрузки на L7-балансировщик [удалите внешний сетевой балансировщик](../../../../network-load-balancer/operations/load-balancer-delete.md). Выберите вариант, который соответствует способу первоначального развертывания вашего Ingress-контроллера NGINX:

    {% list tabs %}

    * С помощью Helm-чарта

        1. В файле `values.yaml`, который вы использовали для конфигурации Ingress-контроллера NGINX, в секции `controller.service.external` установите значение параметра `enabled: false`. Остальные параметры в файле оставьте без изменений.

            ```bash
            controller:
              service:
                external:
                  enabled: false
                ...
            ```

        1. Примените изменения конфигурации Ingress-контроллера NGINX с помощью команды:

            ```bash
            helm upgrade <имя_Ingress-контроллера_NGINX> -f values.yaml <чарт_для_Ingress-контроллера_NGINX> -n <пространство_имен>
            ```

        {% note warning %}

        При изменении конфигурации Ingress-контроллера NGINX ваш сервис временно будет недоступен.

        {% endnote %}

    * С помощью манифеста

        Удалите ресурс `Service` для внешнего сетевого балансировщика с помощью команды:

        ```bash
        kubectl delete service <имя_ресурса_Service_для_внешнего_сетевого_балансировщика>
        ```

    {% endlist %}

1. (Опционально) Дождитесь удаления внешнего сетевого балансировщика для Ingress-контроллера NGINX и удаления соответствующего ему объекта `Service`. Посмотреть информацию о сервисах вы можете с помощью команды:

    ```bash
    kubectl get service
    ```