從 Azure Kubernetes Service 對 Azure Container Registry 進行驗證Authenticate with Azure Container Registry from Azure Kubernetes Service

當您搭配使用 Azure Container Service (AKS) 與 Azure Kubernetes Registry (ACR) 時,必須建立驗證機制。When you're using Azure Container Registry (ACR) with Azure Kubernetes Service (AKS), an authentication mechanism needs to be established. 本文詳細說明在這兩個 Azure 服務之間進行驗證所建議的組態。This article details the recommended configurations for authentication between these two Azure services.

您只需要設定下列其中一種驗證方法。You only need to configure one of these authentication methods. 最常見的方法是將授與使用 AKS 服務主體的存取權The most common approach is to grant access using the AKS service principal. 如果您有特定需求,您可以選擇性地授與使用 Kubernetes 祕密的存取權If you have specific needs, you can optionally grant access using Kubernetes secrets.

本文假設您已建立 AKS 叢集,且您能夠使用 kubectl 命令列用戶端存取與叢集。This article assumes that you've already created an AKS cluster and you are able to access the cluster with the kubectl command-line client.

將 AKS 存取權授與 ACRGrant AKS access to ACR

當您建立 AKS 叢集時,Azure 也會建立服務主體來支援其他 Azure 資源的叢集可操作性。When you create an AKS cluster, Azure also creates a service principal to support cluster operability with other Azure resources. 您可以使用此自動產生的服務主體,向 ACR 登錄進行驗證。You can use this auto-generated service principal for authentication with an ACR registry. 若要這麼做,您需要建立 Azure AD 角色指派,授與叢集的服務主體對容器登錄的存取權。To do so, you need to create an Azure AD role assignment that grants the cluster's service principal access to the container registry.

使用下列指令碼,將 AKS 產生的服務主體提取存取權授與 Azure Container Registry。Use the following script to grant the AKS-generated service principal pull access to an Azure container registry. 請先為您的環境修改 AKS_*ACR_* 變數,然後再執行指令碼。Modify the AKS_* and ACR_* variables for your environment before running the script.

#!/bin/bash

AKS_RESOURCE_GROUP=myAKSResourceGroup
AKS_CLUSTER_NAME=myAKSCluster
ACR_RESOURCE_GROUP=myACRResourceGroup
ACR_NAME=myACRRegistry

# Get the id of the service principal configured for AKS
CLIENT_ID=$(az aks show --resource-group $AKS_RESOURCE_GROUP --name $AKS_CLUSTER_NAME --query "servicePrincipalProfile.clientId" --output tsv)

# Get the ACR registry resource id
ACR_ID=$(az acr show --name $ACR_NAME --resource-group $ACR_RESOURCE_GROUP --query "id" --output tsv)

# Create role assignment
az role assignment create --assignee $CLIENT_ID --role acrpull --scope $ACR_ID

使用 Kubernetes 祕密進行存取Access with Kubernetes secret

在某些情況下,您可能無法將所需角色指派給自動產生的 AKS 服務主體,授與其存取 ACR 的權限。In some instances, you might not be able to assign the required role to the auto-generated AKS service principal granting it access to ACR. 例如,由於貴組織的安全性模型,您在 Azure Active Directory 租用戶中可能沒有足夠權限為 AKS 產生的服務主體指派角色。For example, due to your organization's security model, you might not have sufficient permissions in your Azure Active Directory tenant to assign a role to the AKS-generated service principal. 要將角色指派給服務主體,需要您的 Azure AD 帳戶擁有寫入您 Azure AD 租用戶的權限。Assigning a role to a service principal requires your Azure AD account to have write permission to your Azure AD tenant. 如果您沒有權限,您可以建立新的服務主體,然後使用 Kubernetes 映像提取密碼,授與其容器登錄的存取權。If you don't have permission, you can create a new service principal, then grant it access to the container registry using a Kubernetes image pull secret.

使用下列指令碼來建立新的服務主體 (您將使用其認證進行 Kubernetes 映像提取祕密)。Use the following script to create a new service principal (you'll use its credentials for the Kubernetes image pull secret). 請先為您的環境修改 ACR_NAME 變數,然後再執行指令碼。Modify the ACR_NAME variable for your environment before running the script.

#!/bin/bash

ACR_NAME=myacrinstance
SERVICE_PRINCIPAL_NAME=acr-service-principal

# Populate the ACR login server and resource id.
ACR_LOGIN_SERVER=$(az acr show --name $ACR_NAME --query loginServer --output tsv)
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)

# Create acrpull role assignment with a scope of the ACR resource.
SP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --role acrpull --scopes $ACR_REGISTRY_ID --query password --output tsv)

# Get the service principal client id.
CLIENT_ID=$(az ad sp show --id http://$SERVICE_PRINCIPAL_NAME --query appId --output tsv)

# Output used when creating Kubernetes secret.
echo "Service principal ID: $CLIENT_ID"
echo "Service principal password: $SP_PASSWD"

您現在可以將服務主體認證儲存在 Kubernetes 映像提取密碼中,而且您的 AKS 叢集會在執行容器時予以參考。You can now store the service principal's credentials in a Kubernetes image pull secret, which your AKS cluster will reference when running containers.

使用下列 kubectl 命令以建立 Kubernetes 密碼。Use the following kubectl command to create the Kubernetes secret. <acr-login-server> 取代為 Azure 容器登錄的完整格式名稱 (其格式為「acrname.azurecr.io」)。Replace <acr-login-server> with the fully qualified name of your Azure container registry (it's in the format "acrname.azurecr.io"). <service-principal-ID><service-principal-password> 取代為執行先前指令碼獲取的值。Replace <service-principal-ID> and <service-principal-password> with the values you obtained by running the previous script. 以任何正確格式的電子郵件地址取代 <email-address>Replace <email-address> with any well-formed email address.

kubectl create secret docker-registry acr-auth --docker-server <acr-login-server> --docker-username <service-principal-ID> --docker-password <service-principal-password> --docker-email <email-address>

您現在可以藉由使用 imagePullSecrets 參數指定其名稱,在 Pod 部署中使用 Kubernetes 密碼 (在此情況下為「acr-auth」):You can now use the Kubernetes secret in pod deployments by specifying its name (in this case, "acr-auth") in the imagePullSecrets parameter:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: acr-auth-example
spec:
  template:
    metadata:
      labels:
        app: acr-auth-example
    spec:
      containers:
      - name: acr-auth-example
        image: myacrregistry.azurecr.io/acr-auth-example
      imagePullSecrets:
      - name: acr-auth