使用 Azure Kubernetes Service(AKS)的 Azure Container Registry (ACR) 時,你需要建立認證機制。 你可以使用 Azure CLI、Azure PowerShell 或 Azure 入口網站設定 ACR 與 AKS 之間的所需權限。 本文提供範例,說明如何使用 Azure CLI 或 Azure PowerShell 來設定這些 Azure 服務之間的認證。
AKS 與 ACR 的整合會將 AcrPull 角色指派給與 AKS 叢集中與 Agent 集區相關的 Microsoft Entra ID 受控識別。 如需 AKS 受控識別的詳細資訊,請參閱受控識別的摘要。
重要
Microsoft Entra 群組在附加 ACR 時會有延遲問題。 如果將 AcrPull 角色授予 Microsoft Entra 群組,並將 kubelet 身份新增至群組以完成 Azure 角色型存取控制 (Azure RBAC) 設定,則在 RBAC 群組生效之前可能會有延遲。 如果您正在執行需要完成 Azure RBAC 組態的自動化,建議您使用自備 kubelet 身分識別作為替代解決方案。 你可以預先建立一個使用者指派的身份,加入 Microsoft Entra 群組,然後用該身份作為 kubelet 身份來建立 AKS 叢集。 此方法確保在由 kubelet 生成代幣之前將身份加入到 Microsoft Entra 群組中,從而避免延遲問題。
注意
此文章涵蓋 AKS 與 ACR 之間的自動驗證。 如果您需要從私人外部登錄提取映像,請使用映像提取密碼。
謹慎
透過az aks --attach-acr的 AKS-ACR 整合不支援角色指派權限模式設為「RBAC 登錄 + ABAC 存放庫權限」的啟用 ABAC 的 ACR 登錄。啟用 ABAC 的 ACR 登錄需要Container Registry Repository Reader角色而非AcrPull角色,以授與映像提取權限。 對於啟用 ABAC 的 ACR 登錄檔,你不應該使用 az aks --attach-acr,而是透過 Azure 入口網站、Container Registry Repository Reader CLI 或 Azure Resource Manager 手動指派 az role assignment 角色。 欲了解更多關於 ABAC 啟用的 ACR 登錄系統,請參見 Azure 屬性基礎存取控制。
在這個導覽中,你要配置一個 Azure Kubernetes Service (AKS) 叢集,以安全地從 Azure Container Registry(ACR)拉取映像檔。 在Azure CLI中,使用 --attach-acr。 在 Terraform 中,將AcrPull角色指派給 AKS kubelet 受控識別。 本指南遵循與 Azure CLI 工作流程相同的流程,並使用 Terraform 進行基礎架構配置。
開始之前
- 你需要在Azure訂閱時擁有Owner、Azure 帳戶管理員,或Azure共同管理員 角色。
- 為了避免需要這些角色,您可以改用現有的受控識別,從 AKS 驗證 ACR。 欲了解更多資訊,請參閱 使用 Azure 管理身份驗證 ACR。
- 如果你正在使用 Azure CLI,本文要求你必須執行 Azure CLI 2.7.0 或更新版本。 要找到版本,請執行該
az --version指令。 如果你需要安裝或升級,請參考 安裝 Azure CLI。
- 如果你使用 Azure PowerShell,本文要求你使用 Azure PowerShell 5.9.0 或更新版本。 若要尋找版本,請執行
Get-InstalledModule -Name Az命令。 如果你需要安裝或升級,請參考 安裝 Azure PowerShell。 - 您可以在 Terraform 參考中找到使用 Terraform 設定 ACR 的範例和語法。
- Terraform 已安裝(
>= 1.6)。 - Azure CLI 已安裝並登入你的訂閱。
- 分配角色的權限(擁有者或使用者存取管理員)。
在本文中,你要設定一個 Azure Kubernetes Service (AKS) 叢集,以安全地從 Azure Container Registry(ACR)拉取映像檔。 在Azure CLI中,使用 --attach-acr。 在 Terraform 中,將AcrPull角色指派給 AKS kubelet 受控識別。
本文遵循與 Azure CLI 工作流程相同的流程,使用 Terraform 進行基礎架構配置。 要確認你已登入正確的訂閱,請使用以下 Azure CLI 指令:
az login
az account show
建立新的 ACR
如果您還沒有 ACR,請使用 az acr create 命令建立一個。
註冊名稱必須在Azure內全域唯一,包含 5-50 個字母數字,不包含破折號(-)字元。 這個名稱是註冊局完全合格 DNS 名稱的一部分。
export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
export MYACR="mycontainerregistry$RANDOM_STRING"
export ACR_RESOURCE_GROUP="myContainerRegistryResourceGroup"
export LOCATION="westcentralus"
az group create \
--name $ACR_RESOURCE_GROUP \
--location $LOCATION
az acr create \
--name $MYACR \
--resource-group $ACR_RESOURCE_GROUP \
--sku basic
變 RANDOM_STRING 數儲存一個隨機的 10 位數字串。
MYACR值與RANDOM_STRING值串接以形成唯一名稱。
如果您還沒有 ACR,請使用 New-AzContainerRegistry Cmdlet 建立一個。
註冊名稱必須在Azure內全域唯一,包含 5-50 個字母數字,不包含破折號(-)字元。 這個名稱是註冊局完全合格 DNS 名稱的一部分。
$RandomString = (Get-Random -Minimum 1000000000 -Maximum 10000000000).ToString()
$MyAcr = "mycontainerregistry$RandomString"
$AcrResourceGroup = "myContainerRegistryResourceGroup"
$Location = "westcentralus"
New-AzResourceGroup -Name $AcrResourceGroup -Location $Location
$NewAcr = @{
Name = $MyAcr
ResourceGroupName = $AcrResourceGroup
Location = $Location
Sku = "Basic"
}
New-AzContainerRegistry @NewAcr
變 $RandomString 數儲存一個隨機的 10 位數字串。
$MyAcr值與$RandomString值串接以形成唯一名稱。
下一節中的 Terraform 範例會在完整的 AKS 與 ACR 部署中一併建立 ACR。
建立新的 AKS 叢集,並與現有的 ACR 整合
建立一個新的 AKS 叢集,並使用具有 az aks create 參數的 --attach-acr 指令與現有的 ACR 整合。 此命令允許您授權訂用帳戶中的現有 ACR,並為受控識別設定適當的AcrPull角色。
export CLUSTER_NAME="myAKSCluster"
export CLUSTER_RESOURCE_GROUP="myClusterResourceGroup"
az group create \
--name $CLUSTER_RESOURCE_GROUP \
--location $LOCATION
az aks create \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--generate-ssh-keys \
--attach-acr $MYACR
在不同的訂用帳戶中使用 ACR,或是使用資源識別碼連接
如果您正在使用位於與您的 AKS 叢集不同的訂閱中的 ACR,或者偏好使用 ACR 資源 ID 而非 ACR 名稱,請使用以下語法。 此範例使用前一節建立的容器登錄檔來建立變 ACR_RESOURCE_ID 數。
ACR_RESOURCE_ID=$(az acr show \
--name $MYACR \
--resource-group $ACR_RESOURCE_GROUP \
--query id --output tsv)
az aks create \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--generate-ssh-keys \
--attach-acr $ACR_RESOURCE_ID
使用 New-AzAksCluster cmdlet 及 -AcrNameToAttach 參數,建立一個新的 AKS 叢集,並與現有的 ACR 整合。 此命令允許您授權訂用帳戶中的現有 ACR,並為受控識別設定適當的AcrPull角色。
$ClusterName = "myAKSCluster"
$ClusterResourceGroup = "myClusterResourceGroup"
New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location
$NewCluster = @{
Name = $ClusterName
ResourceGroupName = $ClusterResourceGroup
GenerateSshKey = $true
AcrNameToAttach = $MyAcr
}
New-AzAksCluster @NewCluster
在不同的訂用帳戶中使用 ACR,或是使用資源識別碼連接
Azure PowerShell 僅支援使用 -AcrNameToAttach 參數將 ACR 附加到 AKS,且不支援以 資源 ID 附加 ACR。
建立一個 main.tf 檔案,並將以下測試過的範例設定複製到裡面。 Azure Terraform GitHub 儲存庫維護該範例,存放於 Azure Terraform GitHub 儲存庫中。 範例建立 ACR 與 AKS 叢集,將 AcrPull 角色指派給 kubelet 管理身份,將 NGINX 映像匯入登錄檔,並將該映像部署至叢集。
terraform {
required_version = ">= 1.6.0"
required_providers {
azapi = {
source = "azure/azapi"
version = "~> 2.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.30"
}
}
}
provider "azurerm" {
features {}
}
resource "random_string" "suffix" {
length = 6
upper = false
special = false
}
locals {
resource_group_name = "rg-aks-acr-demo"
location = "eastus"
aks_name = "aks-acr-demo"
acr_name = "acraksdemo${random_string.suffix.result}"
}
resource "azurerm_resource_group" "rg" {
name = local.resource_group_name
location = local.location
}
resource "azurerm_container_registry" "acr" {
name = local.acr_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
sku = "Basic"
admin_enabled = false
}
resource "azurerm_kubernetes_cluster" "aks" {
name = local.aks_name
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
dns_prefix = local.aks_name
identity {
type = "SystemAssigned"
}
default_node_pool {
name = "systempool"
node_count = 2
vm_size = "Standard_D2s_v3"
upgrade_settings {
drain_timeout_in_minutes = 0
max_surge = "10%"
node_soak_duration_in_minutes = 0
}
}
}
resource "azurerm_role_assignment" "aks_acr_pull" {
scope = azurerm_container_registry.acr.id
role_definition_name = "AcrPull"
principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id
}
resource "azapi_resource_action" "import_nginx_to_acr" {
type = "Microsoft.ContainerRegistry/registries@2023-07-01"
resource_id = azurerm_container_registry.acr.id
action = "importImage"
method = "POST"
body = {
source = {
registryUri = "docker.io"
sourceImage = "library/nginx:latest"
}
targetTags = ["nginx:v1"]
mode = "Force"
}
}
provider "kubernetes" {
host = azurerm_kubernetes_cluster.aks.kube_config[0].host
client_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_certificate)
client_key = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_key)
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].cluster_ca_certificate)
}
resource "kubernetes_deployment_v1" "nginx" {
depends_on = [
azurerm_role_assignment.aks_acr_pull,
azapi_resource_action.import_nginx_to_acr
]
metadata {
name = "nginx0-deployment"
labels = {
app = "nginx0-deployment"
}
}
spec {
replicas = 2
selector {
match_labels = {
app = "nginx0"
}
}
template {
metadata {
labels = {
app = "nginx0"
}
}
spec {
container {
name = "nginx"
image = "${azurerm_container_registry.acr.login_server}/nginx:v1"
port {
container_port = 80
}
}
}
}
}
}
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "aks_cluster_name" {
value = azurerm_kubernetes_cluster.aks.name
}
output "acr_name" {
value = azurerm_container_registry.acr.name
}
output "acr_login_server" {
value = azurerm_container_registry.acr.login_server
}
設定現有 AKS 叢集的 ACR 整合
你可以將 ACR 附加到現有的 AKS 叢集,或者如果你不想讓叢集再存取登錄檔,也可以將 ACR 從 AKS 叢集中分離。
文章中前面的範例建立了一個 Azure Container Registry 和一個 Azure Kubernetes Service 叢集,並附加到 ACR。 以下是如何將容器登錄檔從叢集附加或分離,並使用本文中建立的 ACR 與 AKS 叢集的範例。 你可以用你自己的 ACR 和 AKS 叢集值替換變數值。
將 ACR 附加至現有的 AKS 叢集
利用 az aks update 帶有參數的 --attach-acr 指令將現有的 ACR 與現有的 AKS 叢集整合。
# Attach using acr-name
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--attach-acr $MYACR
# Attach using acr-resource-id
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--attach-acr $ACR_RESOURCE_ID
az aks update --attach-acr 命令會使用執行命令的使用者權限來建立 ACR 角色指派。 此角色會指派給 kubelet 受控識別。 如需 AKS 受控識別的詳細資訊,請參閱受控識別的摘要。
利用 Set-AzAksCluster 帶有參數的 -AcrNameToAttach 指令將現有的 ACR 與現有的 AKS 叢集整合。
$AttachCluster = @{
Name = $ClusterName
ResourceGroupName = $ClusterResourceGroup
AcrNameToAttach = $MyAcr
}
Set-AzAksCluster @AttachCluster
Set-AzAksCluster -AcrNameToAttach cmdlet 會使用執行命令的使用者權限來建立角色 ACR 指派。 此角色會指派給 kubelet 受控識別。 如需 AKS 受控識別的詳細資訊,請參閱受控識別的摘要。
經過測試的 Terraform 樣本會產生新的 AKS 與 ACR 資源。 要整合現有資源,請使用 Azure CLI 或 Azure PowerShell 標籤,或調整範例AcrPull的角色指派以參考你現有的資源。
將 ACR 從 AKS 叢集中分離
使用 az aks update 帶有 --detach-acr 參數的指令移除 ACR 與 AKS 叢集之間的整合。
# Detach using acr-name
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--detach-acr $MYACR
# Detach using acr-resource-id
az aks update \
--name $CLUSTER_NAME \
--resource-group $CLUSTER_RESOURCE_GROUP \
--detach-acr $ACR_RESOURCE_ID
使用 Set-AzAksCluster 帶有 -AcrNameToDetach 參數的指令移除 ACR 與 AKS 叢集之間的整合。
$DetachCluster = @{
Name = $ClusterName
ResourceGroupName = $ClusterResourceGroup
AcrNameToDetach = $MyAcr
}
Set-AzAksCluster @DetachCluster
測試過的 Terraform 範例並未定義獨立的分離式工作流程。 要在保留 AKS 和 ACR 資源的同時撤銷存取權,請從你的設定中移除 kubernetes_deployment_v1.nginx and azurerm_role_assignment.aks_acr_pull 資源,然後套用更新後的 Terraform 計畫。
初始化並部署設定
設定完成後,先初始化 Terraform,並在應用前檢視執行計畫。
terraform fmt
terraform init
terraform validate
terraform plan
terraform apply
此時,你的 AKS 叢集已設定為從 ACR 擷取映像。
您現在可以:
- 將圖片匯入 ACR。
- 將工作負載部署到 AKS。
- 驗證 pod 部署。
與ACR及AKS合作
先匯入映像到 ACR,然後部署到 AKS 叢集。
將圖片匯入您的 ACR
用 az acr import 指令從 Docker Hub 匯入一張圖片到你的 ACR。
az acr import \
--name $MYACR \
--source docker.io/library/nginx:latest \
--image nginx:v1
執行以下指令確認圖片已匯入。
az acr repository show --name $MYACR --repository nginx
az acr repository show-tags --name $MYACR --repository nginx
Terraform 範例在部署時會將 NGINX 映像匯入 ACR。
用 Import-AzContainerRegistryImage cmdlet 從 Docker Hub 匯入一張圖片到 ACR。
$ImportImage = @{
RegistryName = $MyAcr
ResourceGroupName = $AcrResourceGroup
SourceRegistryUri = 'docker.io'
SourceImage = 'library/nginx:latest'
TargetTag = 'nginx:v1'
}
Import-AzContainerRegistryImage @ImportImage
執行以下指令確認圖片已匯入。
Get-AzContainerRegistryRepository -RegistryName $MyAcr
Get-AzContainerRegistryTag -RegistryName $MyAcr -Repository nginx
建立部署檔案
建立一個參考您匯入至 ACR 之映像的 Kubernetes 部署。 如果部署成功且映像被正確拉取,代表你的 AKS 叢集已成功整合 ACR。
使用以下範例 YAML建立一個名為 acr-nginx.yaml 的檔案。 在image 屬性中,將 ACR-name 替換為你的 ACR 名稱。 在Azure CLI中,執行 echo $MYACR 以顯示 ACR 名稱。 在Azure PowerShell中,執行 $MyAcr 顯示 ACR 名稱。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx0-deployment
labels:
app: nginx0-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx0
template:
metadata:
labels:
app: nginx0
spec:
containers:
- name: nginx
image: <acr-name>.azurecr.io/nginx:v1
ports:
- containerPort: 80
取得憑證並執行部署
使用
az aks get-credentials命令確定您有適當的 AKS 認證。az aks get-credentials \ --resource-group $CLUSTER_RESOURCE_GROUP \ --name $CLUSTER_NAME使用
kubectl apply命令在 AKS 叢集中執行部署。kubectl apply -f acr-nginx.yaml使用
kubectl get pods命令監視部署。kubectl get pods輸出應該會顯示兩個執行中的 Pod,如下列範例輸出所示:
NAME READY STATUS RESTARTS AGE nginx0-deployment-669dfc4d4b-x74kr 1/1 Running 0 20s nginx0-deployment-669dfc4d4b-xdpd6 1/1 Running 0 20s
Terraform 範例會在 terraform apply 期間設定 Kubernetes 提供者,並部署 NGINX 工作負載。 取得叢集憑證,然後驗證部署:
RESOURCE_GROUP=$(terraform output -raw resource_group_name)
CLUSTER_NAME=$(terraform output -raw aks_cluster_name)
az aks get-credentials \
--resource-group $RESOURCE_GROUP \
--name $CLUSTER_NAME
kubectl get pods
請確定您有適當的 AKS 認證,並使用
Import-AzAksCredentialCmdlet。Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName使用
kubectl apply命令在 AKS 叢集中執行部署。kubectl apply -f acr-nginx.yaml使用
kubectl get pods命令監視部署。kubectl get pods輸出應該會顯示兩個執行中的 Pod,如下列範例輸出所示:
NAME READY STATUS RESTARTS AGE nginx0-deployment-669dfc4d4b-x74kr 1/1 Running 0 20s nginx0-deployment-669dfc4d4b-xdpd6 1/1 Running 0 20s
疑難排解
- 使用
az aks check-acr命令確認可從 AKS 叢集存取登錄。 - 如果你的 AKS 叢集使用 HTTP 代理,而 ACR 使用 Private Link,請將兩個 ACR 端點(REST 和資料)加入叢集
noProxy清單。 如需詳細資訊,請參閱 Azure Kubernetes Service (AKS) 中的 HTTP Proxy 支援。 - 深入了解 ACR 監控。
- 深入了解 ACR 健康情況。
清理資源
當你不再需要本文中建立的資源時,可以刪除資源群組,移除所有相關資源。 這些指令會刪除 ACR 和 AKS 叢集,以及叢集以 . 開頭 MC_的節點資源群組。
az group delete --name $ACR_RESOURCE_GROUP --yes --no-wait
az group delete --name $CLUSTER_RESOURCE_GROUP --yes --no-wait
從包含 Terraform 設定的目錄執行以下指令:
terraform destroy
Remove-AzResourceGroup -Name $AcrResourceGroup -Force
Remove-AzResourceGroup -Name $ClusterResourceGroup -Force