Далее описан процесс добавления узлов из Yandex Cloud в существующий статический кластер Deckhouse Kubernetes Platform (DKP).
Для интеграции с Yandex Cloud используется модуль cloud-provider-yandex. Он обеспечивает взаимодействие DKP с API Yandex Cloud, получение информации об облачной инфраструктуре, создание виртуальных машин, работу с сетевыми параметрами и подключение узлов к существующему кластеру.
В разделе описаны два способа добавления узлов:
- Автоматическое создание узлов в Yandex Cloud. DKP создаёт виртуальные машины через API Yandex Cloud. Параметры ВМ задаются ресурсом YandexInstanceClass, а требуемое количество узлов и зоны размещения — ресурсом NodeGroup с типом
CloudEphemeral. - Подключение вручную созданных узлов через bootstrap-скрипт. Виртуальная машина создаётся пользователем заранее и подключается к кластеру с помощью bootstrap-скрипта DKP. Для такого сценария используется NodeGroup с типом
CloudStatic.
Предварительные требования
Перед началом убедитесь, что выполнены следующие условия:
- Кластер создан с параметром
clusterType: Static. - Между сетью статических узлов и VPC Yandex Cloud настроена сетевая связность. Добавляемые узлы Yandex Cloud должны иметь доступ к Kubernetes API, DNS и необходимым адресам согласно разделам «Сетевое взаимодействие» и «Настройка сетевых политик». При использовании Cilium с туннелированием трафика подов должен быть выбран режим
tunnelMode, соответствующий сетевой связности между площадками. - Выполнены требования из раздела «Подключение и авторизация в Yandex Cloud»:
- подготовлен сервисный аккаунт;
- выбран каталог, в котором будут создаваться ресурсы;
- настроены необходимые роли и доступ к используемой VPC.
Добавление автоматически создаваемых узлов
Для выполнения подготовительных команд нужен Yandex Cloud CLI (yc). Его можно использовать на рабочей машине администратора. На master-узле кластера yc не требуется: в кластере нужно применить только подготовленные манифесты.
-
Получите идентификаторы облака и каталога, в котором будут создаваться узлы:
yc resource-manager cloud list yc resource-manager folder list -
Укажите полученные идентификаторы в переменных:
export CLOUD_ID="<CLOUD_ID>" export FOLDER_ID="<FOLDER_ID>"Где:
CLOUD_ID— ID облака Yandex Cloud;FOLDER_ID— ID каталога, в котором будут создаваться ресурсы.
-
Получите идентификаторы сети, подсети и зоны, где будут создаваться узлы:
yc vpc network list --folder-id "$FOLDER_ID" yc vpc subnet list --folder-id "$FOLDER_ID" yc compute zone list -
Укажите полученные значения в переменных:
export NETWORK_ID="<NETWORK_ID>" export SUBNET_ID="<SUBNET_ID>" export ZONE="<ZONE>"Где:
NETWORK_ID— ID VPC-сети;SUBNET_ID— ID подсети, в которой будут создаваться узлы;ZONE— зона доступности, соответствующая выбранной подсети, напримерru-central1-a.
Подробнее в разделе «Подключение и авторизация в Yandex Cloud».
-
Создайте сервисный аккаунт в нужном каталоге Yandex Cloud и назначьте ему права:
yc iam service-account create \ --name dkp-hybrid \ --folder-id "$FOLDER_ID" export SA_ID="$(yc iam service-account get \ --name dkp-hybrid \ --folder-id "$FOLDER_ID" \ --format json | jq -r .id)" yc resource-manager folder add-access-binding "$FOLDER_ID" \ --role editor \ --subject "serviceAccount:${SA_ID}" yc resource-manager folder add-access-binding "$FOLDER_ID" \ --role vpc.admin \ --subject "serviceAccount:${SA_ID}"Роль
editorнужна для создания и управления облачными ресурсами, аvpc.admin— для работы с сетевыми ресурсами VPC. -
Создайте ключ сервисного аккаунта и сохраните его в JSON-файл:
yc iam key create \ --service-account-id "$SA_ID" \ --output dkp-hybrid-sa-key.jsonСохраните JSON-ключ сервисного аккаунта в переменную окружения
SERVICE_ACCOUNT_JSONв однострочном формате:export SERVICE_ACCOUNT_JSON="$(jq -c . dkp-hybrid-sa-key.json)" -
Сохраните публичный SSH-ключ администратора в переменную окружения
SSH_PUBLIC_KEY:export SSH_PUBLIC_KEY="$(cat ~/.ssh/id_rsa.pub)"Если используется другой ключ, укажите путь к нему вместо
~/.ssh/id_rsa.pub.В переменную
SSH_PUBLIC_KEYнужно сохранить публичный SSH-ключ администратора, который будет использоваться для доступа к создаваемым узлам. Не используйте публичный ключ из JSON-файла сервисного аккаунта. -
Получите ID образа операционной системы, из которого будут создаваться виртуальные машины, и сохраните его в переменную окружения
IMAGE_ID:export IMAGE_ID="$(yc compute image get-latest-from-family ubuntu-2404-lts \ --folder-id standard-images \ --format json | jq -r .id)"В переменную
IMAGE_IDнужно сохранить ID образа ОС в Yandex Cloud. Не используйте ID существующей виртуальной машины или ID ключа сервисного аккаунта. -
Укажите CIDR сети, в которой будут размещаться узлы Yandex Cloud:
export NODE_NETWORK_CIDR="<NODE_NETWORK_CIDR>"NODE_NETWORK_CIDR— CIDR, включающий внутренние IP-адреса узлов Yandex Cloud. Для одной зоны обычно совпадает с CIDR выбранной подсети. Например, если узлы создаются в подсети10.128.0.0/24, укажите10.128.0.0/24. Узнать CIDR подсети можно командой:yc vpc subnet list --folder-id "$FOLDER_ID" -
Создайте файл с конфигурацией провайдера. Например,
cloud-provider-cluster-configuration.yaml:cat > cloud-provider-cluster-configuration.yaml <<EOF apiVersion: deckhouse.io/v1 kind: YandexClusterConfiguration layout: WithoutNAT masterNodeGroup: replicas: 1 instanceClass: cores: 4 memory: 8192 imageID: ${IMAGE_ID} diskSizeGB: 100 platform: standard-v3 externalIPAddresses: - "Auto" nodeNetworkCIDR: ${NODE_NETWORK_CIDR} existingNetworkID: empty provider: cloudID: ${CLOUD_ID} folderID: ${FOLDER_ID} serviceAccountJSON: '${SERVICE_ACCOUNT_JSON}' sshPublicKey: '${SSH_PUBLIC_KEY}' EOFВ манифест автоматически подставляются значения переменных окружения, заданных на предыдущих шагах:
CLOUD_ID,FOLDER_ID,IMAGE_ID,NODE_NETWORK_CIDR,SERVICE_ACCOUNT_JSONиSSH_PUBLIC_KEY.В гибридном сценарии, когда control plane уже развёрнут как статический кластер, секция
masterNodeGroupне приводит к созданию master-узлов в Yandex Cloud, но остаётся частью конфигурации провайдера. -
Создайте файл с discovery-данными Yandex Cloud. Например,
cloud-provider-discovery-data.json:cat > cloud-provider-discovery-data.json <<EOF { "apiVersion": "deckhouse.io/v1", "defaultLbTargetGroupNetworkId": "empty", "internalNetworkIDs": [ "${NETWORK_ID}" ], "kind": "YandexCloudDiscoveryData", "monitoringAPIKey": "", "region": "ru-central1", "routeTableID": "empty", "shouldAssignPublicIPAddress": false, "zoneToSubnetIdMap": { "${ZONE}": "${SUBNET_ID}" }, "zones": [ "${ZONE}" ] } EOFВ файл автоматически подставляются значения переменных окружения, заданных на предыдущих шагах:
NETWORK_ID,SUBNET_IDиZONE.Параметр
shouldAssignPublicIPAddressуправляет назначением публичных IP-адресов создаваемым узлам. В примере указано значениеfalse, поэтому создаваемые узлы будут получать только внутренние IP-адреса.Если
shouldAssignPublicIPAddressустановлен вfalse, создаваемые узлы должны иметь доступ к хранилищу образов и внешним сервисам через NAT Gateway, NAT-инстанс, прокси или другой egress-механизм. Для зон, в которых подсети отсутствуют, допустимо использовать значениеempty. -
Закодируйте файлы
cloud-provider-cluster-configuration.yamlиcloud-provider-discovery-data.jsonв Base64:export CLUSTER_CONFIGURATION_B64="$(base64 -w0 cloud-provider-cluster-configuration.yaml)" export DISCOVERY_DATA_B64="$(base64 -w0 cloud-provider-discovery-data.json)" -
Создайте манифест с секретом
d8-provider-cluster-configurationи ModuleConfig для включения и настройки модуляcloud-provider-yandex:cat > yandex-provider-secret-and-mc.yaml <<EOF apiVersion: v1 kind: Secret metadata: labels: name: d8-provider-cluster-configuration name: d8-provider-cluster-configuration namespace: kube-system type: Opaque data: cloud-provider-cluster-configuration.yaml: ${CLUSTER_CONFIGURATION_B64} cloud-provider-discovery-data.json: ${DISCOVERY_DATA_B64} --- apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: cloud-provider-yandex spec: version: 1 enabled: true settings: storageClass: default: network-ssd EOF -
Скопируйте файл
yandex-provider-secret-and-mc.yamlна master-узел кластера. Примените манифест:d8 k apply -f yandex-provider-secret-and-mc.yaml -
Дождитесь включения модуля
cloud-provider-yandexи появления кастомного ресурса YandexInstanceClass:d8 k get module cloud-provider-dvp -o wide d8 k get crd yandexinstanceclasses.deckhouse.io -
Создайте файл с манифестами YandexInstanceClass и NodeGroup. Например,
yandex-instanceclass-nodegroup.yaml:apiVersion: deckhouse.io/v1alpha1 kind: YandexInstanceClass metadata: name: yc-worker spec: cores: 4 memory: 8192 diskSizeGB: 50 diskType: network-ssd mainSubnet: <SUBNET_ID> --- apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: yc-worker spec: nodeType: CloudEphemeral cloudInstances: classReference: kind: YandexInstanceClass name: yc-worker minPerZone: 1 maxPerZone: 1 zones: - ru-central1-aГде:
- YandexInstanceClass описывает параметры виртуальной машины, которая будет создана в Yandex Cloud;
mainSubnet— ID подсети, из которой создаваемые узлы должны иметь доступ к статическим узлам кластера;- NodeGroup описывает группу узлов, которую DKP должен поддерживать в кластере;
nodeType: CloudEphemeralозначает, что узлы будут создаваться автоматически через облачного провайдера;cloudInstances.zonesдолжен содержать зоны из спискаzonesвcloud-provider-discovery-data.json.
-
Примените манифест:
d8 k apply -f yandex-instanceclass-nodegroup.yamlПосле применения DKP начнёт создавать виртуальную машину в Yandex Cloud через machine-controller-manager.
-
Проверьте появление узла в кластере:
d8 k get nodes -o wideПример ожидаемого результата:
NAME STATUS ROLES AGE VERSION INTERNAL-IP static-master-0 Ready control-plane,master 1h v1.33.10 10.128.0.15 yc-worker-f3564dca-7fc59-s2w5d Ready yc-worker 10m v1.33.10 10.128.0.21 -
Для диагностики состояния и поиска возможных проблем проверьте логи machine-controller-manager:
d8 k -n d8-cloud-instance-manager get machinedeployments.machine.sapcloud.io -o wide d8 k -n d8-cloud-instance-manager get machinesets.machine.sapcloud.io -o wide d8 k -n d8-cloud-instance-manager get machines.machine.sapcloud.io -o wide d8 k -n d8-cloud-instance-manager logs deploy/machine-controller-manager --tail=200
Добавление вручную созданных узлов через bootstrap-скрипт
Перед началом убедитесь, что выполнены следующие условия:
-
Модуль
cloud-provider-yandexвключён:d8 k get module cloud-provider-yandex -o wide -
Компоненты модуля
cloud-provider-yandexнаходятся в состоянииRunning:d8 k -n d8-cloud-provider-yandex get pods -o wide - В Yandex Cloud создана виртуальная машина, которая будет подключена к кластеру.
- Виртуальная машина подключена к сети и подсети Yandex Cloud, используемым для гибридной интеграции с кластером.
- У виртуальной машины есть сетевой интерфейс в VPC-сети и подсети Yandex Cloud, используемые для гибридной интеграции с кластером. IP-адрес этого интерфейса должен входить в CIDR, указанный в
nodeNetworkCIDR, и быть доступен со стороны статических узлов кластера. - Имя виртуальной машины в Yandex Cloud совпадает с именем хоста (hostname) внутри операционной системы.
- На виртуальной машине установлен один из пакетных менеджеров (
apt/apt-get,yumилиrpm) для поддерживаемой ОС. В РЕД ОС по умолчанию могут отсутствоватьyumиwhich, поэтому их необходимо заранее установить.
-
Проверьте метаданные виртуальной машины в Yandex Cloud.
В метаданных ВМ должен быть настроен
cloud-initс пользователем, через которого будет выполняться подключение по SSH.Пример метаданных:
#cloud-config datasource: Ec2: strict_id: false ssh_pwauth: no users: - name: <USER> sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash ssh_authorized_keys: - <SSH_PUBLIC_KEY>Где:
<USER>— имя пользователя для SSH-доступа к виртуальной машине;<SSH_PUBLIC_KEY>— публичный SSH-ключ администратора.
-
На master-узле создайте файл с манифестом NodeGroup, указав имя группы узлов (в примере здесь и далее используется имя
yc-manual). Например,yandex-manual-nodegroup.yaml:d8 k apply -f - <<EOF apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: yc-manual spec: nodeType: CloudStatic -
Убедитесь, что NodeGroup создана и синхронизирована:
d8 k get nodegroup yc-manual d8 k describe nodegroup yc-manualПример ожидаемого результата:
NAME TYPE READY NODES UPTODATE INSTANCES DESIRED MIN MAX STANDBY STATUS AGE SYNCED yc-manual CloudStatic 0 0 0 1m True -
На master-узле получите bootstrap-скрипт для созданной NodeGroup:
NODE_GROUP=yc-manual d8 k -n d8-cloud-instance-manager get secret manual-bootstrap-for-${NODE_GROUP} \ -o jsonpath='{.data.bootstrap\.sh}' > ${NODE_GROUP}-bootstrap.b64 -
Скопируйте bootstrap-скрипт на подключаемую ВМ. Если SSH-доступ к ВМ есть с master-узла, выполните на master-узле:
scp ${NODE_GROUP}-bootstrap.b64 <USER>@<NODE_PUBLIC_OR_INTERNAL_IP>:/tmp/bootstrap.b64Для копирования и запуска bootstrap-скрипта используйте пользователя, указанного в метаданных ВМ.
Если SSH-доступ к ВМ есть только с рабочей машины администратора, сначала скопируйте файл с master-узла на рабочую машину, а затем с рабочей машины на ВМ:
scp <MASTER_USER>@<MASTER_IP>:/root/${NODE_GROUP}-bootstrap.b64 ./bootstrap.b64 scp ./bootstrap.b64 <USER>@<NODE_PUBLIC_OR_INTERNAL_IP>:/tmp/bootstrap.b64Где:
<MASTER_USER>— пользователь для SSH-доступа к master-узлу;<MASTER_IP>— IP-адрес master-узла;<USER>— пользователь на подключаемой ВМ;<NODE_PUBLIC_OR_INTERNAL_IP>— публичный или внутренний IP-адрес подключаемой ВМ.
-
На подключаемой ВМ декодируйте bootstrap-скрипт, назначьте права и запустите его:
base64 -d /tmp/bootstrap.b64 > /tmp/bootstrap.sh chmod +x /tmp/bootstrap.sh sudo bash /tmp/bootstrap.shПосле запуска bootstrap-скрипт установит необходимые компоненты, настроит container runtime, kubelet и подключит узел к кластеру.
-
На master-узле проверьте появление нового узла:
d8 k get nodes -o wideПример ожидаемого результата:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP static-master-0 Ready master 1h v1.33.10 10.128.0.15 <none> yandex-worker-hybrid Ready yc-manual 5m v1.33.10 10.128.0.17 <PUBLIC_IP> -
При сбоях подключения проверьте состояние NodeGroup, события и логи компонентов:
d8 k get nodegroup yc-manual d8 k describe nodegroup yc-manual d8 k describe node yandex-worker-hybrid d8 k -n d8-cloud-instance-manager logs deploy/machine-controller-manager --tail=200