你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用现有应用程序网关部署安装 AGIC
应用程序网关入口控制器 (AGIC) 是 Azure Kubernetes 服务 (AKS) 群集中的一个 pod。 AGIC 监视 Kubernetes 入口资源。 它根据 Kubernetes 群集的状态创建并应用 Azure 应用程序网关配置。
提示
请考虑将适用于容器的应用程序网关用作 Kubernetes 入口解决方案。 有关详细信息,请参阅快速入门:为容器 ALB 控制器部署应用程序网关。
先决条件
本文档假设你已安装以下工具和基础结构:
- 使用 Azure 容器网络接口 (CNI) 的 AKS 群集。
- AKS 群集所在的同一虚拟网络中的应用程序网关 v2。
- 为 AKS 群集配置的 Microsoft Entra 工作负载 ID。
- Azure Cloud Shell 是 Azure Shell 环境,它已安装
az
(Azure CLI)、kubectl
和helm
。 支持配置此部署的命令需要这些工具。
添加 Helm 存储库
Helm 是 Kubernetes 的包管理器。 你使用它来安装 application-gateway-kubernetes-ingress
包:
如果使用 Cloud Shell,则无需安装 Helm。 Helm 版本 3 附带了 Cloud Shell。 运行以下命令,为启用了 Kubernetes 基于角色的访问控制 (RBAC) 的 AKS 群集添加 AGIC Helm 存储库:
kubectl create serviceaccount --namespace kube-system tiller-sa
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller-sa
helm init --tiller-namespace kube-system --service-account tiller-sa
备份应用程序网关部署
在安装 AGIC 之前,请备份应用程序网关部署的配置:
- 在 Azure 门户中,转到你的应用程序网关部署。
- 在“自动化”部分中,选择“导出模板”,然后选择“下载”。
下载的 .zip 文件包含 JSON 模板、Bash 脚本和 PowerShell 脚本,可用于还原应用程序网关(如果需要还原)。
设置用于资源管理器身份验证的标识
AGIC 与 Kubernetes API 服务器和 Azure 资源管理器通信。 它需要一个标识来访问这些 API。 你可以使用 Microsoft Entra Workload ID 或服务主体。
设置 Microsoft Entra 工作负载 ID
Microsoft Entra Workload ID 是分配给软件工作负载的标识。 AKS Pod 能够使用此标识向其他 Azure 资源证明身份。
对于此配置,你需要授权 AGIC pod 向 Azure 资源管理器发出 HTTP 请求。
使用 Azure CLI az account set 命令将特定订阅设置为当前处于活动状态的订阅:
az account set --subscription "subscriptionID"
然后使用 az identity create 命令创建托管标识。 你必须在节点资源组中创建该标识。 默认情况下,会为节点资源组分配一个名称,例如
MC_myResourceGroup_myAKSCluster_eastus
。az identity create --name "userAssignedIdentityName" --resource-group "resourceGroupName" --location "location" --subscription "subscriptionID"
对于角色分配,请运行以下命令来识别新创建的标识的
principalId
值:$resourceGroup="resource-group-name" $identityName="identity-name" az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv
授予该标识对应用程序网关部署的“参与者”访问权限。 你需要应用程序网关部署的 ID,示例如下所示:
/subscriptions/A/resourceGroups/B/providers/Microsoft.Network/applicationGateways/C
。首先,通过运行以下命令获取订阅中应用程序网关 ID 的列表:
az network application-gateway list --query '[].id'
运行以下命令,以向标识分配 参与者 访问权限:
$resourceGroup="resource-group-name" $identityName="identity-Name" # Get the Application Gateway ID $AppGatewayID=$(az network application-gateway list --query '[].id' -o tsv) $role="contributor" # Get the principal ID for the user-assigned identity $principalId=$(az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv) az role assignment create --assignee $principalId --role $role --scope $AppGatewayID
授予标识对应用程序网关资源组的 读取 访问权限。 资源组 ID 格式示例如下所示:
/subscriptions/A/resourceGroups/B
。 可以运行以下命令来获取所有资源组:az group list --query '[].id'
$resourceGroup="resource-group-name" $identityName="identity-Name" # Get the Application Gateway resource group $AppGatewayResourceGroup=$(az network application-gateway list --query '[].resourceGroup' -o tsv) # Get the Application Gateway resource group ID $AppGatewayResourceGroupID=$(az group show --name $AppGatewayResourceGroup --query id -o tsv) $role="Reader" # Get the principal ID for the user-assigned identity $principalId=$(az identity list -g $resourceGroup --query "[?name == '$identityName'].principalId | [0]" -o tsv) # Assign the Reader role to the user-assigned identity at the resource group scope az role assignment create --role $role --assignee $principalId --scope $AppGatewayResourceGroupID
注意
请确保 AGIC 使用的标识已将 Microsoft.Network/virtualNetworks/subnets/join/action 权限委托给应用程序网关部署到的子网。 如果你未定义具有此权限的自定义角色,则可以使用内置的“网络参与者”角色。
设置服务主体
还可以使用 Kubernetes 机密为 AGIC 提供对 Azure 资源管理器的访问权限。
创建一个 Active Directory 服务主体并使用 Base64 对其进行编码。 JSON Blob 需要使用 Base64 编码才能保存到 Kubernetes 中。
az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0
将 Base64 编码的 JSON Blob 添加到
helm-config.yaml
文件中。helm-config.yaml
文件对 AGIC 进行配置。armAuth: type: servicePrincipal secretJSON: <Base64-Encoded-Credentials>
部署 AGIC 加载项
为入口控制器创建部署清单
---
# file: pet-supplies-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pet-supplies-ingress
spec:
ingressClassName: azure-application-gateway
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: store-front
port:
number: 80
- path: /order-service
pathType: Prefix
backend:
service:
name: order-service
port:
number: 3000
- path: /product-service
pathType: Prefix
backend:
service:
name: product-service
port:
number: 3002
部署入口控制器
$namespace="namespace"
$file="pet-supplies-ingress.yaml"
kubectl apply -f $file -n $namespace
将入口控制器安装为 Helm 图表
使用 Cloud Shell 安装 AGIC Helm 包:
执行 Helm 更新:
helm repo update
下载
helm-config.yaml
:wget https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/master/docs/examples/sample-helm-config.yaml -O helm-config.yaml
或者复制以下 YAML 文件:
# This file contains the essential configs for the ingress controller helm chart # Verbosity level of the App Gateway Ingress Controller verbosityLevel: 3 ################################################################################ # Specify which application gateway the ingress controller must manage # appgw: subscriptionId: <subscriptionId> resourceGroup: <resourceGroupName> name: <applicationGatewayName> # Setting appgw.shared to "true" creates an AzureIngressProhibitedTarget CRD. # This prohibits AGIC from applying config for any host/path. # Use "kubectl get AzureIngressProhibitedTargets" to view and change this. shared: false ################################################################################ # Specify which kubernetes namespace the ingress controller must watch # Default value is "default" # Leaving this variable out or setting it to blank or empty string would # result in Ingress Controller observing all accessible namespaces. # # kubernetes: # watchNamespace: <namespace> ################################################################################ # Specify the authentication with Azure Resource Manager # # Two authentication methods are available: # - Option 1: Azure-AD-workload-identity armAuth: type: workloadIdentity identityClientID: <identityClientId> ## Alternatively you can use Service Principal credentials # armAuth: # type: servicePrincipal # secretJSON: <<Generate this value with: "az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0" >> ################################################################################ # Specify if the cluster is Kubernetes RBAC enabled or not rbac: enabled: false # true/false # Specify aks cluster related information. THIS IS BEING DEPRECATED. aksClusterConfiguration: apiServerAddress: <aks-api-server-address>
编辑
helm-config.yaml
并填写appgw
和armAuth
的值。注意
<identity-client-id>
是你在上一部分中设置的 Microsoft Entra Workload ID 值的一个属性。 可以通过运行以下命令来检索此信息:az identity show -g <resourcegroup> -n <identity-name>
。 在该命令中,<resourcegroup>
是托管与 AKS 群集、应用程序网关和托管标识相关的基础结构资源的资源组。使用上一步骤中的
helm-config.yaml
配置安装 Helm 图表:helm install agic-controller oci://mcr.microsoft.com/azure-application-gateway/charts/ingress-azure --version 1.7.5 -f helm-config.yaml
或者,可以在一个步骤中结合使用
helm-config.yaml
和 Helm 命令:helm install oci://mcr.microsoft.com/azure-application-gateway/charts/ingress-azure \ --name agic-controller \ --version 1.7.5 \ --namespace default \ --debug \ --set appgw.name=applicationgatewayABCD \ --set appgw.resourceGroup=your-resource-group \ --set appgw.subscriptionId=subscription-uuid \ --set appgw.shared=false \ --set armAuth.type=servicePrincipal \ --set armAuth.secretJSON=$(az ad sp create-for-rbac --role Contributor --sdk-auth | base64 -w0) \ --set rbac.enabled=true \ --set verbosityLevel=3 \ --set kubernetes.watchNamespace=default \ --set aksClusterConfiguration.apiServerAddress=aks-abcdefg.hcp.westus2.azmk8s.io
检查新建 pod 的日志,以确认它是否已正确启动。
若要了解如何使用 Azure 应用程序网关部署通过 HTTP 或 HTTPS 向 Internet 公开 AKS 服务,请参阅此操作指南。
设置共享应用程序网关部署
默认情况下,AGIC 对它所链接到的应用程序网关部署拥有完全所有权。 AGIC 0.8.0 和更高版本可与其他 Azure 组件共享单个应用程序网关部署。 例如,你可以对 Azure 虚拟机规模集上和 AKS 群集上托管的应用使用同一个应用程序网关部署。
示例方案
让我们探讨一个虚构的应用程序网关部署,该部署管理两个网站的流量:
dev.contoso.com
:托管在新 AKS 群集上,使用应用程序网关和 AGIC。prod.contoso.com
:托管在虚拟机规模集上。
使用默认设置时,AGIC 拥有它所指向的应用程序网关部署的完全所有权。 AGIC 将覆盖所有应用程序网关配置。 如果你在应用程序网关上手动为 prod.contoso.com
创建侦听器,但未在 Kubernetes 入口中定义该侦听器,则 AGIC 很快就会删除 prod.contoso.com
配置。
若要安装 AGIC 并从使用虚拟机规模集的计算机为 prod.contoso.com
提供服务,必须将 AGIC 约束为仅配置 dev.contoso.com
。 你可以通过实例化以下自定义资源定义 (CRD) 来帮助实现此约束:
cat <<EOF | kubectl apply -f -
apiVersion: "appgw.ingress.k8s.io/v1"
kind: AzureIngressProhibitedTarget
metadata:
name: prod-contoso-com
spec:
hostname: prod.contoso.com
EOF
上述命令创建一个 AzureIngressProhibitedTarget
对象。 此对象使 AGIC(版本 0.8.0 及更高版本)知道存在 prod.contoso.com
的应用程序网关配置。 此对象还显式指示 AGIC 避免更改与该主机名相关的任何配置。
使用新的 AGIC 安装启用共享应用程序网关部署
若要将 AGIC(0.8.0 和更高版本)限制为一部分应用程序网关配置,请修改 helm-config.yaml
模板。
在 appgw:
节中,添加一个 shared
键并将其设置为 true
:
appgw:
subscriptionId: <subscriptionId> # existing field
resourceGroup: <resourceGroupName> # existing field
name: <applicationGatewayName> # existing field
shared: true # Add this field to enable shared Application Gateway
应用 Helm 更改:
确保已安装
AzureIngressProhibitedTarget
CRD:kubectl apply -f https://raw.githubusercontent.com/Azure/application-gateway-kubernetes-ingress/7b55ad194e7582c47589eb9e78615042e00babf3/crds/AzureIngressProhibitedTarget-v1-CRD-v1.yaml
更新 Helm:
helm upgrade \ --recreate-pods \ -f helm-config.yaml \ agic-controller oci://mcr.microsoft.com/azure-application-gateway/charts/ingress-azure
因此,AKS 群集有一个名为 prohibit-all-targets
的 AzureIngressProhibitedTarget
新实例:
kubectl get AzureIngressProhibitedTargets prohibit-all-targets -o yaml
prohibit-all-targets
对象禁止 AGIC 更改任何主机和路径的配置。 使用 appgw.shared=true
安装 Helm 会部署 AGIC,但不会对应用程序网关进行任何更改。
放宽权限
由于带有 appgw.shared=true
和默认 prohibit-all-targets
的 Helm 会阻止 AGIC 应用某个配置,因此你必须放宽 AGIC 权限:
使用以下代码片段创建名为
AzureIngressProhibitedTarget
的新 YAML 文件,其中包含特定设置:cat <<EOF | kubectl apply -f - apiVersion: "appgw.ingress.k8s.io/v1" kind: AzureIngressProhibitedTarget metadata: name: your-custom-prohibitions spec: hostname: your.own-hostname.com EOF
现在,你已创建了自己的自定义禁止规则,接下来可以删除默认的禁止规则(该规则过于宽泛):
kubectl delete AzureIngressProhibitedTarget prohibit-all-targets
为现有 AGIC 安装启用共享应用程序网关部署
假设你已有一个正常运行的 AKS 群集和应用程序网关部署,并且你已在群集中配置了 AGIC。 你有 prod.contoso.com
的入口,并且能够成功地从群集为它提供流量。
你希望将 staging.contoso.com
添加到现有应用程序网关部署,但需要将其托管在虚拟机上。 你将重复使用现有的应用程序网关部署,并为 staging.contoso.com
手动配置侦听器和后端池。 但是,手动调整应用程序网关配置(使用 Azure 门户、资源管理器 API 或 Terraform)将与 AGIC 拥有完全所有权的事实相冲突。 应用更改后不久,AGIC 会覆盖或删除这些更改。
你可以禁止 AGIC 对一部分配置进行更改。
使用以下代码片段创建名为
AzureIngressProhibitedTarget
的一个新 YAML 文件:cat <<EOF | kubectl apply -f - apiVersion: "appgw.ingress.k8s.io/v1" kind: AzureIngressProhibitedTarget metadata: name: manually-configured-staging-environment spec: hostname: staging.contoso.com EOF
查看新建的对象:
kubectl get AzureIngressProhibitedTargets
从 Azure 门户修改应用程序网关配置。 例如,添加侦听器、路由规则和后端。 你创建的新对象 (
manually-configured-staging-environment
) 禁止 AGIC 覆盖与staging.contoso.com
相关的应用程序网关配置。