gpt4 book ai didi

python - Azure AKS/容器应用程序无法使用托管标识访问 key 保管库

转载 作者:行者123 更新时间:2023-12-02 06:53:41 29 4
gpt4 key购买 nike

我在 Azure 上的 kubernetes 集群上部署了一个 docker 容器 python 应用程序(我也尝试过容器应用程序)。我正在尝试将此应用程序连接到 Azure key 保管库以获取一些 secret 。我创建了一个托管身份并将其分配给两者,但 python 应用程序始终无法找到托管身份,甚至无法尝试连接到 key 保管库。

托管身份角色分配:

key 保管库贡献者 -> 在 key 保管库上

托管身份运营商 -> 托管身份

Azure Kubernetes 服务贡献者角色,Azure Kubernetes 服务集群用户角色,Managed Identity Operator -> 在包含集群的资源组上

此外,在 key 保管库访问策略上,我添加了托管身份并授予其访问所有 key 、 secret 和证书权限的权限(目前)

Python 代码:

 credential = ManagedIdentityCredential()
vault_client = SecretClient(vault_url=key_vault_uri, credential=credential)
retrieved_secret = vault_client.get_secret(secret_name)

我不断收到错误:

azure.core.exceptions.ClientAuthenticationError: Unexpected content type "text/plain; charset=utf-8"
Content: no azure identity found for request clientID

因此,在某些时候,我尝试在集群 secret 中添加托管身份 clientID 并从那里加载它,但仍然遇到相同的错误:

Python 代码:

    def get_kube_secret(self, secret_name):
kube_config.load_incluster_config()
v1_secrets = kube_client.CoreV1Api()

string_secret = str(v1_secrets.read_namespaced_secret(secret_name, "redacted_namespace_name").data).replace("'", "\"")
json_secret = json.loads(string_secret)
return json_secret

def decode_base64_string(self, encoded_string):
decoded_secret = base64.b64decode(encoded_string.strip())
decoded_secret = decoded_secret.decode('UTF-8')
return decoded_secret

managed_identity_client_id_secret = self.get_kube_secret('managed-identity-credential')['clientId']
managed_identity_client_id = self.decode_base64_string(managed_identity_client_id_secret)

更新:

我还尝试使用 secret 存储 CSI 驱动程序,但我感觉我错过了一个步骤。是否应该更新 python 代码才能使用 secret 存储 CSI 驱动程序?

# This is a SecretProviderClass using user-assigned identity to access the key vault
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-kvname-user-msi
spec:
provider: azure
parameters:
usePodIdentity: "false"
useVMManagedIdentity: "true" # Set to true for using managed identity
userAssignedIdentityID: "$CLIENT_ID" # Set the clientID of the user-assigned managed identity to use
vmmanagedidentityclientid: "$CLIENT_ID"
keyvaultName: "$KEYVAULT_NAME" # Set to the name of your key vault
cloudName: "" # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud
objects: ""
tenantId: "$AZURE_TENANT_ID"

部署 Yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: redacted_namespace
labels:
app: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: redacted_image
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
imagePullPolicy: Always
resources:
# You must specify requests for CPU to autoscale
# based on CPU utilization
requests:
cpu: "250m"
env:
- name: test-secrets
valueFrom:
secretKeyRef:
name: test-secrets
key: test-secrets
volumeMounts:
- name: test-secrets
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: test-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "azure-kvname-user-msi"
dnsPolicy: ClusterFirst

更新 16/01/2023

我按照答案中的步骤以及信中链接的文档进行操作,甚至联系了 Azure 支持人员并在电话上与他们一起逐步操作,结果仍然是以下错误:

"failed to process mount request" err="failed to get objectType:secret, objectName:MongoUsername, objectVersion:: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://<RedactedVaultName>.vault.azure.net/secrets/<RedactedSecretName>/?api-version=2016-10-01: StatusCode=400 -- Original Error: adal: Refresh request failed. Status Code = '400'. Response body: {\"error\":\"invalid_request\",\"error_description\":\"Identity not found\"} Endpoint http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&client_id=<RedactedClientId>&resource=https%3A%2F%2Fvault.azure.net"

最佳答案

使用Secrets Store CSI Driver ,您可以将 SecretProviderClass 配置为使用 workload identity通过在 SecretProviderClass 中设置 clientID。您需要使用 user assigned managed identity 的客户端 ID并将 usePodIdentityuseVMManagedIdentity 设置更改为 false

通过这种方法,您无需在应用中添加任何其他代码来检索 secret 。相反,您可以将 secret 存储(使用 CSI 驱动程序)挂载为 pod 中的卷挂载,并将 secret 加载为环境变量,记录为 here .

这个doc将引导您完成在 Azure 上的设置,但从总体上讲,您需要执行以下操作:

  1. 使用 Azure CLI 注册 EnableWorkloadIdentityPreview 功能
  2. 使用 Azure CLI 创建 AKS 集群,启用 azure-keyvault-secrets-provider 加载项并启用 --enable-oidc-issuer- -enable-workload-identiy 标志设置
  3. 创建 Azure Key Vault 并设置您的 secret
  4. 创建 Azure 用户分配的托管标识,并在 key 保管库上为托管标识的客户端 ID 设置访问策略
  5. 连接到 AKS 集群并创建一个 Kubernetes ServiceAccount,其中包含可为 Azure 工作负载身份启用此功能的注释和标签
  6. 使用 AKS 集群的 OIDC 颁发者 URL 和 Kubernetes ServiceAccount 作为主题,为托管身份创建 Azure 身份联合凭据
  7. 使用 clientID 创建 Kubernetes SecretProviderClass 以使用工作负载身份,并添加 secretObjects block 以启用使用 Kubernetes secret 存储将对象同步为环境变量.
  8. 创建一个带有标签的 Kubernetes Deployment 以使用工作负载身份,serviceAccountName 设置为您在上面创建的服务帐户,使用 CSI 的卷以及您上面创建的 secret 提供程序类、volumeMount,最后是容器中的环境变量,使用 valueFromsecretKeyRef 语法从 secret 对象存储中挂载。

希望有帮助。

关于python - Azure AKS/容器应用程序无法使用托管标识访问 key 保管库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75093624/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com