虽然你可以通过 Azure 负载均衡器路由出口流量,但可以创建的出站流量的流数量有限制。 Azure NAT 网关允许每个 IP 地址最多 64,512 个出站 UDP 和 TCP 流量流,并且最多只能有 16 个 IP 地址。
本文介绍了如何创建一个带有托管 NAT 网关和用户分配的 NAT 网关的 Azure Kubernetes 服务 (AKS) 集群,用于处理出口流量。 它还演示了如何在 Windows 上禁用 OutboundNAT。
开始之前
- 确保使用最新版本的 Azure CLI。
- 请确保使用的是 Kubernetes 版本 1.20.x 或更高版本。
- 托管 NAT 网关与自定义虚拟网络不兼容。
重要
在非专用群集中,API 服务器群集流量是通过群集出站类型路由和处理的。 若要防止 API 服务器流量作为公共流量进行处理,请考虑使用 专用群集。
创建带有托管 NAT 网关的 AKS 群集
- 使用带有
az aks create
、--outbound-type managedNATGateway
、--nat-gateway-managed-outbound-ip-count
参数的--nat-gateway-idle-timeout
命令创建具有新的托管 NAT 网关的 AKS 群集。 如果希望 NAT 网关从特定可用性区域运行,请使用--zones
指定区域。 - 如果在创建托管 NAT 网关时未指定任何区域,则默认情况下,NAT 网关将部署到“无区域”。 将 NAT 网关放置在“无区域”中时,Azure 会将资源放置在某个区域中。 有关非区域性部署模型的详细信息,请参阅非区域性 NAT 网关。
- 托管 NAT 网关资源不能跨多个可用性区域使用。
以下命令首先创建所需的资源组,然后使用托管 NAT 网关创建 AKS 群集。
export RANDOM_SUFFIX=$(openssl rand -hex 3)
export MY_RG="myResourceGroup$RANDOM_SUFFIX"
export MY_AKS="myNatCluster$RANDOM_SUFFIX"
az group create --name $MY_RG --location "eastus2"
结果:
{
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx",
"location": "eastus2",
"managedBy": null,
"name": "myResourceGroupxxx",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
az aks create \
--resource-group $MY_RG \
--name $MY_AKS \
--node-count 3 \
--outbound-type managedNATGateway \
--nat-gateway-managed-outbound-ip-count 2 \
--nat-gateway-idle-timeout 4 \
--generate-ssh-keys
结果:
{
"aadProfile": null,
"agentPoolProfiles": [
{
...
"name": "nodepool1",
...
"provisioningState": "Succeeded",
...
}
],
"dnsPrefix": "myNatClusterxxx-dns-xxx",
"fqdn": "myNatClusterxxx-dns-xxx.xxxxx.xxxxxx.chinacloudapp.cn",
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myResourceGroupxxx/providers/Microsoft.ContainerService/managedClusters/myNatClusterxxx",
"name": "myNatClusterxxx",
...
"resourceGroup": "myResourceGroupxxx",
...
"provisioningState": "Succeeded",
...
"type": "Microsoft.ContainerService/ManagedClusters"
}
- 使用带
az aks update
或--nat-gateway-managed-outbound-ip-count
参数的--nat-gateway-idle-timeout
命令更新出站 IP 地址或空闲超时。
以下示例将 AKS 群集的 NAT 网关托管出站 IP 计数更新为 5。
az aks update \
--resource-group $MY_RG \
--name $MY_AKS \
--nat-gateway-managed-outbound-ip-count 5
结果:
{
"aadProfile": null,
"agentPoolProfiles": [
{
...
"name": "nodepool1",
...
"provisioningState": "Succeeded",
...
}
],
"dnsPrefix": "myNatClusterxxx-dns-xxx",
"fqdn": "myNatClusterxxx-dns-xxx.xxxxx.xxxxxx.chinacloudapp.cn",
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myResourceGroupxxx/providers/Microsoft.ContainerService/managedClusters/myNatClusterxxx",
"name": "myNatClusterxxx",
...
"resourceGroup": "myResourceGroupxxx",
...
"provisioningState": "Succeeded",
...
"type": "Microsoft.ContainerService/ManagedClusters"
}
创建带有用户分配的 NAT 网关的 AKS 群集
此配置需要自带网络(通过 Kubenet 或 Azure CNI),并且需要在子网中预配置 NAT 网关。 以下命令为此方案创建所需的资源。
使用
az group create
命令创建资源组。export RANDOM_SUFFIX=$(openssl rand -hex 3) export MY_RG="myResourceGroup$RANDOM_SUFFIX" az group create --name $MY_RG --location southcentralus
结果:
{ "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx", "location": "southcentralus", "managedBy": null, "name": "myResourceGroupxxx", "properties": { "provisioningState": "Succeeded" }, "tags": null, "type": "Microsoft.Resources/resourceGroups" }
创建托管标识以获取网络权限,并将 ID 存储到
$IDENTITY_ID
中供稍后使用。export IDENTITY_NAME="myNatClusterId$RANDOM_SUFFIX" export IDENTITY_ID=$(az identity create \ --resource-group $MY_RG \ --name $IDENTITY_NAME \ --location southcentralus \ --query id \ --output tsv)
结果:
/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myNatClusterIdxxx
使用
az network public-ip create
命令为 NAT 网关创建公共 IP。export PIP_NAME="myNatGatewayPip$RANDOM_SUFFIX" az network public-ip create \ --resource-group $MY_RG \ --name $PIP_NAME \ --location southcentralus \ --sku standard
结果:
{ "publicIp": { "ddosSettings": null, "dnsSettings": null, "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.Network/publicIPAddresses/myNatGatewayPipxxx", "ipAddress": null, "ipTags": [], "location": "southcentralus", "name": "myNatGatewayPipxxx", ... "provisioningState": "Succeeded", ... "sku": { "name": "Standard", "tier": "Regional" }, "type": "Microsoft.Network/publicIPAddresses", ... } }
使用
az network nat gateway create
命令创建 NAT 网关。export NATGATEWAY_NAME="myNatGateway$RANDOM_SUFFIX" az network nat gateway create \ --resource-group $MY_RG \ --name $NATGATEWAY_NAME \ --location southcentralus \ --public-ip-addresses $PIP_NAME
结果:
{ "etag": "W/\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\"", "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.Network/natGateways/myNatGatewayxxx", "location": "southcentralus", "name": "myNatGatewayxxx", "provisioningState": "Succeeded", "publicIpAddresses": [ { "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.Network/publicIPAddresses/myNatGatewayPipxxx" } ], ... "type": "Microsoft.Network/natGateways" }
重要
单个 NAT 网关资源不能跨多个可用性区域使用。 为了确保区域复原能力,建议将 NAT 网关资源部署到每个可用性区域,并分配给每个区域中包含 AKS 群集的子网。 有关此部署模型的详细信息,请参阅每个区域的 NAT 网关。 如果未为 NAT 网关配置任何区域,则默认区域放置为“无区域”,其中 Azure 会将 NAT 网关放入一个区域中。
使用
az network vnet create
命令创建虚拟网络。export VNET_NAME="myVnet$RANDOM_SUFFIX" az network vnet create \ --resource-group $MY_RG \ --name $VNET_NAME \ --location southcentralus \ --address-prefixes 172.16.0.0/20
结果:
{ "newVNet": { "addressSpace": { "addressPrefixes": [ "172.16.0.0/20" ] }, ... "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.Network/virtualNetworks/myVnetxxx", "location": "southcentralus", "name": "myVnetxxx", "provisioningState": "Succeeded", ... "type": "Microsoft.Network/virtualNetworks", ... } }
使用 NAT 网关在虚拟网络中创建子网,并将 ID 存储到
$SUBNET_ID
中供稍后使用。export SUBNET_NAME="myNatCluster$RANDOM_SUFFIX" export SUBNET_ID=$(az network vnet subnet create \ --resource-group $MY_RG \ --vnet-name $VNET_NAME \ --name $SUBNET_NAME \ --address-prefixes 172.16.0.0/22 \ --nat-gateway $NATGATEWAY_NAME \ --query id \ --output tsv)
结果:
/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.Network/virtualNetworks/myVnetxxx/subnets/myNatClusterxxx
使用
az aks create
命令通过具有 NAT 网关和托管标识的子网创建 AKS 群集。export AKS_NAME="myNatCluster$RANDOM_SUFFIX" az aks create \ --resource-group $MY_RG \ --name $AKS_NAME \ --location southcentralus \ --network-plugin azure \ --vnet-subnet-id $SUBNET_ID \ --outbound-type userAssignedNATGateway \ --assign-identity $IDENTITY_ID \ --generate-ssh-keys
结果:
{ "aadProfile": null, "agentPoolProfiles": [ { ... "name": "nodepool1", ... "provisioningState": "Succeeded", ... } ], "dnsPrefix": "myNatClusterxxx-dns-xxx", "fqdn": "myNatClusterxxx-dns-xxx.xxxxx.xxxxxx.chinacloudapp.cn", "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myResourceGroupxxx/providers/Microsoft.ContainerService/managedClusters/myNatClusterxxx", "name": "myNatClusterxxx", ... "resourceGroup": "myResourceGroupxxx", ... "provisioningState": "Succeeded", ... "type": "Microsoft.ContainerService/ManagedClusters" }
为 Windows 禁用 OutboundNAT
Windows OutboundNAT 可能导致 AKS Pod 出现某些连接和通信问题。 一个示例问题是节点端口重用。 在此示例中,Windows OutboundNAT 使用端口将 Pod IP 转换为 Windows 节点主机 IP,这可能会因端口耗尽问题而导致与外部服务的连接不稳定。
Windows 默认会启用 OutboundNAT。 现在可以在创建新的 Windows 代理池时手动禁用 OutboundNAT。
先决条件
- 具有 v1.26 或更高版本的现有 AKS 群集。 如果使用的是 Kubernetes 1.25 或更低版本,则需要更新部署配置。
限制
- 无法将群集出站类型设置为 LoadBalancer。 可以将它设置为 NAT 网关或 UDR:
- NAT 网关:NAT 网关可以自动处理 NAT 连接,并且比标准负载均衡器更强大。 此选项可能会产生额外费用。
- UDR (UserDefinedRouting):配置传递规则时,必须牢记端口限制。
- 如果需要从负载均衡器切换到 NAT 网关,则可以将 NAT 网关添加到 VNet 中,或运行
az aks upgrade
以更新出站类型。
注意
UserDefinedRouting 具有以下限制:
- Azure 负载均衡器的 SNAT(必须使用默认 OutboundNAT)具有“主机 IP 上的 64 个端口”。
- Azure 防火墙的 SNAT(禁用 OutboundNAT)对每个公共 IP 有 2496 个端口。
- NAT 网关的 SNAT(禁用 OutboundNAT)对每个公共 IP 有 64512 个端口。
- 如果 Azure 防火墙端口范围对于应用程序来说不够用,则需要使用 NAT 网关。
- 如果目标 IP 地址在符合 IANA RFC 1918 的专用 IP 地址范围内或符合 IANA RFC 6598 的共享地址空间内,Azure 防火墙将不使用网络规则执行 SNAT。
手动为 Windows 禁用 OutboundNAT
在使用带有
az aks nodepool add
标记的--disable-windows-outbound-nat
命令创建新的 Windows 代理池时,可以手动为 Windows 禁用 OutboundNAT。注意
可以使用现有的 AKS 群集,但可能需要更新出站类型并添加节点池以启用
--disable-windows-outbound-nat
。以下命令将 Windows 节点池添加到现有 AKS 群集,禁用 OutboundNAT。
export WIN_NODEPOOL_NAME="win$(head -c 1 /dev/urandom | xxd -p)" az aks nodepool add \ --resource-group $MY_RG \ --cluster-name $MY_AKS \ --name $WIN_NODEPOOL_NAME \ --node-count 3 \ --os-type Windows \ --disable-windows-outbound-nat
结果:
{ "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroupxxx/providers/Microsoft.ContainerService/managedClusters/myNatClusterxxx/agentPools/mynpxxx", "name": "mynpxxx", "osType": "Windows", "provisioningState": "Succeeded", "resourceGroup": "myResourceGroupxxx", "type": "Microsoft.ContainerService/managedClusters/agentPools" }
后续步骤
有关 Azure NAT 网关的详细信息,请参阅 Azure NAT 网关。