在 Azure Kubernetes 服务中使用网络策略保护 Pod 之间的流量(AKS)

重要

AKS 中 Windows 节点上对 Azure 网络策略管理器(NPM)的支持将于 2026 年 9 月 30 日结束。

此更改仅适用于已加入 NPM 的客户。 未向此功能注册的订阅将无法再加入。 现有已注册的客户可以继续使用 NPM,直到支持终止日期。

为了确保设置继续获得支持、安全更新和部署兼容性,请在节点级别或 Project Calico 等开源工具上探索网络安全组(NSG)等替代选项。

重要

AKS 中 Linux 节点上对 Azure 网络策略管理器(NPM)的支持将于 2026 年 9 月 30 日结束。

为了避免服务中断,需要在支持终止日期之前将 运行 Linux 节点的 AKS 群集从 NPM 迁移到 Cilium 网络策略

重要

对 AKS 群集上的 kubenet 网络的支持将于 2028 年 3 月 31 日结束。

若要避免服务中断,需要在支持结束日期之前升级到 Azure 容器网络接口(CNI)Overlay

安装网络策略引擎并创建 Kubernetes 网络策略,以控制 AKS 群集中 Pod 之间的流量流。

网络策略概述

默认情况下,AKS 群集中的所有 Pod 都可以无限制地发送和接收流量。 为了提高安全性,可定义用来控制流量流的规则。

网络策略是一种 Kubernetes 规范,用于为 Pod 之间的通信定义访问策略。 使用网络策略时,可以定义一组有序的规则来发送和接收流量。 将规则应用于与一个或多个标签选择器匹配的 Pod 集合。

将网络策略规则定义为 YAML 清单,并且可以将其包含在更广泛的清单中,这些规则也会创建部署或服务。

AKS 中的网络策略选项

Azure 提供了三个用于强制实施网络策略的网络策略引擎:

建议使用 Cilium。 Cilium 使用 Linux Berkeley 数据包筛选器(BPF)对流量强制实施网络策略,该筛选器比 IPTable 更高效。

为了实施指定的策略,Azure NPM 使用IPTables(适用于 Linux)和主机网络服务 (HNS) ACLPolicies(适用于 Windows)。 策略将转换为一系列允许和禁止的 IP 对。 然后,这些对作为 IPTableHNS ACLPolicy 筛选规则进行编程。

网络策略引擎之间的差异:Cilium、Azure NPM 和 Calico

网络策略引擎 支持的平台 支持的网络选项 Kubernetes 规范符合性 其他功能 支持
纤毛 Linux Azure CNI 支持所有策略类型 FQDN、L3/4 Azure 支持和工程团队
Azure NPM Linux、Windows Server 2022 Azure CNI 支持所有策略类型 N/A Azure 支持和工程团队
白布 Linux、Windows Server 2019、Windows Server 2022 Azure CNI(Linux、Windows Server 2019、Windows Server 2022)和 kubenet (Linux) 支持所有策略类型 虽然 Calico 有许多 AKS 无法阻止的功能,但 AKS 不会测试或支持这些功能。 有关详细信息,请参阅 Calico 网络策略问题 Azure 支持和工程团队

Azure 网络策略管理器限制 (Linux)

适用于 Linux 的 Azure NPM 具有以下限制:

  • 不支持缩放 超过 250 个节点20,000 个 Pod 。 如果尝试超出这些限制进行缩放,可能会遇到内存不足 (OOM) 错误。 为了获得更好的可伸缩性和 IPv6 支持,我们建议为网络策略引擎使用或升级到 由 Cilium 提供支持的 Azure CNI
  • 不支持 IPv6。 否则,它完全支持 Linux 中的网络策略规范。

Azure 网络策略管理器限制 (Windows)

适用于 Windows 的 Azure NPM 不支持网络策略规范的以下功能:

  • 命名端口。
  • 流式传输控制传输协议 (SCTP)。
  • 负匹配标签或命名空间选择器。 例如,除 debug=true 之外的所有标签。
  • except 无类别域际路由选择 (CIDR) 块(具有异常的 CIDR)。

Azure 网络策略管理器的已知问题

编辑或删除“足够大”的网络策略时,可能会遇到与受影响节点的新连接或从 Pod 建立临时连接问题。 达到此争用条件永远不会影响活动连接。

如果某个节点发生此争用条件,该节点上的 Azure NPM pod 将进入无法更新安全规则的状态,这可能会导致受影响节点上 pod 的新连接出现意外连接。 为了缓解该问题,Azure NPM pod 会在进入此状态后自动重启约 15 秒。 在受影响的节点上重新启动 Azure NPM 时,它会删除所有安全规则,然后重新应用所有网络策略的安全规则。 尽管重新应用了所有安全规则,但对于受影响节点上 pod 的新连接,可能会发生临时的意外连接。

若要限制达到此争用条件的可能性,可以减小网络策略的大小。 此问题很可能发生在具有多个 ipBlock 部分的网络策略中。 具有 四个或更少ipBlock 部分的网络策略不太可能遇到该问题。

负载均衡器服务和网络策略

入站和出站服务的 Kubernetes 服务路由通常涉及重写正在处理的流量的源 IP 和目标 IP,包括从 LoadBalancer 服务传入群集的流量。 此重写行为意味着网络策略可能无法正确处理从外部服务接收或发送到外部服务的流量。 有关详细信息,请参阅 Kubernetes 网络策略文档

若要限制哪些源可以将流量发送到负载均衡器服务,请使用 spec.loadBalancerSourceRanges 配置在发生任何重写之前应用的流量阻止。 有关详细信息,请参阅 AKS 标准负载均衡器文档

开始之前

需要安装并配置 Azure CLI 2.0.61 或更高版本。 使用 az --version 命令查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

也可以使用用户分配的标识,而不是系统分配的标识。 有关详细信息,请参阅使用托管标识

使用 Azure 网络策略管理器创建 AKS 群集(Linux)

  1. 为资源组名称、群集名称和位置设置环境变量。 根据需要替换值。

    export RESOURCE_GROUP=myResourceGroup
    export CLUSTER_NAME=myAKSCluster
    export LOCATION=eastus
    
  2. 使用 az aks create 创建 AKS 群集,并为 azurenetwork-plugin 指定 network-policy

    az aks create \
        --resource-group $RESOURCE_GROUP \
        --name $CLUSTER_NAME \
        --node-count 1 \
        --network-plugin azure \
        --network-policy azure \
        --generate-ssh-keys
    

使用 Azure 网络策略管理器创建 AKS 群集(Windows Server 2022(预览版)

重要

AKS 预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

安装 aks-preview Azure CLI 扩展

  1. 使用 aks-preview 命令安装 az extension add 扩展。

    az extension add --name aks-preview
    
  2. 使用 az extension update 命令更新到扩展的最新版本。

    az extension update --name aks-preview
    

注册 WindowsNetworkPolicyPreview 功能标志

  1. 使用 WindowsNetworkPolicyPreview 命令注册 az feature register 功能标志。

    az feature register --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"
    

    状态显示为“已注册”需要几分钟时间

  2. 使用 az feature show 命令验证注册状态。

    az feature show --namespace "Microsoft.ContainerService" --name "WindowsNetworkPolicyPreview"
    
  3. 当状态显示已注册时,请使用Microsoft.ContainerService命令刷新资源提供程序的az provider register注册。

    az provider register --namespace Microsoft.ContainerService
    

为 Windows Server 容器创建管理员凭据

  • 创建一个用户名,用作群集上 Windows Server 容器的管理员凭据。 以下命令提示输入用户名。 将其设置为 WINDOWS_USERNAME

    echo "Please enter the username to use as administrator credentials for Windows Server containers on your cluster: " && read WINDOWS_USERNAME
    

创建 AKS 群集

  1. 为资源组名称、群集名称和位置设置环境变量。 根据需要替换值。

    export RESOURCE_GROUP=myResourceGroup
    export CLUSTER_NAME=myAKSCluster
    export LOCATION=eastus
    
  2. 使用 az aks create 创建 AKS 群集,并为 azurenetwork-plugin 指定 network-policy

    az aks create \
        --resource-group $RESOURCE_GROUP \
        --name $CLUSTER_NAME \
        --node-count 1 \
        --windows-admin-username $WINDOWS_USERNAME \
        --network-plugin azure \
        --network-policy azure \
        --generate-ssh-keys
    

使用 Calico 创建 AKS 群集

使用 az aks create 命令创建 AKS 群集并指定 --network-plugin azure--network-policy calico。 指定 --network-policy calico 可在 Linux 和 Windows 节点池上启用 Calico。

如果计划将 Windows 节点池添加到群集,请包括满足 windows-admin-username的参数 windows-admin-password。 若要为群集上的 Windows Server 容器创建管理员凭据,请参阅 为 Windows Server 容器创建管理员凭据

重要

目前,使用 Calico 网络策略与 Windows 节点配合使用在使用 Kubernetes 1.20 或更高版本的新群集上可用,这些群集需要使用 Calico 3.17.2 并配置 Azure CNI 网络。 已启用 Calico 的 AKS 群集上的 Windows 节点还默认启用了浮动 IP。

对于使用早期版本 Calico 的只用 Linux 节点池运行 Kubernetes 1.20 的群集,Calico 版本将自动升级到 3.17.2。

在现有群集上安装 Azure 网络策略管理器或 Calico

警告

在现有群集上安装 Azure NPM 或 Calico 时,请记住以下信息:

  • 升级过程会触发每个节点池同时重建镜像。 不支持单独升级每个节点池。
  • 在每个节点池中,节点遵循与标准 Kubernetes 版本升级操作相同的镜像化过程。 此行为意味着会暂时添加缓冲区节点,以最大程度地减少节点重新映像过程中正在运行的应用程序的中断。 可能发生的任何中断都类似于在节点映像升级或 Kubernetes 版本升级期间可能会遇到的情况。

下列信息适用于从 kubenet 使用 Calico 升级到使用 Calico 的 Azure CNI 覆盖网络:

  • 在启用了 Calico 的 kubenet 群集中,Calico 用作 CNI 和网络策略引擎。
  • 在 Azure CNI 群集中,Calico 仅用于网络策略强制执行,而不用作 CNI。 这可能会导致 Pod 启动和 Calico 允许来自 Pod 的出站流量之间出现短暂的延迟。
  • 更新现有群集以使用az aks update命令安装 Azure NPM 或 Calico,并为参数azure指定calico--network-policy。 以下示例命令演示如何安装任一 Azure NPM:

    az aks update
        --resource-group $RESOURCE_GROUP \
        --name $CLUSTER_NAME \
        --network-policy azure
    

使用 Azure NPM 或 Calico 将现有群集升级到 Cilium

若要将现有群集升级到由 Cilium 提供支持的 Azure CNI,请参阅将现有群集升级到由 Cilium 提供支持的 Azure CNI

连接到 AKS 群集

  • 使用 kubectl 命令将 az aks get-credentials 配置为连接到你的群集。 此命令将下载凭据,并将 Kubernetes CLI 配置为使用这些凭据。

    az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
    

验证网络策略设置

若要开始验证网络策略,请创建示例应用程序并设置流量规则。

  1. 使用demo命令创建一个名为kubectl create namespace运行示例 Pod 的命名空间。

    kubectl create namespace demo
    
  2. 使用server命令创建一个在 TCP 端口 80 上提供服务的名为kubectl run的 Pod。

    kubectl run server -n demo --image=k8sgcr.azk8s.cn/e2e-test-images/agnhost:2.33 --labels="app=server" --port=80 --command -- /agnhost serve-hostname --tcp --http=false --port "80"
    
  3. 创建一个 Pod,名称为 client,使用 kubectl run 命令运行 Bash。

    kubectl run -it client -n demo --image=k8sgcr.azk8s.cn/e2e-test-images/agnhost:2.33 --command -- bash
    

    注意

    如果要在特定节点上调度客户端或服务器,请在 Pod 创建命令中--command参数kubectl run之前添加以下代码段:--overrides='{"spec": { "nodeSelector": {"kubernetes.io/os": "linux|windows"}}}'

  4. 在单独的窗口中,使用server命令获取 Pod 的 kubectl get pod IP 地址。

    kubectl get pod --output=wide -n demo
    

    输出应类似于以下示例输出:

    NAME     READY   STATUS    RESTARTS   AGE   IP            NODE             NOMINATED NODE   READINESS GATES
    server   1/1     Running   0          30s   10.224.0.72   akswin22000001   <none>           <none>
    

使用网络策略测试连接性

小窍门

若要测试没有网络策略的连接,请在客户端 shell 中运行以下命令: /agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp<server-ip> 替换为服务器 Pod 的 IP 地址。 如果连接成功,则无任何输出。

  1. 创建名为 demo-policy.yaml 的文件并粘贴以下 YAML 清单:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: demo-policy
      namespace: demo
    spec:
      podSelector:
        matchLabels:
          app: server
      ingress:
      - from:
        - podSelector:
            matchLabels:
              app: client
        ports:
        - port: 80
          protocol: TCP
    
  2. 使用 kubectl apply 命令应用网络策略清单。

    kubectl apply –f demo-policy.yaml
    
  3. 在客户端 shell 中,使用以下命令 /agnhost 验证与服务器的连接:

    /agnhost connect <server-ip>:80 --timeout=3s --protocol=tcp
    

    由于服务器标记为 app=server,但客户端未标记,因此与流量的连接将被阻止。 输出应类似于以下示例输出:

    TIMEOUT
    
  4. 使用client命令标记kubectl label并验证与服务器的连接。

    kubectl label pod client -n demo app=client
    

    如果连接成功,则无任何输出。

迁移到自主管理的 Calico

AKS 仅支持 Calico 进行标准 Kubernetes 网络策略,并且不测试其他功能。 如果要迁移到自管理的 Calico,请按照 Tigera 的指引 从 Azure 托管的 Calico 迁移到自管理的 Calico。 Tigera 文档提到,对于自管理的 Calico,在卸载部分按照的设置进行操作。

卸载 Azure 网络策略管理器或 Calico

注意

从群集中卸载 Azure NPM 或 Calico 时,请记住以下信息:

  • 卸载过程 不会删除 Calico 使用的自定义资源定义(CRD)和自定义资源(CRR)。 这些 CRD 和 CR 都具有以 projectcalico.orgtigera.io 结尾的名称。 成功卸载 Calico ,可以手动删除这些 CRD 和关联的 CR。
  • 升级不会删除群集中的任何网络策略资源,但卸载过程后不再强制实施这些策略。
  • 使用az aks update命令从现有群集中删除 Azure 网络策略管理器或 Calico 并指定none--network-policy参数。

    az aks update
        --resource-group $RESOURCE_GROUP \
        --name $CLUSTER_NAME \
        --network-policy none
    

清理资源

在本文中,你创建了一个命名空间和两个 Pod,并应用了网络策略。 如果不再需要这些资源,可以将其删除。

  • 使用 kubectl delete 命令删除资源。

    kubectl delete namespace demo