Я пытаюсь получить доступ к базе данных SQL с помощью управляемого удостоверения из кластера AKS. Я настроил и развернул свое приложение Python в кластере Azure Kubernetes. Проблема заключается в настройке моего ресурса для использования управляемого удостоверения» в Azure. Мы следовали и настроили управляемую идентификацию из спецификации Microsoft, но это не сработало.
Ошибка:
Аутентификация ManagedIdentityCredential недоступна. Запрошенное удостоверение не присвоено этому ресурсу.
Выполненные шаги:
from azure.identity import ManagedIdentityCredential
import pyodbc, struct
import pandas as pd
def get_conn():
connection_string = "Driver = {ODBC Driver 17 for SQL Server};Server=tcp:XXXXXX.database.windows.net,1433;Database=XXXXX;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30"
credential = ManagedIdentityCredential(client_id = "XXXXXX") # Client id of Managed Identity
token_bytes = credential.get_token("https://database.windows.net/.default").token.encode("UTF-16-LE")
token_struct = struct.pack(f'<I{len(token_bytes)}s', len(token_bytes), token_bytes)
SQL_COPT_SS_ACCESS_TOKEN = 1256 # This connection option is defined by microsoft in msodbcsql.h
conn = pyodbc.connect(connection_string, attrs_before = {SQL_COPT_SS_ACCESS_TOKEN: token_struct})
return conn
def get_all():
with get_conn() as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM test_table_data")
data = pd.DataFrame(cursor.fetchall())
print(data.head())
return
Также создал пользователя в SQL,
CREATE USER [Msi_name] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [Msi_name];
ALTER ROLE db_datawriter ADD MEMBER [Msi_name];
ALTER ROLE db_ddladmin ADD MEMBER [Msi_name];
GO
Любой совет будет оценен и полезен. Спасибо
Кластер AKS нельзя связать напрямую с управляемым удостоверением, как это можно сделать с другим ресурсом, например виртуальной машиной или функцией Azure.
Внутри вашего кластера AKS, то есть внутри вашего Kubelet, вы получаете платформу идентификации, которая отделена от вашей платформы идентификации Microsoft Entra ID (или, по крайней мере, не связана напрямую, так сказать).
Это не означает, что вы не можете использовать свою Управляемую идентификацию, но сначала вам нужно сделать шаг. Вам необходимо выполнить обмен токенами между вашим удостоверением пользователя кластера AKS и идентификатором Microsoft Entra. Затем с помощью токена Entra ID вы сможете выполнять операции в плоскости управления Azure.
Это можно сделать через Workload Identity, что практично. Это означает, что Entra ID может доверять вашему поставщику удостоверений кластера AKS для получения токенов.
Microsoft предоставляет для этого хорошее руководство. Поскольку у вас уже есть запущенный кластер AKS и управляемое удостоверение, вам нужно только:
Вы можете выполнить все шаги здесь: https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster#update-an-existing-aks-cluster
Как вы советовали, я выполнил руководство Microsoft и выполнил обновление кластера AKS, получил URL-адрес эмитента OIDC, создал учетную запись службы Kubernetes и учетные данные федеративного удостоверения, а также развернул свое приложение yaml с добавлением меток удостоверения рабочей нагрузки и учетной записи службы. Но проблема все та же. Я что-нибудь пропустил?
В модуле при попытке доступа, например, из azure.identity import ManagedIdentityCredential,scope = "database.windows.net/.default " , credential = ManagedIdentityCredential(client_id = "Msi_client_id"), access_token = credential.get_token(scope)
Вам следует использовать WorkloadIdentityCredential модуля Python azure.identity для получения токена Entra. Пример: из azure.identity.aio import WorkloadIdentityCredential credential = WorkloadIdentityCredential( tenant_id = "<tenant_id>", client_id = "<client_id>", token_file_path = "< token_file_path>", ) # Параметры можно опустить, если установлены следующие переменные среды: # - AZURE_TENANT_ID # - AZURE_CLIENT_ID # - AZURE_FEDERATED_TOKEN_FILE credential = WorkloadIdentityCredential()
Большое спасибо. Я только что посмотрел Идентификацию рабочей нагрузки. Не могли бы вы посоветовать, как получить # token_file_path - #AZURE_FEDERATED_TOKEN_FILE. Я не могу это выяснить. Спасибо
Большое спасибо за подробное объяснение. Это действительно полезно. Как вы посоветовали, попробую выполнить эти действия, повторно развернув свое приложение и проверив. Спасибо