安装使用现有应用程序网关的应用程序网关入口控制器 (AGIC)
应用程序网关入口控制器 (AGIC) 是 Azure Kubernetes 服务 (AKS) 群集中的一个 pod。 AGIC 监视 Kubernetes 入口资源,并根据 Kubernetes 群集状态创建和应用应用程序网关配置。
轮廓
- 先决条件
- Azure 资源管理器身份验证
- 选项 1:设置 Microsoft Entra 工作负载 ID 并在 ARM 上创建 Azure 标识
- 选项 2:设置服务主体
- 使用 Helm 安装入口控制器
- 共享应用程序网关:将 AGIC 安装在一个可以在一个 AKS 群集和/或其他 Azure 组件之间共享应用程序网关的环境中。
先决条件
本文档假设已安装以下工具和基础结构:
- 使用 Azure 容器网络接口 (CNI) 的 AKS 群集
- AKS 群集所在的同一虚拟网络中的应用程序网关 v2
- 为 AKS 群集配置的 Microsoft Entra 工作负载 ID
在安装 AGIC 之前,请备份应用程序网关的配置:
- 从 Azure 门户 导航到应用程序网关实例。
- 在“自动化”部分下,选择“导出模板”,然后选择“下载”。
下载的 zip 文件包含 JSON 模板、bash 和 PowerShell 脚本,你可以根据需要使用它们来还原应用网关
安装 Helm
Helm 是 Kubernetes 的包管理器,用于安装 application-gateway-kubernetes-ingress
包。
安装 Helm 并运行以下命令:
- 已启用 Kubernetes RBAC 的 AKS 群集
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
Azure 资源管理器身份验证
AGIC 与 Kubernetes API 服务器和 Azure 资源管理器通信。 它需要一个标识来访问这些 API。
设置 Microsoft Entra 工作负载 ID
Microsoft Entra 工作负载 ID 是分配给软件工作负载,用于进行身份验证和访问其他服务和资源的标识。 此标识使 AKS Pod 能够使用此标识并与其他 Azure 资源进行身份验证。 我们需要为此配置授权 AGIC pod 向 ARM 发出 HTTP 请求。
使用 Azure CLI az account set 命令将特定订阅设置为当前活动订阅。 然后使用 az identity create 命令创建托管标识。 需要在 节点资源组 中创建标识。 默认情况下会为节点资源组分配一个名称,例如 MC_myResourceGroup_myAKSCluster_chinanorth2。
az account set --subscription "subscriptionID"
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 权限委托给应用程序网关部署到的子网。 如果未使用此权限定义自定义角色,则可以使用包含 Microsoft.Network/virtualNetworks/subnets/join/action 权限的内置“网络参与者”角色。
使用服务主体
还可以使用 Kubernetes 机密为 AGIC 提供对 ARM 的访问权限。
创建 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
的详细信息。armAuth: type: servicePrincipal secretJSON: <Base64-Encoded-Credentials>
部署 Azure 应用程序网关入口控制器加载项
创建入口控制器部署清单
---
# 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 图表的形式安装入口控制器
前几个步骤在 Kubernetes 群集上安装了 Helm 的 Tiller。 安装 AGIC Helm 包:
执行 helm 更新
helm repo update
下载 helm-config.yaml,用于配置 AGIC:
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> environment: AzureChinaCloud # 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 工作负载 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.environment=AzureChinaCloud \ --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.chinanorth2.azmk8s.io
检查新建 pod 的日志,以确认它是否已正确启动
请参阅此操作指南,了解如何使用 Azure 应用程序网关通过 HTTP 或 HTTPS 向 Internet 公开 AKS 服务。
共享应用程序网关
默认情况下,AGIC 对它所链接到的应用程序网关拥有完全所有权。 AGIC 0.8.0 和更高版本可与其他 Azure 组件共享单个应用程序网关。 例如,我们可以对虚拟机规模集上托管的某个应用以及某个 AKS 群集使用同一个应用程序网关。
在启用此设置之前,请备份应用程序网关的配置:
- 从 Azure 门户导航到
Application Gateway
实例 - 在“自动化”部分下,选择“导出模板”,然后选择“下载”。
下载的 zip 文件包含可用于还原应用程序网关的 JSON 模板、bash 和 PowerShell 脚本
示例方案
让我们探讨一个虚构的应用程序网关,它将管理两个网站的流量:
dev.contoso.com
- 托管在新 AKS 群集上,使用应用程序网关和 AGICprod.contoso.com
- 托管在 Azure 虚拟机规模集上
使用默认设置时,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(0.8.0 和更高版本)限制为一部分应用程序网关配置,请修改 helm-config.yaml
模板。
在 appgw:
节下,添加 shared
键并将其设置为 true
。
appgw:
subscriptionId: <subscriptionId> # existing field
resourceGroup: <resourceGroupName> # existing field
name: <applicationGatewayName> # existing field
environment: AzureChinaCloud # 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
添加到现有的应用程序网关,但需要将此网关托管在 VM 上。 我们将重复使用现有的应用程序网关,并为 staging.contoso.com
手动配置侦听器和后端池。 但是,手动调整应用程序网关配置(使用门户、ARM 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
相关的应用程序网关配置。