[Документация Yandex Cloud](../../index.md) > [Yandex Managed Service for Kubernetes](../index.md) > [Практические руководства](index.md) > Миграция ресурсов в другую зону доступности

# Миграция ресурсов Kubernetes в другую зону доступности

{% note info %}

В [регионе Казахстан](../../overview/concepts/region.md) доступны только [платформы](../../compute/concepts/vm-platforms.md#standard-platforms) `standard-v3` (Intel Ice Lake) и `standard-v3-t4i` (Intel Ice Lake with T4i). Другие типы платформ, кластеры GPU и выделенные хосты недоступны.

{% endnote %}

В кластере Managed Service for Kubernetes вы можете [перенести группу узлов и рабочую нагрузку в подах](#transfer-a-node-group) из одной зоны доступности в другую.

## Перед началом работы {#before-you-begin}

Если у вас еще нет интерфейса командной строки Yandex Cloud (CLI), [установите и инициализируйте его](../../cli/quickstart.md#install).

По умолчанию используется каталог, указанный при [создании](../../cli/operations/profile/profile-create.md) профиля CLI. Чтобы изменить каталог по умолчанию, используйте команду `yc config set folder-id <идентификатор_каталога>`. Также для любой команды вы можете указать другой каталог с помощью параметров `--folder-name` или `--folder-id`. Если вы обращаетесь к ресурсу по имени, поиск будет выполнен в каталоге по умолчанию. Если вы обращаетесь к ресурсу по идентификатору, поиск будет выполнен глобально — во всех каталогах с учетом прав доступа.

Если CLI уже установлен, обновите его до последней версии:

```bash
yc components update
```


## Перенесите группу узлов и рабочую нагрузку в подах в другую зону доступности {#transfer-a-node-group}

[Подготовьте группу узлов](#prepare), после чего выполните миграцию одним из способов:

* Миграция непосредственно группы узлов в новую зону доступности. Зависит от вида рабочей нагрузки в подах:

   * [Stateless-нагрузка](#stateless) — работа приложений в подах во время миграции зависит от распределения нагрузки между узлами кластера. Если поды находятся в мигрирующей группе узлов и группах, для которых не меняется зона доступности, приложения продолжают работать. Если поды находятся только в мигрирующей группе, поды и приложения в них придется остановить на короткий срок.

      Примеры stateless-нагрузки: веб-сервер, [Ingress-контроллер](../../application-load-balancer/tools/k8s-ingress-controller/index.md) Yandex Application Load Balancer, приложение REST API.

   * [Stateful-нагрузка](#stateful) — независимо от распределения нагрузки между узлами кластера поды и приложения придется остановить на короткий срок.

      Примеры stateful-нагрузки: базы данных, хранилища.

* [Постепенная миграция stateless- и stateful-нагрузки](#gradual-migration) в новую группу узлов. Заключается в создании новой группы узлов в новой зоне доступности и постепенном отключении старых узлов. Так вы можете контролировать перенос нагрузки.

### Подготовительные действия {#prepare}

1. Проверьте, используются ли стратегии `nodeSelector`, `affinity` или `topology spread constraints` для привязки подов к узлам группы. Подробнее о стратегиях смотрите в [документации Kubernetes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) и разделе [Высокая доступность и отказоустойчивость](../concepts/usage-recommendations.md#high-availability). Чтобы проверить привязку пода к узлам и убрать ее:

   {% list tabs group=instructions %}

   - Консоль управления {#console}

      1. В [консоли управления](https://kz.console.yandex.cloud) выберите каталог с вашим кластером Managed Service for Kubernetes.
      1. Перейдите в сервис **Managed Service for&nbsp;Kubernetes**.
      1. Перейдите на страницу кластера, затем — в раздел **Рабочая нагрузка**.
      1. На вкладке **Pods** откройте страницу пода.
      1. Перейдите на вкладку **YAML**.
      1. Проверьте, содержит ли манифест пода указанные параметры и Kubernetes-метки в них:

         * Параметры:

            * `spec.nodeSelector`
            * `spec.affinity`
            * `spec.topologySpreadConstraints`

         * Kubernetes-метки, заданные внутри параметров:

            * `failure-domain.beta.kubernetes.io/zone`: `<зона_доступности>`
            * `topology.kubernetes.io/zone`: `<зона_доступности>`

         Если в конфигурации есть хотя бы один из указанных параметров и он содержит хотя бы одну из перечисленных Kubernetes-меток, такая настройка будет препятствовать миграции группы узлов и рабочей нагрузки.

      1. Проверьте, есть ли в манифесте пода зависимости от сущностей:

         * зоны доступности, из которой вы переносите ресурсы;
         * конкретных узлов в группе.

      1. Если вы нашли указанные выше настройки, привязки и зависимости, удалите их из конфигурации пода:

         1. Скопируйте YAML-конфигурацию из консоли управления.
         1. Создайте локальный YAML-файл и вставьте в него конфигурацию.
         1. Удалите из нее привязки к зонам доступности. Например, если в параметре `spec.affinity` указана Kubernetes-метка `failure-domain.beta.kubernetes.io/zone`, удалите ее.
         1. Примените новую конфигурацию:

            ```bash
            kubectl apply -f <путь_до_YAML-файла>
            ```

         1. Убедитесь, что под перешел в статус `Running`:

            ```bash
            kubectl get pods
            ```

      1. Проверьте таким образом каждый под и поправьте его конфигурацию.

   {% endlist %}

1. Перенесите в новую зону доступности персистентные данные (например, базы данных, очереди сообщений, серверы мониторинга и логов).

### Миграция stateless-нагрузки {#stateless}

1. Создайте подсеть в новой зоне доступности и перенесите группу узлов:

   {% list tabs group=instructions %}
   
   - CLI {#cli}
   
      1. Создайте подсеть:
         
         ```bash
         yc vpc subnet create \
            --name <название_подсети> \
            --zone <зона_доступности> \
            --network-id <идентификатор_сети> \
            --range <CIDR_подсети>
         ```
   
         Где:
   
         * `--name` — название подсети.
         * `--zone` — зона доступности: `kz1-a`, `kz1-b` или `kz1-d`.
         * `--network-id` — идентификатор сети, в которую входит новая подсеть.
         * `--range` — список IPv4-адресов, откуда или куда будет поступать трафик. Например, `10.0.0.0/22` или `192.168.0.0/16`. Адреса должны быть уникальными внутри сети. Минимальный размер подсети — `/28`, а максимальный размер подсети — `/16`. Поддерживается только IPv4.
   
      1. Перенесите группу узлов в новую зону доступности. Ниже приведен пример команды для переноса группы, расположенной в одной зоне:
   
         ```bash
         yc managed-kubernetes node-group update \
            --id <идентификатор_группы_узлов> \
            --location zone=<зона_доступности>,subnet-id=<идентификатор_подсети> \
            --network-interface subnets=<идентификатор_подсети>,`
                 `ipv4-address=nat,`
                 `security-group-ids=[<идентификаторы_групп_безопасности>]
         ```
   
         Где:
   
         * `id` — идентификатор группы узлов, которую вы переносите в другую зону доступности.
         * `zone` — зона доступности, в которую вы переносите группу узлов: `kz1-a`, `kz1-b` или `kz1-d`.
         * `subnet-id` и `subnets` — идентификатор новой подсети, созданной ранее.
         * `ipv4-address` — способ назначения IPv4-адреса. Значение `nat` позволяет присвоить узлам публичные и внутренние IP-адреса.
         * `security-group-ids` — список идентификаторов [групп безопасности](../operations/connect/security-groups.md).
   
         {% note warning %}
   
         Если вы хотите сохранить для группы узлов значения других параметров сети, также укажите их в параметре `network-interface`. Иначе группа может быть пересоздана со значениями по умолчанию. Подробнее смотрите [Изменение группы узлов Managed Service for Kubernetes](../operations/node-group/node-group-update.md).
   
         {% endnote %}
   
         Важно передать параметры `ipv4-address` и `security-group-ids` в команде — это позволит назначить группе узлов публичные IP-адреса и сохранить в ней группы безопасности.
   
         Команда пересоздает узлы внутри их группы в указанной зоне доступности и подсети. При пересоздании учитываются настройки развертывания — максимальное количество узлов, на которое разрешается увеличить или уменьшить размер группы по сравнению с исходным количеством узлов.
   
         {% cut "Как перенести группу узлов, расположенную в разных зонах доступности" %}
   
         В этом случае используйте команду:
   
         ```bash
         yc managed-kubernetes node-group update \
            --id <идентификатор_группы_узлов> \
            --location zone=<зона_доступности>,subnet-id=<идентификатор_подсети> \
            ...
            --location zone=<зона_доступности>,subnet-id=<идентификатор_подсети> \
            --network-interface subnets=[<идентификаторы_подсетей>],`
                 `ipv4-address=nat,`
                 `security-group-ids=[<идентификаторы_групп_безопасности>]
         ```
   
         Где:
   
         * `id` — идентификатор группы узлов, которую вы переносите в другую зону доступности.
         * `zone` — зона доступности: `kz1-a`, `kz1-b` или `kz1-d`. Укажите параметры `location` для каждой зоны доступности, в которой будет располагаться группа узлов.
         * `subnet-id` и `subnets` — идентификаторы подсетей для указанных зон доступности.
         * `ipv4-address` — способ назначения IPv4-адреса. Значение `nat` позволяет присвоить узлам публичные и внутренние IP-адреса.
         * `security-group-ids` — список идентификаторов [групп безопасности](../operations/connect/security-groups.md).
   
         {% endcut %}
   
   - Terraform {#tf}
   
      {% note alert %}
   
      Чтобы убедиться, что группа узлов не будет пересоздана (если вы не делаете это намеренно), изучите вывод команд `terraform plan` и `terraform apply` перед применением конфигурации.
   
      Перенести группу узлов в другую зону доступности без пересоздания можно только при наличии в конфигурационном файле блока `allocation_policy`.
   
      {% endnote %}
   
      1. Внесите следующие изменения в конфигурационный файл:
         * Добавьте манифест новой подсети (ресурс `yandex_vpc_subnet`) в зоне доступности, в которую вы хотите перенести группу узлов.
         * Измените параметры местоположения группы узлов (ресурс `yandex_kubernetes_node_group`):
           * `allocation_policy.location.subnet_id` — удалите этот параметр, если он есть в манифесте.
           * `allocation_policy.location.zone` — укажите зону доступности, в которую вы хотите перенести группу узлов.
           * `instance_template.network_interface.subnet_ids` — укажите идентификатор новой подсети. Добавьте этот параметр, если его нет в манифесте.
   
         ```hcl
         resource "yandex_vpc_subnet" "my-new-subnet" {
            name           = "<название_подсети>"
            zone           = "<зона_доступности>"
            network_id     = "<идентификатор_сети>"
            v4_cidr_blocks = ["<CIDR_подсети>"]
         }
         ...
         resource "yandex_kubernetes_node_group" "k8s-node-group" {
            allocation_policy {
               location {
                  zone = "<зона_доступности>"
               }
            }
            ...
            instance_template {
               network_interface {
                  subnet_ids = [yandex_vpc_subnet.my-new-subnet.id]
                  ...
               }
               ...
            }
            ...
         }
         ```
   
         Где:
   
         * `name` — имя подсети.
         * `zone` — зона доступности, в которую вы переносите группу узлов: `kz1-a`, `kz1-b` или `kz1-d`.
         * `network_id` — идентификатор сети, в которую входит новая подсеть.
         * `v4_cidr_blocks` — список IPv4-адресов, откуда или куда будет поступать трафик. Например, `10.0.0.0/22` или `192.168.0.0/16`. Адреса должны быть уникальными внутри сети. Минимальный размер подсети — `/28`, а максимальный размер подсети — `/16`. Поддерживается только IPv4.
         * `subnet_ids` — идентификатор новой подсети.
   
      1. Проверьте корректность конфигурационного файла.
   
         1. В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры.
         1. Выполните команду:
         
            ```bash
            terraform validate
            ```
         
            Если в файлах конфигурации есть ошибки, Terraform на них укажет.
   
      1. Подтвердите изменение ресурсов.
   
         1. Выполните команду для просмотра планируемых изменений:
         
            ```bash
            terraform plan
            ```
         
            Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
         
         1. Если вас устраивают планируемые изменения, внесите их:
            1. Выполните команду:
         
               ```bash
               terraform apply
               ```
         
            1. Подтвердите изменение ресурсов.
            1. Дождитесь завершения операции.
   
      Узлы группы будут пересозданы в указанной зоне доступности и подсети. При пересоздании учитываются настройки развертывания — максимальное количество узлов, на которое разрешается увеличить или уменьшить размер группы по сравнению с исходным количеством узлов.
   
   {% endlist %}

1. Убедитесь, что поды запущены в перенесенной группе узлов:

   ```bash
   kubectl get po --output wide
   ```

   Вывод команды показывает, в каких узлах запущены поды.

### Миграция stateful-нагрузки {#stateful}

Миграция основана на масштабировании контроллера `StatefulSet`. Чтобы перенести рабочую stateful-нагрузку:

1. Получите список контроллеров `StatefulSet`, чтобы узнать название нужного контроллера:

   ```bash
   kubectl get statefulsets
   ```

1. Узнайте количество подов контроллера:

   ```bash
   kubectl get statefulsets <название_контроллера> \
      -n default -o=jsonpath='{.status.replicas}'
   ```

   Сохраните полученное значение. Оно понадобится в конце миграции stateful-нагрузки для масштабирования контроллера StatefulSet.

1. Уменьшите количество подов до нуля:

   ```bash
   kubectl scale statefulset <название_контроллера> --replicas=0
   ```

   Так вы выключите поды, которые используют диски. При этом сохранится объект API Kubernetes [PersistentVolumeClaim](../concepts/volume.md#persistent-volume) (PVC).

1. Для объекта [PersistentVolume](../concepts/volume.md#persistent-volume) (PV), связанного с `PersistentVolumeClaim`, измените значение параметра `persistentVolumeReclaimPolicy` с `Delete` на `Retain`, чтобы предотвратить случайную потерю данных.

   1. Получите название объекта `PersistentVolume`:

      ```bash
      kubectl get pv
      ```

   1. Отредактируйте объект `PersistentVolume`:

      ```bash
      kubectl edit pv <название_PV>
      ```

1. Проверьте, содержит ли манифест объекта `PersistentVolume` параметр `spec.nodeAffinity`:

    ```bash
    kubectl get pv <название_PV> --output='yaml'
    ```

    Если манифест содержит параметр `spec.nodeAffinity` и в нем указана принадлежность к зоне доступности, сохраните этот параметр. Его понадобится указать в новом `PersistentVolume`.

1. Создайте [снапшот](../../glossary/snapshot.md) — копию диска `PersistentVolume` на определенный момент времени. Подробнее о механизме снапшотов смотриите в [документации Kubernetes](https://kubernetes.io/docs/concepts/storage/volume-snapshots/).

   1. Получите название объекта `PersistentVolumeClaim`:

      ```bash
      kubectl get pvc
      ```

   1. Создайте файл `snapshot.yaml` с манифестом снапшота и укажите в нем название `PersistentVolumeClaim`:

      ```yaml
      apiVersion: snapshot.storage.k8s.io/v1
      kind: VolumeSnapshot
      metadata:
         name: new-snapshot-test-<номер>
      spec:
         volumeSnapshotClassName: yc-csi-snapclass
         source:
            persistentVolumeClaimName: <название_PVC>
      ```

      Если вы создаете несколько снапшотов для разных `PersistentVolumeClaim`, укажите `<номер>` (номер по порядку), чтобы значение `metadata.name` было уникальным для каждого снапшота.

   1. Создайте снапшот:

      ```bash
      kubectl apply -f snapshot.yaml
      ```

   1. Убедитесь, что снапшот создан:

      ```bash
      kubectl get volumesnapshots.snapshot.storage.k8s.io
      ```

   1. Убедитесь, что создан объект API Kubernetes [VolumeSnapshotContent](https://kubernetes.io/docs/concepts/storage/volume-snapshots/#introduction):

      ```bash
      kubectl get volumesnapshotcontents.snapshot.storage.k8s.io
      ```

1. Получите идентификатор снапшота:

   ```bash
   yc compute snapshot list
   ```

1. Создайте [диск виртуальной машины](../../compute/concepts/disk.md) из снапшота:

   ```bash
   yc compute disk create \
      --source-snapshot-id <идентификатор_снапшота> \
      --zone <зона_доступности>
   ```

   В команде укажите зону доступности, в которую переносится группа узлов Managed Service for Kubernetes.

   Сохраните следующие параметры из вывода команды:
   * идентификатор диска в поле `id`;
   * тип диска в поле `type_id`;
   * размер диска в поле `size`.

1. Создайте объект API Kubernetes `PersistentVolume` на основе нового диска:

   1. Создайте файл `persistent-volume.yaml` с манифестом `PersistentVolume`:

      ```yaml
      apiVersion: v1
      kind: PersistentVolume
      metadata:
         name: new-pv-test-<номер>
      spec:
         capacity:
            storage: <размер_PersistentVolume>
         accessModes:
            - ReadWriteOnce
         csi:
            driver: disk-csi-driver.mks.ycloud.io
            fsType: ext4
            volumeHandle: <идентификатор_диска>
         storageClassName: <тип_диска>
      ```

      В файле укажите параметры диска, созданного на основе снапшота:

      * `spec.capacity.storage` — размер диска.
      * `spec.csi.volumeHandle` — идентификатор диска.
      * `spec.storageClassName` — тип диска. Укажите его в соответствии с таблицей:

         | Тип диска на основе снапшота | Тип диска для YAML-файла |
         | ----------- | ----------- |
         | `network-ssd` | `yc-network-ssd` |
         | `network-ssd-nonreplicated` | `yc-network-ssd-nonreplicated` |
         | `network-nvme` | `yc-network-nvme` |
         | `network-hdd` | `yc-network-hdd` |

      Если вы создаете несколько объектов `PersistentVolume`, укажите `<номер>` (номер по порядку), чтобы значение `metadata.name` было уникальным.

      Если ранее вы сохранили параметр `spec.nodeAffinity`, добавьте его в манифест и укажите зону доступности, в которую переносится группа узлов Managed Service for Kubernetes. Если параметр не указан, рабочая нагрузка может запуститься в другой зоне доступности, в которой недоступен `PersistentVolume`. Это приведет к ошибке запуска.

      Пример параметра `spec.nodeAffinity`:

      ```yaml
      spec:
         ...
         nodeAffinity:
            required:
               nodeSelectorTerms:
               - matchExpressions:
                  - key: failure-domain.beta.kubernetes.io/zone
                    operator: In
                    values:
                       - ru-central1-d
      ```

   1. Создайте объект `PersistentVolume`:

      ```bash
      kubectl apply -f persistent-volume.yaml
      ```

   1. Убедитесь, что `PersistentVolume` создан:

      ```bash
      kubectl get pv
      ```

      В выводе команды появится объект `new-pv-test-<номер>`.

   1. Если в манифесте вы указали параметр `spec.nodeAffinity`, убедитесь, что для `PersistentVolume` применен этот параметр:

       {% list tabs group=instructions %}

       - Консоль управления {#console}

          1. В [консоли управления](https://kz.console.yandex.cloud) выберите каталог с вашим кластером Managed Service for Kubernetes.
          1. Перейдите в сервис **Managed Service for&nbsp;Kubernetes**.
          1. Перейдите на страницу кластера, затем — в раздел **Постоянные тома**.
          1. На вкладке **PersistentVolumes** найдите объект `new-pv-test-<номер>` и посмотрите значение поля **Зона доступности**. В нем должна отображаться зона доступности. Прочерк означает, что нет привязки к зоне доступности.

       {% endlist %}

   1. Если в манифесте вы не указали параметр `spec.nodeAffinity`, вы можете добавить его. Для этого отредактируйте объект `PersistentVolume`:

      ```bash
      kubectl edit pv new-pv-test-<номер>
      ```

1. Создайте объект `PersistentVolumeClaim` на основе нового объекта `PersistentVolume`:

   1. Создайте файл `persistent-volume-claim.yaml` с манифестом `PersistentVolumeClaim`:

      ```yaml
      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
         name: <название_PVC>
      spec:
         accessModes:
            - ReadWriteOnce
         resources:
            requests:
               storage: <размер_PV>
         storageClassName: <тип_диска>
         volumeName: new-pv-test-<номер>
      ```

      В файле задайте параметры:

      * `metadata.name` — название объекта `PersistentVolumeClaim`, который вы использовали для создания снапшота. Название можно получить с помощью команды `kubectl get pvc`.
      * `spec.resources.requests.storage` — размер `PersistentVolume`, совпадает с размером созданного диска.
      * `spec.storageClassName` — тип диска `PersistentVolume`, совпадает с типом диска у нового объекта `PersistentVolume`.
      * `spec.volumeName` — название объекта `PersistentVolume`, на основе которого создается `PersistentVolumeClaim`. Название можно получить с помощью команды `kubectl get pv`.

   1. Удалите исходный объект `PersistentVolumeClaim`, чтобы затем заменить его:

      ```bash
      kubectl delete pvc <название_PVC>
      ```

   1. Создайте объект `PersistentVolumeClaim`:

      ```bash
      kubectl apply -f persistent-volume-claim.yaml
      ```

   1. Убедитесь, что `PersistentVolumeClaim` создан:

      ```bash
      kubectl get pvc
      ```

      В выводе команды для `PersistentVolumeClaim` будет указан размер, который вы задали в YAML-файле.

1. Создайте подсеть в новой зоне доступности и перенесите группу узлов:

   {% list tabs group=instructions %}
   
   - CLI {#cli}
   
      1. Создайте подсеть:
         
         ```bash
         yc vpc subnet create \
            --name <название_подсети> \
            --zone <зона_доступности> \
            --network-id <идентификатор_сети> \
            --range <CIDR_подсети>
         ```
   
         Где:
   
         * `--name` — название подсети.
         * `--zone` — зона доступности: `kz1-a`, `kz1-b` или `kz1-d`.
         * `--network-id` — идентификатор сети, в которую входит новая подсеть.
         * `--range` — список IPv4-адресов, откуда или куда будет поступать трафик. Например, `10.0.0.0/22` или `192.168.0.0/16`. Адреса должны быть уникальными внутри сети. Минимальный размер подсети — `/28`, а максимальный размер подсети — `/16`. Поддерживается только IPv4.
   
      1. Перенесите группу узлов в новую зону доступности. Ниже приведен пример команды для переноса группы, расположенной в одной зоне:
   
         ```bash
         yc managed-kubernetes node-group update \
            --id <идентификатор_группы_узлов> \
            --location zone=<зона_доступности>,subnet-id=<идентификатор_подсети> \
            --network-interface subnets=<идентификатор_подсети>,`
                 `ipv4-address=nat,`
                 `security-group-ids=[<идентификаторы_групп_безопасности>]
         ```
   
         Где:
   
         * `id` — идентификатор группы узлов, которую вы переносите в другую зону доступности.
         * `zone` — зона доступности, в которую вы переносите группу узлов: `kz1-a`, `kz1-b` или `kz1-d`.
         * `subnet-id` и `subnets` — идентификатор новой подсети, созданной ранее.
         * `ipv4-address` — способ назначения IPv4-адреса. Значение `nat` позволяет присвоить узлам публичные и внутренние IP-адреса.
         * `security-group-ids` — список идентификаторов [групп безопасности](../operations/connect/security-groups.md).
   
         {% note warning %}
   
         Если вы хотите сохранить для группы узлов значения других параметров сети, также укажите их в параметре `network-interface`. Иначе группа может быть пересоздана со значениями по умолчанию. Подробнее смотрите [Изменение группы узлов Managed Service for Kubernetes](../operations/node-group/node-group-update.md).
   
         {% endnote %}
   
         Важно передать параметры `ipv4-address` и `security-group-ids` в команде — это позволит назначить группе узлов публичные IP-адреса и сохранить в ней группы безопасности.
   
         Команда пересоздает узлы внутри их группы в указанной зоне доступности и подсети. При пересоздании учитываются настройки развертывания — максимальное количество узлов, на которое разрешается увеличить или уменьшить размер группы по сравнению с исходным количеством узлов.
   
         {% cut "Как перенести группу узлов, расположенную в разных зонах доступности" %}
   
         В этом случае используйте команду:
   
         ```bash
         yc managed-kubernetes node-group update \
            --id <идентификатор_группы_узлов> \
            --location zone=<зона_доступности>,subnet-id=<идентификатор_подсети> \
            ...
            --location zone=<зона_доступности>,subnet-id=<идентификатор_подсети> \
            --network-interface subnets=[<идентификаторы_подсетей>],`
                 `ipv4-address=nat,`
                 `security-group-ids=[<идентификаторы_групп_безопасности>]
         ```
   
         Где:
   
         * `id` — идентификатор группы узлов, которую вы переносите в другую зону доступности.
         * `zone` — зона доступности: `kz1-a`, `kz1-b` или `kz1-d`. Укажите параметры `location` для каждой зоны доступности, в которой будет располагаться группа узлов.
         * `subnet-id` и `subnets` — идентификаторы подсетей для указанных зон доступности.
         * `ipv4-address` — способ назначения IPv4-адреса. Значение `nat` позволяет присвоить узлам публичные и внутренние IP-адреса.
         * `security-group-ids` — список идентификаторов [групп безопасности](../operations/connect/security-groups.md).
   
         {% endcut %}
   
   - Terraform {#tf}
   
      {% note alert %}
   
      Чтобы убедиться, что группа узлов не будет пересоздана (если вы не делаете это намеренно), изучите вывод команд `terraform plan` и `terraform apply` перед применением конфигурации.
   
      Перенести группу узлов в другую зону доступности без пересоздания можно только при наличии в конфигурационном файле блока `allocation_policy`.
   
      {% endnote %}
   
      1. Внесите следующие изменения в конфигурационный файл:
         * Добавьте манифест новой подсети (ресурс `yandex_vpc_subnet`) в зоне доступности, в которую вы хотите перенести группу узлов.
         * Измените параметры местоположения группы узлов (ресурс `yandex_kubernetes_node_group`):
           * `allocation_policy.location.subnet_id` — удалите этот параметр, если он есть в манифесте.
           * `allocation_policy.location.zone` — укажите зону доступности, в которую вы хотите перенести группу узлов.
           * `instance_template.network_interface.subnet_ids` — укажите идентификатор новой подсети. Добавьте этот параметр, если его нет в манифесте.
   
         ```hcl
         resource "yandex_vpc_subnet" "my-new-subnet" {
            name           = "<название_подсети>"
            zone           = "<зона_доступности>"
            network_id     = "<идентификатор_сети>"
            v4_cidr_blocks = ["<CIDR_подсети>"]
         }
         ...
         resource "yandex_kubernetes_node_group" "k8s-node-group" {
            allocation_policy {
               location {
                  zone = "<зона_доступности>"
               }
            }
            ...
            instance_template {
               network_interface {
                  subnet_ids = [yandex_vpc_subnet.my-new-subnet.id]
                  ...
               }
               ...
            }
            ...
         }
         ```
   
         Где:
   
         * `name` — имя подсети.
         * `zone` — зона доступности, в которую вы переносите группу узлов: `kz1-a`, `kz1-b` или `kz1-d`.
         * `network_id` — идентификатор сети, в которую входит новая подсеть.
         * `v4_cidr_blocks` — список IPv4-адресов, откуда или куда будет поступать трафик. Например, `10.0.0.0/22` или `192.168.0.0/16`. Адреса должны быть уникальными внутри сети. Минимальный размер подсети — `/28`, а максимальный размер подсети — `/16`. Поддерживается только IPv4.
         * `subnet_ids` — идентификатор новой подсети.
   
      1. Проверьте корректность конфигурационного файла.
   
         1. В командной строке перейдите в каталог, в котором расположены актуальные конфигурационные файлы Terraform с планом инфраструктуры.
         1. Выполните команду:
         
            ```bash
            terraform validate
            ```
         
            Если в файлах конфигурации есть ошибки, Terraform на них укажет.
   
      1. Подтвердите изменение ресурсов.
   
         1. Выполните команду для просмотра планируемых изменений:
         
            ```bash
            terraform plan
            ```
         
            Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
         
         1. Если вас устраивают планируемые изменения, внесите их:
            1. Выполните команду:
         
               ```bash
               terraform apply
               ```
         
            1. Подтвердите изменение ресурсов.
            1. Дождитесь завершения операции.
   
      Узлы группы будут пересозданы в указанной зоне доступности и подсети. При пересоздании учитываются настройки развертывания — максимальное количество узлов, на которое разрешается увеличить или уменьшить размер группы по сравнению с исходным количеством узлов.
   
   {% endlist %}

1. Верните прежнее количество подов контроллера `StatefulSet`:

   ```bash
   kubectl scale statefulset <название_контроллера> --replicas=<количество_подов>
   ```

   Поды запустятся в перенесенной группе узлов.

   В команде укажите параметры:

   * Название контроллера `StatefulSet`. Его можно получить с помощью команды `kubectl get statefulsets`.
   * Количество подов, которое было до масштабирования контроллера.

1. Убедитесь, что поды запущены в перенесенной группе узлов:

   ```bash
   kubectl get po --output wide
   ```

   Вывод команды показывает, в каких узлах запущены поды.

1. Удалите неиспользуемый объект `PersistentVolume` (в статусе `Released`).

   1. Получите название объекта `PersistentVolume`:

      ```bash
      kubectl get pv
      ```

   1. Удалите объект `PersistentVolume`:

      ```bash
      kubectl delete pv <название_PV>
      ```

### Постепенная миграция stateless- и stateful-нагрузки {#gradual-migration}

Ниже представлена инструкция по постепенной миграции нагрузки из старой группы узлов в новую. Инструкцию по миграции объектов `PersistentVolume` и `PersistentVolumeClaim` смотрите в подразделе [Миграция stateful-нагрузки](#stateful).

1. [Создайте новую группу узлов](../operations/node-group/node-group-create.md) Managed Service for Kubernetes в новой зоне доступности.

1. Запретите запуск новых подов в старой группе узлов:

   ```bash
   kubectl cordon -l yandex.cloud/node-group-id=<идентификатор_старой_группы_узлов>
   ```

1. Для каждого узла из старой группы узлов выполните команду:

   ```bash
   kubectl drain <имя_узла> --ignore-daemonsets --delete-emptydir-data
   ```

   Поды постепенно переместятся в новую группу узлов.

1. Убедитесь, что поды запущены в новой группе узлов:

   ```bash
   kubectl get po --output wide
   ```

1. [Удалите старую группу узлов](../operations/node-group/node-group-delete.md).