在本文中,我们提供了一个全面的指南,用于计划、执行和验证从网络策略管理器(NPM)到 Cilium 网络策略的迁移。 目标是确保策略一致性、最大程度地减少服务中断,并符合 Azure CNI 基于 eBPF 的网络和增强可观测性的战略方向。

本指南仅适用于运行 Linux 节点的 AKS 群集。 AKS 中的 Windows 节点当前不支持 Cilium 网络策略。

开始之前的重要注意事项

  • 策略兼容性:NPM 和 Cilium 在强制模型中有所不同。 在迁移之前,需要验证现有策略是否兼容或确定所需的更改。 有关指导,请参阅“迁移前验证”部分。
  • 停机时间预期:在节点重映像期间,策略执行可能会暂时不一致。
  • Windows 节点池:AKS 中的 Windows 节点当前不支持 Cilium 网络策略。
  • 迁移前验证

    在从网络策略管理器(NPM)迁移到 Cilium 网络策略之前,评估现有网络策略的兼容性非常重要。 虽然大多数策略在迁移后继续按预期运行,但存在特定情况,NPM 和 Cilium 的行为可能会有所不同。 这些差异可能需要在迁移之前或之后更新策略,以确保一致的强制实施并避免意外的流量下降。 在本部分中,我们概述了可能需要策略调整的已知方案。 我们解释了它为何重要,并提供指导,说明需要采取哪些措施(如果有)来使您的策略与 Cilium 兼容。

    带有 endPort 的 NetworkPolicy

    Cilium 在版本 1.17 中开始支持 endPort Kubernetes NetworkPolicy 中的字段。

    EndPort 字段允许在单个规则中定义一系列端口,而不是指定单个端口。

    下面是使用 endPort 字段的 Kubernetes NetworkPolicy 的示例:

      egress:
        - to:
            - ipBlock:
                cidr: 10.0.0.0/24
          ports:
            - protocol: TCP
              port: 32000
              endPort: 32768
    
  • 如果您的 AKS 群集运行的是 Cilium 版本 1.17 或更高版本,由于完全支持 endPort,因此不需要进行任何更改。
  • 如果群集运行的 Cilium 版本低于 1.17,请在迁移之前从任何策略中删除 endPort 字段。 请改用显式单端口条目。
  • 带有 ipBlock 的 NetworkPolicy

    Kubernetes NetworkPolicy 中的 ipBlock 字段允许为入口源或出口目标定义 CIDR 范围。 这些范围可以包括外部 IP、Pod IP 或节点 IP。 但是,Cilium 不允许通过 ipBlock 流出到 Pod 或节点 IP,即使这些 IP 位于指定的 CIDR 范围内也是如此。

    例如,以下 NetworkPolicy 使用 ipBlock 允许所有流出流量到 0.0.0.0/0:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: example-ipblock
    spec:
      podSelector: {}
      policyTypes:
        - Egress
      egress:
        - to:
          - ipBlock:
              cidr: 0.0.0.0/0 
    
  • 在 NPM 下,此策略允许流出到所有目标,包括 Pod 和节点。
  • 迁移到 Cilium 后,将阻止对 Pod 和节点 IP 的访问,尽管这些 IP 属于 0.0.0.0/0 范围。
  • 若要允许流量流向 Pod IP,迁移之前请将 ipBlock 替换为 namespaceSelector 和 podSelector 的组合。
  • 下面是使用 namespaceSelector 和 podSelector 的示例:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: example-ipblock
    spec:
      podSelector: {}
      policyTypes:
        - Egress
      egress:
        - to:
          - ipBlock:
              cidr: 0.0.0.0/0
          - namespaceSelector: {}
          - podSelector: {}
    
  • 对于节点 IP,没有预迁移解决方法。 迁移后,必须创建一个显式允许流出到主机和/或远程节点实体的 CiliumNetworkPolicy。 在该策略正式生效之前,将阻止流出到节点 IP 的流量。
  • 下面是 CiliumNetworkPolicy 的一个示例,用于允许从/传向本地和远程节点的流量:

    apiVersion: "cilium.io/v2"
    kind: CiliumNetworkPolicy
    metadata:
      name: allow-node-egress
      namespace: ipblock-test
    spec:
      endpointSelector: {}  # Applies to all pods in the namespace
      egress:
         - toEntities:
              - host # host allows traffic from/to the local node’s host network namespace
              - remote-node # remote-node allows traffic from/to the remote node’s host network namespace
    

    具有命名端口的 NetworkPolicy

    Kubernetes NetworkPolicy 允许按名称而不是数字引用端口。 如果在 NetworkPolicies 中使用命名端口,Cilium 可能无法正确强制实施规则,并导致意外流量被阻止。 当同一端口名称用于不同端口时,会出现此问题。 有关详细信息,请参阅 Cilium GitHub 问题 #30003

    下面是 NetworkPolicy 使用命名端口允许出口流量的示例:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      annotations:
      name: allow-egress
      namespace: default
    spec:
      podSelector:
        matchLabels:
          network-rules-egress: cilium-np-test
      egress:
      - ports:
        - port: http-test # Named port
          protocol: TCP
      policyTypes:
      - Egress
    
  • 在迁移之前,请将策略中的所有命名端口替换为相应的数值。
  • 包含“出口策略”的 NetworkPolicy

    Kubernetes NetworkPolicy 在 NPM 上不会阻止从 Pod 流出到其所在节点 IP 的流量,这种流量是隐式允许的。 迁移到 Cilium 后,此行为会发生变化。之前被允许流向本地节点的流量将被阻止,除非另有显式允许。

    例如,以下策略仅允许流出到内部 API 子网:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-egress 
      namespace: default
    spec:
      podSelector: {}
      policyTypes:
        - Egress
      egress:
        - to:
          - ipBlock:
              cidr: 10.20.30.0/24
    
  • 使用 NPM:明确允许到 10.20.30.0/24 的流出流量,隐式允许到本地节点的流出流量。
  • 使用 Cilium:仅允许到 10.20.30.0/24 的流量;对于节点 IP 的出站流量将被阻止,除非你显式允许。
  • 查看工作负载的所有现有出口策略。
  • 如果应用程序依赖于 NPM 的隐式允许行为来传出到本地节点,则必须添加显式出口规则,以便在迁移后保持连接。
  • 迁移后,可以添加 CiliumNetworkPolicy,以显式允许流出流量流向本地主机。
  • 入口策略行为更改

    在网络策略管理器(NPM)下,通过 LoadBalancer 或 NodePort 服务到达的传入流量,如果其“externalTrafficPolicy=Cluster”(这是默认设置),则不会受到入口策略的强制实施。 此行为意味着,即使 Pod 具有限制性的入口策略,来自外部源的流量仍可能通过 loadbalancer 或 nodeport 服务访问它。

    相比之下,Cilium 对所有流量强制实施入口策略,包括因 externalTrafficPolicy=Cluster 而在内部路由的流量。 因此,迁移后,如果未显式定义适当的入口规则,则可能会删除以前允许的流量。

    例如,客户创建网络策略来拒绝所有入口流量

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: default-deny-ingress
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
    
  • 使用 NPM 时:禁止直接连接到 Pod 或通过 ClusterIP 服务连接。 但是,尽管拒绝所有策略,但仍允许通过 NodePort 或 LoadBalancer 进行访问。
  • 使用 Cilium:除非显式允许,否则会阻止所有入口流量,包括通过 NodePort 或 LoadBalancer 的流量。
  • 使用 externalTrafficPolicy=Cluster 查看 LoadBalancer 或 NodePort 服务背后的工作负荷的所有入口策略。
  • 确保入口规则显式允许来自预期外部源(例如 IP 范围、命名空间或标签)的流量。
  • 如果策略当前依赖于 NPM 下的隐式允许行为,则必须添加显式入口规则,以便在迁移后保持连接。
  • 升级到由 Cilium 提供支持的 Azure CNI

    若要使用 Cilium 网络策略,AKS 群集必须运行由 Cilium 提供支持的 Azure CNI。 在当前使用 NPM 的群集中启用 Cilium 时,会自动卸载现有 NPM 引擎,并将其替换为 Cilium。

    升级过程会触发每个节点池同时重建镜像。 不支持单独升级每个节点池。 群集网络的任何中断都类似于节点映像升级或 Kubernetes 版本升级 ,其中节点池中的每个节点都会重新映像。 Cilium 将仅在重新映像所有节点后才开始强制实施网络策略。

    这些说明适用于使用 Cilium 数据平面从 Azure CNI 升级到 Azure CNI 的群集。 此处不涉及自行配置的 CNI 升级或更改 IPAM 模式。 有关详细信息,请参阅 升级 Azure CNI 文档

    若要执行升级,需要 Azure CLI 2.52.0 或更高版本。 运行 az --version 查看当前安装的版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

    使用以下命令将现有群集升级到由 Cilium 提供支持的 Azure CNI。 替换 clusterNameresourceGroupName 的值:

    az aks update --name <clusterName> --resource-group <resourceGroupName> --network-dataplane cilium
    
  • 有关在 AKS 上使用 Cilium FQDN 网络策略的详细信息,请参阅 在高级容器网络服务中为容器网络安全设置 FQDN 筛选功能

  • 有关在 AKS 上使用 Cilium L7 网络策略的详细信息,请参阅 使用高级容器网络服务设置第 7 层(L7)策略

  • 有关 aks 的网络策略最佳做法的详细信息,请参阅 Azure Kubernetes 服务(AKS)中网络策略的最佳做法

  •