在 Azure Kubernetes 服务 (AKS) 中结合自己的 IP 地址范围使用 kubenet 网络
默认情况下,AKS 群集使用 kubenet,并为你创建 Azure 虚拟网络和子网。 节点使用 kubenet 从 Azure 虚拟网络子网获取 IP 地址。 Pod 接收从逻辑上不同的地址空间到节点的 Azure 虚拟网络子网的 IP 地址。 然后配置网络地址转换 (NAT),以便 Pod 可以访问 Azure 虚拟网络上的资源。 流量的源 IP 地址通过 NAT 转换为节点的主 IP 地址。 这种方法大大减少了需要在网络空间中保留供 Pod 使用的 IP 地址数量。
借助 Azure 容器网络接口 (CNI),每个 Pod 都可以从子网获得 IP 地址,并且可供直接访问。 这些 IP 地址必须事先计划,并且在网络空间中必须唯一。 每个节点都有一个配置参数来表示它支持的最大 Pod 数。 这样,就会为每个节点预留相应的 IP 地址数。 使用此方法需要经过更详细的规划,并且经常会耗尽 IP 地址,或者在应用程序需求增长时需要在更大的子网中重建群集。 可以在创建群集时或新建节点池时,配置可部署到节点的最大 Pod 数。 如果在创建新节点池时未指定 maxPods
,则会收到 kubenet 的默认值 110。
本文介绍如何使用 kubenet 网络来创建和使用 AKS 群集的虚拟网络子网。 有关网络选项和注意事项的详细信息,请参阅 Kubernetes 和 AKS 的网络概念。
先决条件
- AKS 群集的虚拟网络必须允许出站 Internet 连接。
- 不要在同一子网中创建多个 AKS 群集。
- AKS 群集不得将
169.254.0.0/16
、172.30.0.0/16
、172.31.0.0/16
或192.0.2.0/24
用于 Kubernetes 服务地址范围、Pod 地址范围或群集虚拟网络地址范围。 创建群集后,无法更新此范围。 - AKS 群集使用的群集标识在虚拟网络中的子网上必须至少具有网络参与者角色。 CLI 可帮助自动设置角色分配。 如果你使用 ARM 模板或其他客户端,则需要手动设置角色分配。 你还必须具有相应的权限(如订阅所有者),才能创建群集标识并向其分配权限。 如果你要定义自定义角色,而不是使用内置的网络参与者角色,则需要以下权限:
Microsoft.Network/virtualNetworks/subnets/join/action
Microsoft.Network/virtualNetworks/subnets/read
警告
若要使用 Windows Server 节点池,必须使用 Azure CNI。 kubenet 网络模型不适用于 Windows Server 容器。
准备阶段
需要安装并配置 Azure CLI 2.0.65 或更高版本。 运行 az --version
即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。
使用自有子网的 kubenet 网络概述
在许多环境中,你已定义分配了 IP 地址范围的虚拟网络和子网,并且你会使用这些资源来支持多个服务和应用程序。 若要提供网络连接,AKS 群集可以使用 kubenet(基本网络)或 Azure CNI(高级网络)。
使用 kubenet 时,只有节点接收虚拟网络子网中的 IP 地址。 Pod 无法直接相互通信。 用户定义的路由 (UDR) 和 IP 转发处理不同节点中 Pod 之间的连接。 默认情况下,UDR 和 IP 转发配置由 AKS 服务进行创建和维护,但如果需要,你可以自带路由表以进行自定义路由管理。 此外,可以在接收分配的 IP 地址的服务后面部署 Pod,并对应用程序的流量进行负载均衡。 下图显示了 AKS 节点(不是 Pod)如何接收虚拟网络子网中的 IP 地址:
Azure 在一个 UDR 中最多支持 400 个路由,因此,AKS 群集中的节点数不能超过 400 个。 kubenet 不支持 AKS 虚拟节点和 Azure 网络策略。 支持 Calico 网络策略。
使用 Azure CNI 时,每个 Pod 将接收 IP 子网中的 IP 地址,并且可以直接与其他 Pod 和服务通信。 群集的最大大小可为指定的 IP 地址范围上限。 但是,必须提前规划 IP 地址范围,AKS 节点根据它们支持的最大 Pod 数消耗所有 IP 地址。 Azure CNI 支持虚拟节点或网络策略(Azure 或 Calico)等高级网络功能和方案。
Kubenet 的限制和注意事项
- 在 Kubenet 的设计中需要额外的跃点,这会导致 Pod 通信出现轻微延迟。
- 需要路由表和用户定义的路由才能使用 Kubenet,这会增加操作的复杂性。
- 有关详细信息,请参阅在 AKS 中使用用户定义的路由表自定义群集出口和在 AKS 中使用出站类型自定义群集出口。
- 由于 Kubenet 设计,Kubenet 不支持直接 Pod 寻址。
- 与 Azure CNI 群集不同,多个 Kubenet 群集无法共享一个子网。
- AKS 不会将网络安全组 (NSG) 应用于其子网,也不会修改与该子网相关的任何 NSG。 如果提供自己的子网并添加与该子网相关的 NSG,则必须确保 NSG 中的安全规则允许节点和 Pod CIDR 之间的流量。 有关详细信息,请参阅网络安全组。
- Kubenet 不支持的功能包括:
注意
群集中的某些系统 Pod(例如 konnectivity)使用主机节点 IP 地址,而不使用覆盖地址空间中的 IP。 系统 Pod 仅使用节点 IP,而不使用虚拟网络中的 IP 地址。
IP 地址可用性和耗尽
Azure CNI 的一个常见问题是分配的 IP 地址范围太小,无法在扩展或升级群集时添加更多节点。 网络团队可能无法提供足够大的 IP 地址范围来支持预期的应用程序需求。
作为一种折衷方案,可以创建使用 kubenet 的 AKS 群集并连接到现有虚拟网络子网。 这种方法可让节点接收定义的 IP 地址,而无需提前为群集中可能运行的所有潜在 Pod 节点预留大量的 IP 地址。 使用 kubenet 时,可以大幅减小要使用的 IP 地址范围,并且可以支持大型群集和应用程序的需求。 例如,在子网上使用 /27 IP 地址范围时,可运行包括 20-25 个节点的群集,空间足以进行缩放或升级。 此群集大小最多支持 2,200-2,750 个 Pod(每个节点的最大 Pod 数默认为 110 个)。 可以在 AKS 中使用 kubenet 配置的每个节点的最大 Pod 数为 250。
以下基本计算方法对网络模型的差异做了比较:
- kubenet:一个简单的 /24 IP 地址范围可以支持群集中最多 251 个节点。 每个 Azure 虚拟网络子网保留前三个 IP 地址用于管理操作。 此节点计数最多支持 27,610 个 Pod(每个节点的最大 Pod 数默认为 110 个)。
- Azure CNI:相同的基本 /24 子网范围最多只能支持群集中的 8 个节点。 此节点数最多只能支持 240 个 Pod(每个节点的最大 Pod 数默认为 30 个)。
注意
这些最大值未考虑到帐户升级或扩展操作。 在实践中,不可能会运行子网 IP 地址范围支持的节点数上限。 必须保留一些 IP 地址用于缩放或升级操作。
虚拟网络对等互连和 ExpressRoute 连接
若要提供本地连接,kubenet 和 Azure CNI 网络方法都可以使用 Azure 虚拟网络对等互连或 ExpressRoute 连接。 精心规划 IP 地址范围,以防止地址重叠和流量路由错误。 例如,许多本地网络使用通过 ExpressRoute 连接播发的 10.0.0.0/8 地址范围。 我们建议在此地址范围之外(例如 172.16.0.0/16)的 Azure 虚拟网络子网中创建 AKS 群集。
选择要使用的网络模型
如果每种网络模型似乎都很合适,以下考虑因素可帮助你做出决策:
对于以下情况,可使用 kubenet:
- IP 地址空间有限。
- 大部分 Pod 通信在群集中进行。
- 不需要虚拟节点或 Azure 网络策略等高级 AKS 功能。
对于以下情况,可使用 Azure CNI:
- 有可用的 IP 地址空间。
- 大部分 Pod 通信是与群集外部的资源进行的。
- 不想管理用户定义的 Pod 连接路由。
- 需要虚拟节点或 Azure 网络策略等 AKS 高级功能。
有关帮助你决定使用哪个网络模型的详细信息,请参阅 [Compare network models and their support scope][network-comparisons]。
创建虚拟网络和子网
使用
az group create
命令创建资源组。az group create --name myResourceGroup --location chinaeast2
如果没有可用的现有虚拟网络和子网,请使用
az network vnet create
命令创建这些网络资源。 以下示例命令创建名为 myAKSVnet、地址前缀为 192.168.0.0/16 的虚拟网络,以及名为 myAKSSubnet、地址前缀为 192.168.1.0/24 的子网:az network vnet create \ --resource-group myResourceGroup \ --name myAKSVnet \ --address-prefixes 192.168.0.0/16 \ --subnet-name myAKSSubnet \ --subnet-prefix 192.168.1.0/24 \
使用
az network vnet subnet show
命令获取子网资源 ID,并将其存储为名为SUBNET_ID
的变量以供稍后使用。SUBNET_ID=$(az network vnet subnet show --resource-group myResourceGroup --vnet-name myAKSVnet --name myAKSSubnet --query id -o tsv)
在虚拟网络中创建 AKS 群集
创建具有系统分配的托管标识的 AKS 群集
注意
使用系统分配的标识时,Azure CLI 将在群集创建完成后向系统分配的标识授予网络参与者角色。 如果要使用 ARM 模板或其他客户端,则需要改用用户分配的托管标识。
使用
az aks create
命令创建具有系统分配的托管标识的 AKS 群集。az aks create \ --resource-group myResourceGroup \ --name myAKSCluster \ --network-plugin kubenet \ --service-cidr 10.0.0.0/16 \ --dns-service-ip 10.0.0.10 \ --pod-cidr 10.244.0.0/16 \ --vnet-subnet-id $SUBNET_ID \ --generate-ssh-keys
部署参数:
- --service-cidr 是可选的。 此地址用于为 AKS 群集中的内部服务分配 IP 地址。 此 IP 地址范围应为未在网络环境中的其他位置使用的地址空间,包括任何本地网络范围(如果你使用 Express Route 或站点到站点 VPN 连接来连接或计划连接到 Azure 虚拟网络)。 默认值为 10.0.0.0/16。
- --dns-service-ip 是可选的。 此地址应为你的服务 IP 地址范围的“.10”地址。 默认值为 10.0.0.10。
- --pod-cidr 是可选的。 此地址应该是未在网络环境中的其他位置使用的较大地址空间。 如果你需要或者打算使用 Express Route 或站点到站点 VPN 连接来连接 Azure 虚拟网络,则此范围可包括任何本地网络范围。 默认值为 10.244.0.0/16。
- 此地址范围必须足够大,可以容纳预期要扩展到的节点数。 部署群集后,无法更改此地址范围。
- Pod IP 地址范围用于将 /24 地址空间分配到群集中的每个节点。 在以下示例中,10.244.0.0/16 的 --pod-cidr 分配了第一个节点 10.244.0.0/24、第二个节点 10.244.1.0/24、第三个节点 10.244.2.0/24。
- 群集扩展或升级时,Azure 平台会继续向每个新节点分配 Pod IP 地址范围。
创建具有用户分配的托管标识的 AKS 群集
创建托管标识
使用
az identity
命令创建托管标识。 如果有一个现成的托管标识,则可以改为使用az identity show --ids <identity-resource-id>
命令来查找主体 ID。az identity create --name myIdentity --resource-group myResourceGroup
输出应与下面的示例输出类似:
{ "clientId": "<client-id>", "clientSecretUrl": "<clientSecretUrl>", "id": "/subscriptions/<subscriptionid>/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity", "location": "chinaeast2", "name": "myIdentity", "principalId": "<principal-id>", "resourceGroup": "myResourceGroup", "tags": {}, "tenantId": "<tenant-id>", "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }
为托管标识添加角色分配
如果使用 Azure CLI,则会自动添加该角色,你可以跳过此步骤。 如果使用 ARM 模板或其他客户端,则需要使用群集托管标识的主体 ID 来执行角色分配。
使用
az network vnet show
命令获取虚拟网络资源 ID,并将其存储为名为VNET_ID
的变量。VNET_ID=$(az network vnet show --resource-group myResourceGroup --name myAKSVnet --query id -o tsv)
使用
az role assignment create
命令为 AKS 群集的托管标识分配虚拟网络上的“网络参与者”权限,并提供 <principalId>。az role assignment create --assignee <control-plane-identity-principal-id> --scope $VNET_ID --role "Network Contributor" # Example command az role assignment create --assignee 22222222-2222-2222-2222-222222222222 --scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myAKSVnet" --role "Network Contributor"
注意
向 Azure 使用的群集托管标识授予的权限最长可能需要 60 分钟才能填充完成。
创建 AKS 群集
使用
az aks create
命令创建 AKS 群集,并为assign-identity
参数提供控制平面的托管标识资源 ID 以分配用户分配的托管标识。az aks create \ --resource-group myResourceGroup \ --name myAKSCluster \ --node-count 3 \ --network-plugin kubenet \ --vnet-subnet-id $SUBNET_ID \ --assign-identity <identity-resource-id> \ --generate-ssh-keys
创建 AKS 群集时,将自动创建网络安全组和路由表。 这些网络资源可以通过 AKS 控制平面进行管理。 网络安全组自动与节点上的虚拟 NIC 相关联。 路由表自动与虚拟网络子网相关联。 在你创建和公开服务时,系统会自动更新网络安全组规则和路由表。
在 kubenet 中自带子网和路由表
使用 kubenet 时,群集子网上必须存在路由表。 AKS 支持自带现有的子网和路由表。 如果自定义子网不包含路由表,AKS 会为你创建一个路由表,并在整个群集生命周期中添加规则。 如果在创建群集时自定义子网包含路由表,AKS 将在群集操作期间确认现有路由表,并相应地为云提供程序操作添加/更新规则。
警告
可以在自定义路由表中添加/更新自定义规则。 但是,规则由 Kubernetes 云提供商添加,不能更新或删除。 诸如 0.0.0.0/0 的规则必须始终存在于给定的路由表中,并映射到 Internet 网关的目标,例如 NVA 或其他出口网关。 更新规则时请小心。
了解有关设置自定义路由表的详细信息。
Kubenet 网络需要使用经过规划和组织的路由表规则才能成功路由请求。 由于此原因,需要为依赖路由表的每个群集精心维护路由表。 多个群集无法共享一个路由表,因为不同群集的 Pod CIDR 可能会相互重叠,从而导致意外路由和路由中断的情况。 在同一虚拟网络上配置多个群集或为每个群集设置专用虚拟网络时,请考虑以下限制:
- 在创建 AKS 群集之前,需要将自定义路由表与子网关联。
- 创建群集后,无法更新关联的路由表资源。 但是,可以在路由表中修改自定义规则。
- 每个 AKS 群集必须为与群集关联的所有子网使用同一个唯一的路由表。 由于可能存在重叠的 Pod CIDR 和发生路由规则冲突,无法对多个群集重复使用同一个路由表。
- 对于系统分配的托管标识,仅支持通过 Azure CLI 提供你自己的子网和路由表,因为 Azure CLI 会自动添加角色分配。 如果要使用 ARM 模板或其他客户端,你必须使用用户分配的托管标识,在创建群集之前分配权限,并确保用户分配的标识对你的自定义子网和自定义路由表具有写入权限。
- 不支持对多个 AKS 群集使用同一路由表。
注意
通过 kubenet 网络插件创建和使用自己的 VNet 和路由表时,必须为群集配置用户分配的托管标识。 使用系统分配的托管标识,你无法在创建群集之前检索标识 ID,这会导致在角色分配过程中出现延迟。
通过 Azure 网络插件创建和使用你自己的 VNet 和路由表时,系统分配和用户分配的托管标识均受支持。 强烈建议为 BYO 方案使用用户分配的托管标识。
将具有用户分配的托管标识的路由表添加到 AKS 群集
创建自定义路由表并将其与虚拟网络中的子网相关联后,可以创建新的 AKS 群集,使用用户分配的托管标识指定路由表。 需要使用计划将 AKS 群集部署到的子网 ID。 此子网还必须与自定义路由表关联。
使用
az network vnet subnet list
命令获取子网 ID。az network vnet subnet list --resource-group myResourceGroup --vnet-name myAKSVnet [--subscription]
使用
az aks create
命令创建一个具有自定义子网的 AKS 群集(该子网预先配置有路由表),并为--vnet-subnet-id
和--assign-identity
参数提供值。az aks create \ --resource-group myResourceGroup \ --name myManagedCluster \ --vnet-subnet-id mySubnetIDResourceID \ --assign-identity controlPlaneIdentityResourceID \ --generate-ssh-keys
后续步骤
本文介绍了如何将 AKS 群集部署到现有的虚拟网络子网中。 现在,你可以开始使用 Helm 创建新应用或使用 Helm 部署现有应用。