Подготовьте хост узла Flex и удостоверение личности (предварительная версия)

Important

Предварительные версии функций AKS доступны на условиях самообслуживания и по выбору пользователя. Предварительные версии предоставляются "как есть" и "при наличии". На них не распространяются соглашения об уровне обслуживания и ограниченная гарантия. Предварительные версии AKS сопровождаются частичной поддержкой клиентов на основе принципа лучших усилий. Как таковые, эти функции не предназначены для использования в производстве. Для получения дополнительной информации ознакомьтесь со следующими статьями поддержки:

Перед присоединением узла Linux в качестве гибкого узла подготовьте узел, настройте удостоверение, выбранное во время планирования, и предоставьте этому удостоверению доступ к кластеру Azure Kubernetes Service (AKS).

В этой статье вы:

  • Просмотрите требования к узлу, а затем подготовьте к использованию или выберите узел Linux и его удостоверение в Azure.
  • Подготовьте и проверьте хост, а также запишите значения, используемые в процессе подключения.
  • Назначьте удостоверению права доступа на уровне кластера AKS и проверьте это удостоверение.

Выполните команды управления в этой статье в среде Bash, совместимой с Linux, которая имеет необходимые средства и сетевой доступ. В этой статье эта среда называется средой Bash. Отдельный компьютер, который присоединяется к кластеру, — это хост узла Flex; выполняйте там команды, только если в шаге это явно указано.

Перед тем как начать

Загрузка среды развертывания

Запустите новый сеанс Bash, определите файл среды из статьи планирования и загрузите его. Замените <deployment-name> меткой развертывания.

export FLEXNODE_DEPLOYMENT="<deployment-name>"
export FLEXNODE_ENV_FILE="${HOME}/.config/aks-flexnode/${FLEXNODE_DEPLOYMENT}.env"
test -s "${FLEXNODE_ENV_FILE}"
source "${FLEXNODE_ENV_FILE}"

Файл окружения содержит общие значения для развертывания, которые используются в этой статье, включая WORK_DIR, каталог в вашем окружении Bash, где сохраняются загрузки и созданные файлы. По умолчанию WORK_DIR — это ~/.local/share/aksflexnode/<deployment-name>. Статья получает любые другие переменные, необходимые ему. Если файл среды еще не создан, сначала выполните планирование развертывания гибких узлов .

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

Задайте активную подписку и подтвердите выбранный кластер:

az account set --subscription "${SUBSCRIPTION_ID}"

az aks show \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --query "{Name:name,ResourceId:id,ProvisioningState:provisioningState}" \
    --output table

Продолжайте, если идентификатор ресурса соответствует AKS_RESOURCE_ID, а состояние подготовки — Succeeded.

1. Проверьте требования к хосту

Используйте выделенный хост, соответствующий следующим требованиям:

  • Узел AMD64 или ARM64 под управлением Ubuntu 24.04 LTS, Azure Linux 3.x или Red Hat Enterprise Linux (RHEL) 9 или 10.
  • Уникальное имя узла, которое является допустимым именем поддомена DNS. Агент преобразует его в нижний регистр при регистрации узла.
  • Не менее четырех виртуальных ЦП и не менее 8 ГиБ должно быть свободно в разделе /var/lib.
  • Учетная запись SSH с привилегированным доступом или без sudo пароля на узле.
  • Сетевой доступ к серверу API службы AKS, Azure Resource Manager, Microsoft Entra ID, выбранному выпуску гибкого узла и зеркалу артефактов, а также к необходимым реестрам контейнеров.
  • Существующая связность уровня 3 между сетью хоста Flex node и сетью узлов, управляемых AKS. Хост и кластер AKS необязательно должны находиться в одном регионе Azure.

Среда Bash также должна иметь возможность подключаться к узлу гибких узлов через SSH. Общедоступный IP-адрес не требуется, если у вас есть другой утвержденный путь управления.

2. Подготовьте или выберите хост и идентификатор

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

Tip

Подключение компьютера за пределами Azure? Используйте управляемую идентификацию Azure Arc, если компьютер уже включён в Azure Arc, или используйте субъект-службу. Используйте управляемый идентификатор Azure VM только в том случае, если узел-хост flex node представляет собой виртуальную машину Azure.

Задайте пути ключа SSH, используемые каждым параметром удостоверения:

export SSH_PRIVATE_KEY_PATH="<path-to-private-key>"
export SSH_PUBLIC_KEY_PATH="<path-to-public-key>"

Каждый вариант идентификации также задает два адреса хоста. FLEX_HOST_SSH_TARGET — адрес, используемый средой Bash. FLEX_HOST_PRIVATE_IP — это адрес узла, доступный из сети узлов, управляемой AKS. Убедитесь у администратора сети, что FLEX_HOST_PRIVATE_IP принадлежит FLEX_HOST_SUBNET_CIDR и является адресом, доступным из сети узлов, управляемой AKS. Не используйте отдельный общедоступный или управляемый адрес в качестве адреса гибкого узла.

Используйте управляемую идентификацию Azure Arc

Используйте этот параметр для узла, который уже подключен к Azure Arc. При необходимости следуйте инструкциям по подключению гибридных компьютеров с Azure Arc серверами.

Задайте значения ресурсов Arc и адреса узла:

export ARC_RESOURCE_GROUP="<arc-machine-resource-group>"
export ARC_MACHINE_NAME="<arc-machine-name>"
export FLEX_HOST_SSH_TARGET="<admin-user>@<reachable-host-address>"
export FLEX_HOST_PRIVATE_IP="<private-ip-reachable-from-aks>"

Получение идентификатора ресурса, состояния подключения и идентификатора основного объекта:

ARC_RESOURCE_ID="/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${ARC_RESOURCE_GROUP}/providers/Microsoft.HybridCompute/machines/${ARC_MACHINE_NAME}"
export ARC_RESOURCE_ID

HOST_PRINCIPAL_OBJECT_ID="$(az resource show \
    --ids "${ARC_RESOURCE_ID}" \
    --query identity.principalId \
    --output tsv)"
export HOST_PRINCIPAL_OBJECT_ID

az resource show \
    --ids "${ARC_RESOURCE_ID}" \
    --query "{Name:name,Status:properties.status,IdentityType:identity.type,PrincipalId:identity.principalId}" \
    --output yaml

Продолжить, когда Status имеет значение Connected, а PrincipalId заполнен.

Проверьте агент Connected Machine и службу Hybrid Instance Metadata Service на хосте:

ssh -i "${SSH_PRIVATE_KEY_PATH}" "${FLEX_HOST_SSH_TARGET}" \
    'sudo azcmagent show && systemctl is-active himdsd'

Убедитесь, что azcmagent show сообщает те же идентификатор подписки, группу ресурсов и имя компьютера, что и ARC_RESOURCE_ID, ARC_MACHINE_NAME и ARC_RESOURCE_GROUP. Также убедитесь, что himdsd активен. Если ресурс не совпадает, остановитесь и исправьте значения ресурса Arc, прежде чем назначать доступ.

Запишите значения Arc и идентификатора:

set_flexnode_env ARC_RESOURCE_GROUP "${ARC_RESOURCE_GROUP}"
set_flexnode_env ARC_MACHINE_NAME "${ARC_MACHINE_NAME}"
set_flexnode_env ARC_RESOURCE_ID "${ARC_RESOURCE_ID}"
set_flexnode_env FLEX_HOST_SSH_TARGET "${FLEX_HOST_SSH_TARGET}"
set_flexnode_env FLEX_HOST_PRIVATE_IP "${FLEX_HOST_PRIVATE_IP}"
set_flexnode_env HOST_PRINCIPAL_OBJECT_ID "${HOST_PRINCIPAL_OBJECT_ID}"
set_flexnode_env HOST_IDENTITY_CLIENT_ID ""

Использование служебного принципала

Используйте этот вариант для другой поддерживаемой виртуальной машины или физического сервера. Отдавайте предпочтение учетным данным на основе сертификата вместо долгосрочного секрета клиента. Ниже описано, как создать выделенное приложение и субъект-службу с самозаверяющий сертификат для оценки. Они не создают секрет клиента и не назначают роль Azure. Доступ к целевому кластеру AKS предоставляется на шаге 4.

Прежде чем продолжить, выполните следующие действия:

  • Установите OpenSSL в среде Bash и используйте up-to-date Azure CLI, поддерживающую az login --certificate.
  • Войдите с помощью учетной записи, которая может регистрировать приложения и создавать субъекты-службы в клиенте Microsoft Entra, связанном с целевой подпиской. Само по себе владение подпиской Azure не предоставляет этих разрешений в каталоге. Если клиент ограничивает регистрацию приложения, обратитесь к администратору клиента за помощью. См. статью "Создание субъекта-службы Azure с помощью Azure CLI".
  • Убедитесь, что ваша организация разрешает самозаверяющие сертификаты для оценки. Для существующего утвержденного удостоверения используйте его идентификатор арендатора, идентификатор клиента приложения, идентификатор объекта субъекта-службы и защищенный PEM-файл, а затем перейдите к разделу Запишите значения субъекта-службы и узла.

Не сохраняйте учетные данные, закрытый ключ или путь к учетным данным в файле общей среды. Не распечатывайте PEM-файл и не добавляйте его в систему контроля версий. PEM-файл содержит незашифрованный закрытый ключ, чтобы агент смог пройти проверку подлинности без интерактивного запроса пароля. Защитите его с помощью прав доступа к файлам и утвержденных средств контроля доступа к хосту.

Создание субъекта-службы на основе сертификатов

Выполните эти команды в среде Bash во время входа в учетную запись оператора.

  1. Подтвердите подписку, клиент и учетную запись входа.

    az account set --subscription "${SUBSCRIPTION_ID}"
    az account show \
        --query "{SubscriptionId:id,TenantId:tenantId,Account:user.name}" \
        --output table
    
    SP_TENANT_ID="$(az account show --query tenantId --output tsv)"
    export SP_TENANT_ID
    

    Продолжайте, только если подписка и клиент являются целевыми объектами.

  2. Выберите уникальное отображаемое имя приложения и создайте защищенный каталог учетных данных.

    export SP_DISPLAY_NAME="aks-flexnode-${FLEXNODE_DEPLOYMENT}-$(date -u +%Y%m%dT%H%M%SZ)"
    install -d -m 0700 "${WORK_DIR:?Load the deployment environment first.}"
    SP_CREDENTIAL_DIR="$(mktemp -d "${WORK_DIR}/sp-credential.XXXXXXXX")"
    export SP_CREDENTIAL_DIR
    export SP_CLIENT_CERTIFICATE_FILE="${SP_CREDENTIAL_DIR:?Credential directory wasn't created.}/sp-client.pem"
    
  3. Создайте 30-дневный сертификат и объединенный PEM-файл, содержащий сертификат и закрытый ключ.

    (
        set -e
        umask 077
    
        openssl req -x509 -newkey rsa:2048 -sha256 -days 30 -nodes \
            -keyout "${SP_CREDENTIAL_DIR}/sp-client.key" \
            -out "${SP_CREDENTIAL_DIR}/sp-client.crt" \
            -subj "/CN=${SP_DISPLAY_NAME}"
    
        cat "${SP_CREDENTIAL_DIR}/sp-client.crt" \
            "${SP_CREDENTIAL_DIR}/sp-client.key" \
            > "${SP_CLIENT_CERTIFICATE_FILE}"
        chmod 0600 "${SP_CLIENT_CERTIFICATE_FILE}"
        rm -f "${SP_CREDENTIAL_DIR}/sp-client.key"
    )
    
    openssl x509 \
        -in "${SP_CREDENTIAL_DIR}/sp-client.crt" \
        -noout -subject -dates
    stat -c '%a %n' "${SP_CLIENT_CERTIFICATE_FILE}"
    

    Остановите работу, если создание сертификата завершается ошибкой. Убедитесь, что права доступа к PEM-файлу установлены как 600. Срок действия 30 дней предназначен для оценки, а не политики смены. Замените учетные данные в соответствии с утвержденной процедурой до истечения срока их действия, если хост остается подключенным.

  4. Создайте приложение и субъект-службу, загрузив только открытый сертификат.

    SP_CLIENT_ID="$(az ad sp create-for-rbac \
        --name "${SP_DISPLAY_NAME}" \
        --cert "@${SP_CREDENTIAL_DIR}/sp-client.crt" \
        --query appId \
        --output tsv)"
    export SP_CLIENT_ID
    

    Продолжайте только после успешного выполнения команды и возврата идентификатора клиента приложения. Команда может сообщить, что она отрегулировала дату окончания учетных данных в соответствии с истечением срока действия сертификата. Не добавляйте --scopes или --role; последующее назначение роли ограничено кластером AKS. Не запускайте создание повторно для уже существующего приложения, чтобы обновить его учетные данные.

  5. Получите идентификатор объекта субъекта-службы и проверьте зарегистрированные учетные данные.

    SP_OBJECT_ID="$(az ad sp show \
        --id "${SP_CLIENT_ID}" \
        --query id \
        --output tsv)"
    export SP_OBJECT_ID
    
    az ad sp show \
        --id "${SP_CLIENT_ID}" \
        --query "{ClientId:appId,ServicePrincipalObjectId:id}" \
        --output table
    
    az ad app show \
        --id "${SP_CLIENT_ID}" \
        --query "{ClientId:appId,PasswordCredentials:length(passwordCredentials),Certificates:keyCredentials[].{KeyId:keyId,Expires:endDateTime}}" \
        --output json
    

    Убедитесь, что идентификатор объекта субъект-службы заполнен, оба идентификатора клиента совпадают с SP_CLIENT_ID, PasswordCredentials имеет значение 0, и зарегистрирован ровно один сертификат с ожидаемым сроком действия. Если репликация каталогов задерживает поиск, подождите кратко и повторите поиск, а не создайте другое приложение.

Для проверки только учетных данных выполните проверку подлинности сертификата в разделе "Проверка субъекта-службы". Вам не нужно назначать роль в Azure или подготавливать узел для этой проверки. После завершения теста удалите выделенное тестовое приложение и локальные учетные данные.

Запишите значения субъект-службы и узла

Задайте адреса хостов. Если вы выбрали существующую идентификационную запись, сначала задайте SP_TENANT_ID, SP_CLIENT_ID и SP_OBJECT_ID равными её идентификаторам.

export FLEX_HOST_SSH_TARGET="<admin-user>@<reachable-host-address>"
export FLEX_HOST_PRIVATE_IP="<private-ip-reachable-from-aks>"

: "${SP_TENANT_ID:?Set the Microsoft Entra tenant ID.}"
: "${SP_CLIENT_ID:?Set the application client ID.}"
: "${SP_OBJECT_ID:?Set the service principal object ID.}"
export HOST_IDENTITY_CLIENT_ID=""
export HOST_PRINCIPAL_OBJECT_ID="${SP_OBJECT_ID}"

set_flexnode_env FLEX_HOST_SSH_TARGET "${FLEX_HOST_SSH_TARGET}"
set_flexnode_env FLEX_HOST_PRIVATE_IP "${FLEX_HOST_PRIVATE_IP}"
set_flexnode_env SP_TENANT_ID "${SP_TENANT_ID}"
set_flexnode_env SP_CLIENT_ID "${SP_CLIENT_ID}"
set_flexnode_env SP_OBJECT_ID "${SP_OBJECT_ID}"
set_flexnode_env HOST_IDENTITY_CLIENT_ID "${HOST_IDENTITY_CLIENT_ID}"
set_flexnode_env HOST_PRINCIPAL_OBJECT_ID "${HOST_PRINCIPAL_OBJECT_ID}"

SP_OBJECT_ID — это идентификатор объекта корпоративного приложения, также называемый идентификатором объекта субъекта-службы. Это не идентификатор объекта регистрации приложения. Убедитесь, что SP_CLIENT_ID, SP_OBJECT_ID и сертификат принадлежат одному и тому же субъекту-службе.

Bootstrap сопоставляет SP_TENANT_ID и SP_CLIENT_ID с azure.servicePrincipal.tenantId и azure.servicePrincipal.clientId в сгенерированной конфигурации агента. SP_OBJECT_ID используется для назначения роли Azure, а не как идентификатор клиента агента. Сведения о поле certificate-file, полном виде конфигурации с редактированием конфиденциальных данных и безопасных командах проверки см. в разделе Проверка сгенерированной конфигурации сервисного субъекта.

Сохраните защищенный PEM-файл для проверки подлинности и начальной загрузки узла. Сделайте его доступным на узле в рамках утвержденного процесса управления учетными данными перед подключением. Запишите его расположение с помощью утвержденного процесса управления учетными данными, а не в файле общей среды. Продолжайте с Подготовить и проверить хост, а затем назначьте роль AKS.

Использование управляемого идентификатора виртуальной машины Azure

Используйте этот параметр для виртуальной машины Azure. Создайте виртуальную машину, выполнив следующее краткое руководство. Создайте виртуальную машину Linux с помощью Azure CLI или выберите существующую виртуальную машину. Поместите виртуальную машину в сеть узла flex node, запланированную для этого развертывания. Вам не нужен общедоступный IP-адрес, если в вашей среде Bash есть другой утвержденный путь SSH.

Задайте значения виртуальной машины:

export VM_RESOURCE_GROUP="<vm-resource-group>"
export VM_NAME="<vm-name>"
export VM_ADMIN_USER="<vm-admin-user>"

Получение идентификатора ресурса виртуальной машины и адресов узла. Целевой объект SSH использует общедоступный IP-адрес, если виртуальная машина имеет один, а частный адрес в противном случае:

VM_RESOURCE_ID="$(az vm show \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --query id \
    --output tsv)"
export VM_RESOURCE_ID

FLEX_HOST_PRIVATE_IP="$(az vm show \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --show-details \
    --query privateIps \
    --output tsv)"
export FLEX_HOST_PRIVATE_IP

VM_PUBLIC_IP="$(az vm show \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --show-details \
    --query publicIps \
    --output tsv)"
export VM_PUBLIC_IP

export FLEX_HOST_SSH_TARGET="${VM_ADMIN_USER}@${VM_PUBLIC_IP:-${FLEX_HOST_PRIVATE_IP}}"

Подтвердите частный адрес, возвращенный для виртуальной машины:

az vm list-ip-addresses \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --query "[0].virtualMachine.{Name:name,PrivateAddresses:network.privateIpAddresses}" \
    --output table

Продолжайте, только если FLEX_HOST_PRIVATE_IP содержит один частный адрес, принадлежащий FLEX_HOST_SUBNET_CIDR и доступный из сети узлов, управляемой AKS. Если Azure возвращает несколько адресов, укажите в FLEX_HOST_PRIVATE_IP запланированный адрес гибкого узла, прежде чем продолжить.

Если у виртуальной машины нет общедоступного IP-адреса, или ваша среда Bash достигает узла с помощью другого утвержденного пути управления, задайте FLEX_HOST_SSH_TARGET адрес или имя узла, которое может достичь вашей среды Bash.

Заполните один из следующих вариантов управляемого удостоверения.

Системно назначенная управляемая идентичность

Включите управляемую идентичность, назначенную системой:

az vm identity assign \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --output none

Получение идентификатора основного объекта:

HOST_PRINCIPAL_OBJECT_ID="$(az vm show \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --query identity.principalId \
    --output tsv)"
export HOST_PRINCIPAL_OBJECT_ID

export HOST_IDENTITY_CLIENT_ID=""

Управляемая идентификация, назначаемая пользователем

Создайте или выберите удостоверение, следуя инструкции по управлению управляемыми удостоверениями, назначаемыми пользователем, с помощью Azure CLI.

Задайте значения идентификатора:

export USER_ASSIGNED_IDENTITY_RESOURCE_GROUP="<identity-resource-group>"
export USER_ASSIGNED_IDENTITY_NAME="<identity-name>"

Получите идентификаторы личности:

USER_ASSIGNED_IDENTITY_RESOURCE_ID="$(az identity show \
    --resource-group "${USER_ASSIGNED_IDENTITY_RESOURCE_GROUP}" \
    --name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --query id \
    --output tsv)"
export USER_ASSIGNED_IDENTITY_RESOURCE_ID

HOST_PRINCIPAL_OBJECT_ID="$(az identity show \
    --resource-group "${USER_ASSIGNED_IDENTITY_RESOURCE_GROUP}" \
    --name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --query principalId \
    --output tsv)"
export HOST_PRINCIPAL_OBJECT_ID

HOST_IDENTITY_CLIENT_ID="$(az identity show \
    --resource-group "${USER_ASSIGNED_IDENTITY_RESOURCE_GROUP}" \
    --name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --query clientId \
    --output tsv)"
export HOST_IDENTITY_CLIENT_ID

Назначьте удостоверение для виртуальной машины:

az vm identity assign \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --identities "${USER_ASSIGNED_IDENTITY_RESOURCE_ID}" \
    --output none

Убедитесь, что виртуальная машина содержит выбранное удостоверение:

az vm identity show \
    --resource-group "${VM_RESOURCE_GROUP}" \
    --name "${VM_NAME}" \
    --query "{Type:type,UserAssignedIdentities:userAssignedIdentities}" \
    --output yaml

Продолжайте, когда вывод содержит USER_ASSIGNED_IDENTITY_RESOURCE_ID.

Запишите идентификатор виртуальной машины

Запишите значения VM и идентификатора:

set_flexnode_env VM_RESOURCE_GROUP "${VM_RESOURCE_GROUP}"
set_flexnode_env VM_NAME "${VM_NAME}"
set_flexnode_env VM_ADMIN_USER "${VM_ADMIN_USER}"
set_flexnode_env VM_RESOURCE_ID "${VM_RESOURCE_ID}"
set_flexnode_env VM_PUBLIC_IP "${VM_PUBLIC_IP}"
set_flexnode_env FLEX_HOST_SSH_TARGET "${FLEX_HOST_SSH_TARGET}"
set_flexnode_env FLEX_HOST_PRIVATE_IP "${FLEX_HOST_PRIVATE_IP}"
set_flexnode_env HOST_PRINCIPAL_OBJECT_ID "${HOST_PRINCIPAL_OBJECT_ID}"
set_flexnode_env HOST_IDENTITY_CLIENT_ID "${HOST_IDENTITY_CLIENT_ID}"

3. Подготовка и проверка узла

Подключитесь к узлу:

ssh -i "${SSH_PRIVATE_KEY_PATH}" "${FLEX_HOST_SSH_TARGET}"

На узле проверьте операционную систему, архитектуру, имя узла, ЦП и доступное хранилище:

source /etc/os-release
printf 'Operating system: %s %s\n' "${NAME}" "${VERSION_ID}"
printf 'Architecture: %s\n' "$(uname -m)"
printf 'Host name: %s\n' "$(hostname)"
printf 'vCPUs: %s\n' "$(nproc)"
free -h
df -h /var/lib

Сравните результаты с требованиями к хосту на шаге 1. Прежде чем продолжить, устраните любую разницу.

Загрузочный скрипт требует наличия curl, jq и tar на хосте и останавливается, если хотя бы один из них отсутствует. Агент Flex Node устанавливает оставшиеся пакеты среды выполнения во время первоначальной загрузки.

Установите любой из этих трёх компонентов, если они ещё не включены в ваш образ:

# Ubuntu
sudo apt-get update && sudo apt-get install -y curl jq tar

# Azure Linux 3
sudo tdnf install -y curl jq tar

Выйти из сеанса хоста:

exit

Прочитайте фактическое имя узла Linux из среды Bash:

FLEX_HOST_NAME="$(ssh \
    -i "${SSH_PRIVATE_KEY_PATH}" \
    "${FLEX_HOST_SSH_TARGET}" \
    hostname)"
export FLEX_HOST_NAME

printf 'Flex host name: %s\n' "${FLEX_HOST_NAME}"

Продолжайте, когда команда возвращает ожидаемое имя узла.

Получите полное доменное имя (FQDN) сервера API AKS и проверьте разрешение имён и HTTPS-подключение с узла:

AKS_API_FQDN="$(az aks show \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --query '(privateFqdn || fqdn)' \
    --output tsv)"
export AKS_API_FQDN
ssh -i "${SSH_PRIVATE_KEY_PATH}" "${FLEX_HOST_SSH_TARGET}" \
    "getent hosts '${AKS_API_FQDN}' && \
    timeout 5 bash -c '</dev/tcp/${AKS_API_FQDN}/443'"

Если разрешение имен или подключение TCP завершается ошибкой, перед продолжением работы исправьте DNS, маршрутизацию или сетевые элементы управления. Общедоступный кластер AKS использует общедоступное полное доменное имя API (FQDN). Для частного кластера AKS ваше окружение Bash и сеть хоста гибкого узла должны разрешать полное доменное имя (FQDN) частного API и маршрутизировать к нему трафик.

Запишите значения хоста. Файл общей среды хранит пути и несекретные идентификаторы, а не содержимое ключа или учетных данных.

set_flexnode_env SSH_PRIVATE_KEY_PATH "${SSH_PRIVATE_KEY_PATH}"
set_flexnode_env SSH_PUBLIC_KEY_PATH "${SSH_PUBLIC_KEY_PATH}"
set_flexnode_env FLEX_HOST_NAME "${FLEX_HOST_NAME}"

4. Назначьте роль AKS

Текущий рабочий процесс предварительной версии использует роль участника службы Служба Azure Kubernetes непосредственно на уровне кластера AKS. Все три варианта идентификации используют идентификатор объекта субъекта-службы для управления доступом Azure на основе ролей. Используйте выделенный управляемый идентификатор хоста и удалите это назначение при удалении хоста, как описано в разделе Управление гибкими узлами в AKS и их удаление.

Отображение выбранного идентификатора основного объекта:

printf 'Principal object ID: %s\n' "${HOST_PRINCIPAL_OBJECT_ID}"

Продолжайте, только если значение указано и принадлежит выбранному идентификатору виртуальной машины, компьютеру с поддержкой Arc или субъекту-службе.

Проверьте, существует ли назначение:

az role assignment list \
    --assignee-object-id "${HOST_PRINCIPAL_OBJECT_ID}" \
    --scope "${AKS_RESOURCE_ID}" \
    --fill-principal-name false \
    --query "[?roleDefinitionName=='Azure Kubernetes Service Contributor Role'].{PrincipalId:principalId,Role:roleDefinitionName,Scope:scope}" \
    --output table

Если команда не возвращает строку, создайте назначение:

az role assignment create \
    --assignee-object-id "${HOST_PRINCIPAL_OBJECT_ID}" \
    --assignee-principal-type ServicePrincipal \
    --role "Azure Kubernetes Service Contributor Role" \
    --scope "${AKS_RESOURCE_ID}" \
    --output none

Снова запустите команду списка. Продолжайте, если идентификатор принципала и область действия совпадают с выбранным удостоверением и AKS_RESOURCE_ID. Распространение назначения ролей может занять несколько минут.

5. Подтвердите выбранную личность

Перед загрузкой узла убедитесь, что выбранное удостоверение может пройти проверку подлинности и прочитать точный целевой кластер AKS. Заполните только раздел, соответствующий выбранному вами варианту подтверждения личности.

Проверьте управляемое удостоверение личности Azure Arc

В среде Bash передайте на сервер с поддержкой Azure Arc несекретный идентификатор ресурса AKS:

[[ "${AKS_RESOURCE_ID}" == /subscriptions/*/providers/Microsoft.ContainerService/managedClusters/* ]]
printf -v AKS_RESOURCE_ID_QUOTED '%q' "${AKS_RESOURCE_ID}"

ssh -t \
    -i "${SSH_PRIVATE_KEY_PATH}" \
    "${FLEX_HOST_SSH_TARGET}" \
    "export AKS_RESOURCE_ID=${AKS_RESOURCE_ID_QUOTED}; \
    exec bash -l"

На сервере с поддержкой Azure Arc запросите токен Azure Resource Manager в службе метаданных гибридного экземпляра (HIMDS) и используйте его, чтобы прочитать ресурс AKS. Для чтения токена запроса требуются права root или членство в группе himds:

TOKEN_URL="${IDENTITY_ENDPOINT:-http://127.0.0.1:40342/metadata/identity/oauth2/token}?api-version=2019-11-01&resource=https%3A%2F%2Fmanagement.azure.com"

CHALLENGE_TOKEN_PATH="$(curl --silent --show-error \
    --dump-header - \
    --output /dev/null \
    --header Metadata:true \
    "${TOKEN_URL}" |
    sed -n 's/^[Ww][Ww][Ww]-[Aa]uthenticate: Basic realm=//p' |
    tr -d '\r')"

test -n "${CHALLENGE_TOKEN_PATH}"
CHALLENGE_TOKEN="$(sudo cat "${CHALLENGE_TOKEN_PATH}")"

TOKEN="$(curl --fail --silent --show-error \
    --header Metadata:true \
    --header "Authorization: Basic ${CHALLENGE_TOKEN}" \
    "${TOKEN_URL}" |
    jq -r '.access_token // empty')"

test -n "${TOKEN}"

AKS_ARM_HTTP="$(curl --silent --show-error \
    --output /dev/null \
    --write-out '%{http_code}' \
    --header "Authorization: Bearer ${TOKEN}" \
    "https://management.azure.com${AKS_RESOURCE_ID}?api-version=2025-07-01")"

unset CHALLENGE_TOKEN TOKEN
printf 'AKS_ARM_HTTP=%s\n' "${AKS_ARM_HTTP}"

Ожидаемые выходные данные: AKS_ARM_HTTP=200. Запустите exit, чтобы выйти из сеанса сервера с поддержкой Azure Arc.

Проверка субъекта-службы

В среде Bash используйте объединённый PEM-файл, полученный на этапе подготовки субъекта-службы. Если вы начали новый сеанс или выбрали существующий идентификатор, снова укажите его защищённый путь доступа:

export SP_CLIENT_CERTIFICATE_FILE="<protected-path-to-sp-client.pem>"
test -s "${SP_CLIENT_CERTIFICATE_FILE}"

Остановите, если файл не существует или пуст. Не добавляйте этот путь в файл общей среды.

Сначала проверьте проверку подлинности сертификата с помощью изолированного профиля Azure CLI. Подоболочка удаляет свой временный кэш токенов, даже если команда завершается ошибкой, и не влияет на ваш обычный вход в Azure CLI.

(
    set -e
    SP_AZURE_CONFIG_DIR="$(mktemp -d)"
    chmod 0700 "${SP_AZURE_CONFIG_DIR}"
    trap 'rm -rf -- "${SP_AZURE_CONFIG_DIR}"' EXIT
    export AZURE_CONFIG_DIR="${SP_AZURE_CONFIG_DIR}"

    az login \
        --service-principal \
        --username "${SP_CLIENT_ID}" \
        --certificate "${SP_CLIENT_CERTIFICATE_FILE}" \
        --tenant "${SP_TENANT_ID}" \
        --allow-no-subscriptions \
        --output none

    az account get-access-token \
        --resource https://management.azure.com/ \
        --query "{Tenant:tenant,ExpiresOn:expiresOn}" \
        --output table
)

Убедитесь, что Tenant соответствует SP_TENANT_ID и что срок действия маркера не истек. Эта команда выводит только арендатора и срок действия, а не токен доступа. --allow-no-subscriptions позволяет протестировать аутентификацию перед предоставлением доступа к Azure. Успешная проверка подлинности не подтверждает разрешение на чтение или регистрацию в кластере AKS.

После распространения назначения ролей AKS на шаге 4 проверьте доступ к точному целевому кластеру:

(
    set -e
    SP_AZURE_CONFIG_DIR="$(mktemp -d)"
    chmod 0700 "${SP_AZURE_CONFIG_DIR}"
    trap 'rm -rf -- "${SP_AZURE_CONFIG_DIR}"' EXIT
    export AZURE_CONFIG_DIR="${SP_AZURE_CONFIG_DIR}"

    az login \
        --service-principal \
        --username "${SP_CLIENT_ID}" \
        --certificate "${SP_CLIENT_CERTIFICATE_FILE}" \
        --tenant "${SP_TENANT_ID}" \
        --output none

    az account set --subscription "${SUBSCRIPTION_ID}"

    az aks show \
        --resource-group "${RESOURCE_GROUP}" \
        --name "${CLUSTER_NAME}" \
        --query "{Name:name,ResourceId:id,ProvisioningState:provisioningState}" \
        --output table
)

Продолжайте, только если возвращаемый идентификатор ресурса совпадает с AKS_RESOURCE_ID и состояние подготовки — Succeeded. Если проверка подлинности выполнена успешно, но запрос кластера запрещен, проверьте идентификатор объекта субъекта-службы, точную область назначения ролей и распространение перед повтором. Эта проверка подтверждает, что субъект-служба и его сертификат могут считывать целевой кластер. Хост использует подготовленные учетные данные в разделе Подключение гибкого узла к кластеру AKS.

Проверьте управляемую идентификацию виртуальной машины Azure

В среде Bash передайте на виртуальную машину Azure несекретный идентификатор ресурса AKS и идентификатор клиента удостоверения:

[[ "${AKS_RESOURCE_ID}" == /subscriptions/*/providers/Microsoft.ContainerService/managedClusters/* ]]
printf -v AKS_RESOURCE_ID_QUOTED '%q' "${AKS_RESOURCE_ID}"
printf -v HOST_IDENTITY_CLIENT_ID_QUOTED '%q' "${HOST_IDENTITY_CLIENT_ID}"

ssh -t \
    -i "${SSH_PRIVATE_KEY_PATH}" \
    "${FLEX_HOST_SSH_TARGET}" \
    "export AKS_RESOURCE_ID=${AKS_RESOURCE_ID_QUOTED}; \
    export HOST_IDENTITY_CLIENT_ID=${HOST_IDENTITY_CLIENT_ID_QUOTED}; \
    exec bash -l"

На виртуальной машине Azure запросите маркер Azure Resource Manager из выбранного управляемого удостоверения и используйте его для чтения ресурса AKS:

TOKEN_URL="http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F"

if [ -n "${HOST_IDENTITY_CLIENT_ID}" ]; then
    ENCODED_CLIENT_ID="$(jq -rn \
        --arg value "${HOST_IDENTITY_CLIENT_ID}" \
        '$value|@uri')"
    TOKEN_URL="${TOKEN_URL}&client_id=${ENCODED_CLIENT_ID}"
fi

TOKEN="$(curl --fail --silent --show-error \
    --header Metadata:true \
    "${TOKEN_URL}" |
    jq -r '.access_token // empty')"

test -n "${TOKEN}"

AKS_ARM_HTTP="$(curl --silent --show-error \
    --output /dev/null \
    --write-out '%{http_code}' \
    --header "Authorization: Bearer ${TOKEN}" \
    "https://management.azure.com${AKS_RESOURCE_ID}?api-version=2025-07-01")"

unset TOKEN
printf 'AKS_ARM_HTTP=%s\n' "${AKS_ARM_HTTP}"

Ожидаемые выходные данные: AKS_ARM_HTTP=200. Для идентификатора, назначаемого пользователем, запрос использует тот же HOST_IDENTITY_CLIENT_ID, который рабочий процесс вложения передает в --msi-client-id. Выполните командуexit, чтобы оставить сеанс Azure виртуальной машины.

Процесс подключения attachment workflow выполняет заключительную сквозную проверку, когда хост использует выбранный объект идентификации для регистрации своего ресурса Azure Machine.

Следующий шаг

Затем подключите подготовленный хост и проверьте его в качестве flex-узла.