Antrea NSX 适配器 会将已注册的 Antrea Kubernetes 集群的 Kubernetes 网络策略同步到 NSX 清单。但是,无法在 NSX 环境中更新或管理这些 K8s 网络策略。

如果要在 NSX 中编辑 K8s 网络策略,可以将其导入到 NSX 环境中。此导入功能从 NSX 4.2 开始提供,并且仅支持使用 NSX API 实现该功能。

导入 K8s 网络策略概览

导入操作会将 K8s 网络策略转换为具有等效流量行为的 NSX Distributed Firewall (DFW) 策略。在将 K8s 网络策略转换为 NSX DFW 策略后,NSX 将成为管理转换后的 DFW 策略的真实来源。然后,您可以使用 NSX Manager UI 或 NSX API 编辑 DFW 策略。

此转换是单向操作。无法将 NSX DFW 策略转换回 K8s 网络策略。

重要说明: 如果 NSX 清单包含由 NSX Container Plugin (NCP) 管理的 Kubernetes 网络策略,则不支持导入功能。要导入到 NSX 的 K8s 网络策略必须由 Antrea CNI 管理。

每个导入的 K8s 网络策略都将转换为一个或两个 NSX DFW 策略。一个 DFW 策略将包含所有允许规则(如果 K8s 网络策略中存在输入和输出规则),另一个 DFW 策略将包含默认丢弃流量规则。将始终生成具有默认丢弃规则的 DFW 策略。

系统会将 NSX DFW 策略的跨度(范围)设置为 Antrea Kubernetes 集群。此外,可将 DFW 策略的跨度进一步限制为包含 Kubernetes 命名空间的有效 Pod 成员的 Antrea 组。

转换后的 DFW 策略放置在 NSX 的应用程序层中。导入 API 会将转换的 DFW 策略附加到应用程序层中的其他现有 Antrea 策略之后。导入的策略在 NSX 中的现有 Antrea 策略之后实施,但在实施 Antrea 集群网络策略 (ACNP) 和 Antrea 网络策略 (Antrea Network Policy, ANP) 之前实施,后两者在 Kubernetes 集群本地定义。转换为 NSX DFW 策略后,将保留 K8s 命名空间中的原始流量行为。

Antrea CNI 将转换的 DFW 策略作为 Kubernetes 集群中的 Antrea 集群网络策略实现。这些 Antrea 集群网络策略现在由 NSX 管理,并且只能在 NSX 环境中进行编辑。如果尝试使用 kubectl 命令行编辑 ACNP 配置,Antrea NSX 适配器 将覆盖或恢复对原始策略定义的 ACNP 更改,因为它存在于 NSX 中。

将 K8s 网络策略成功导入 NSX 后,系统会自动从 K8s 清单中删除原始 Kubernetes 网络策略。系统还会使用 K8s 集群的名称、原始 K8s 网络策略和 K8s 命名空间来标记转换的 DFW 策略。这些标记可帮助您在 NSX Manager UI 中搜索转换的 DFW 策略。或者,也可以在 kubectl 命令行上运行 kubectl get acnp -o wide 命令,查看相应实现的 ACNP 中的标记(即 K8s 中的标签)。

导入 K8s 网络策略的必备条件

  • 必须将 Antrea Kubernetes 集群注册到 NSX 4.2 或更高版本。
  • 导入功能需要使用 VMware Container Networking™ with Antrea™ 1.9.0 或更高版本提供的 Antrea-NSX Interworking 版本。
  • NSX 部署中应用相应的安全许可证,以授权系统配置分布式防火墙安全策略。
  • NSX 环境的默认空间中,会为您分配企业管理员角色或安全管理员角色。
  • 确认 Antrea NSX 适配器 已成功将 Kubernetes 网络策略报告给 NSX 清单。
    例如,要在 NSX Manager UI 中进行验证,请执行以下步骤:
    1. 导航到清单 > 容器 > 命名空间
    2. 如果需要,请筛选出 CNI 类型Antrea 的命名空间列表。
    3. 展开命名空间,然后单击网络策略计数,以验证 Kubernetes 网络策略是否已同步到 NSX 清单。
      要检查 NSX 是否读取命名空间中的所有 Kubernetes 网络策略,可以将 UI 中的计数与通过以下 kubectl 命令检索的策略数进行比较。计数必须相同。
      kubectl get networkpolicies -n <namespace>

将 K8s 网络策略字段映射到 NSX 分布式防火墙策略字段

如前所述,将 Kubernetes 网络策略导入到 NSX 时,系统会将此网络策略转换为一个或两个 DFW 策略。一个 DFW 策略包含所有允许规则,另一个 DFW 策略包含默认丢弃流量规则。系统会根据 K8s 网络策略的规范创建 Antrea 组。Antrea 组在转换的 DFW 策略的目标应用对象字段中使用。

下表介绍了 Kubernetes 网络策略中的字段与 NSX 分布式防火墙策略中字段的映射情况。

K8s 网络策略中的字段 NSX 资源 描述

K8s 网络策略本身

一个或两个 DFW 策略

  • K8s 网络策略 spec.ingressspec.egress 中的所有规则都将添加到 DFW“允许”策略中。也就是说,此 DFW 策略中所有规则的规则操作都设置为允许
  • 系统将根据 K8s 网络策略 spec.policyTypes 列表中的值,使用入站流量和/或出站流量的丢弃规则创建具有默认丢弃规则的 DFW 策略。

    例如,如果 K8s 网络策略规范的 spec.policyTypes 列表仅包含 egress,则 DFW“丢弃”策略将具有输出流量的默认丢弃规则(流量方向:出站)。

  • 如果 Kubernetes 网络策略不包含任何输入和输出规则,则会创建仅具有默认丢弃规则的 DFW 策略。
spec.podSelector

metadata.namespace

Antrea 类型的组

将同时使用 spec.podSelectormetadata.namespace 转换为 Antrea 组。

创建的 Antrea 组在 DFW“允许”策略和 DFW“丢弃”策略的应用对象中引用。

如果未指定 spec.podSelectorAntrea 组将仅包含命名空间。

spec.ingress[*]

spec.egress[*]

DFW“允许”策略中的防火墙规则

K8s 网络策略 spec.ingressspec.egress 部分中的每个规则都会转换为 NSX DFW 规则。

这些 DFW 规则将添加到 DFW“允许”策略中。

spec.ingress[*].from
  • podSelector
  • namespaceSelector
  • ipBlock

Antrea 类型的组

  • ingress from 部分中的 Pod 和命名空间选择器将转换为具有动态成员资格条件的 Antrea 组。
  • ipBlock 选择器中的 IP CIDR 范围将转换为 Antrea 组中的静态 IP 地址成员。
  • 这些 Antrea 组在 DFW 规则的字段中引用。
spec.egress[*].to
  • podSelector
  • namespaceSelector
  • ipBlock

Antrea 类型的组

  • egress to 部分中的 Pod 和命名空间选择器将转换为具有动态成员资格条件的 Antrea 组。
  • ipBlock 选择器中的 IP CIDR 范围将转换为 Antrea 组中的静态 IP 地址成员。
  • 这些 Antrea 组在 DFW 规则的目标字段中引用。
spec.ingress[*].ports
  • protocol
  • port

spec.egress[*].ports
  • protocol
  • port

DFW 规则中的服务条目

  • K8s 网络策略输入和输出规则规范中的 L4 协议和目标端口(包括目标端口范围)将转换为 DFW 规则中的服务条目。
  • K8s 规则规范中的目标端口或端口范围始终映射到服务条目中的目标端口。

字段映射示例

本节包含一些示例,可帮助您了解将 K8s 网络策略导入到 NSX 时,Kubernetes 网络策略中的字段与 DFW 策略中的字段的映射情况。

示例 1

K8s 网络策略规范:

apiVersion: v1
kind: Namespace
metadata:
  name: my-ns1
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: knp1
  namespace: my-ns1
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 8.8.8.8/32
      ports:
        - protocol: UDP
          port: 53

此 K8s 网络策略会选择 my-ns1 命名空间中的所有 Pod,并允许从此命名空间中的任何 Pod 到 UDP 端口 53 上的 8.8.8.8/32 CIDR 的输出流量(出站连接)。将丢弃来自此命名空间中 Pod 的所有其他输出流量。

将此 K8s 网络策略导入 NSX 时,将创建两个 DFW 策略。一个 DFW 策略包含一个允许规则,另一个 DFW 策略包含一个丢弃规则。

spec.podSelector 部分将转换为具有动态成员资格条件的 Antrea 组。组中的条件将选择 my-ns1 命名空间中的所有 Pod。此 Antrea 组在 DFW 允许策略和 DFW 丢弃策略的应用对象字段中引用。

spec.egress.to 部分中的 ipBlock 选择器将转换为具有静态 IP 地址成员 8.8.8.8/32 的 Antrea 组。此 Antrea 组在 DFW 允许规则的目标字段中引用。我们将此组称为组 1。

spec.egress.ports 部分将转换为具有 UDP 协议和目标端口 53 的服务条目。

NSX 中 DFW 允许规则的配置如下所示。

目标 服务 上下文配置文件 规则应用对象 规则操作 规则方向
不适用 组 1

UDP

源:任意,目标:53

不适用 任意 允许 出站

NSX 中 DFW 丢弃规则的配置如下所示。

目标 服务 上下文配置文件 规则应用对象 规则操作 规则方向
任意 任意 任意 不适用 任意 丢弃 出站
示例 2

K8s 网络策略规范:

apiVersion: v1
kind: Namespace
metadata:
  name: my-ns2
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: knp2
  namespace: my-ns2
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

此 Kubernetes 网络策略将选择 my-ns2 命名空间中的所有 Pod,并丢弃来自这些 Pod 的所有输入流量和输出流量。此策略基本上将为命名空间创建默认丢弃所有输入和输出流量的规则。

将此 K8s 网络策略导入到 NSX 时,仅创建一个 DFW 丢弃策略。转换后的 DFW 策略包含具有丢弃操作的单个防火墙规则。

spec.podSelector 部分将转换为具有动态成员资格条件的 Antrea 组。组中的条件将选择 my-ns2 命名空间中的所有 Pod。此 Antrea 组在 DFW 丢弃策略的应用对象字段中引用。

NSX 中 DFW 丢弃规则的配置如下所示。

目标 服务 上下文配置文件 规则应用对象 规则操作 规则方向
任意 任意 任意 不适用 任意 丢弃 双向

转换的 DFW 策略和 Antrea 组的命名约定

系统对转换后的 DFW 允许和丢弃策略使用以下命名约定:

DFW 允许策略
<cluster_name>-<namespace>-<K8s_networkpolicy_name>-<K8s_networkpolicy_uuid>-allow
DFW 丢弃策略
<cluster_name>-<namespace>-<K8s_networkpolicy_name>-<K8s_networkpolicy_uuid>-drop

cluster_namenamespaceK8s_networkpolicy_name 的值被截断为 12 个字节。

系统对 Antrea 组使用以下命名约定:

DFW 允许和丢弃策略的“应用对象”字段中引用的组
<cluster_name>-<namespace>-<K8s_networkpolicy_uuid>
DFW 规则的“源”字段中引用的组
<cluster_name>-<namespace>-<K8s_networkpolicy_uuid>-rule[rule index]-from-<peer index>
DFW 规则的“目标”字段中引用的组
<cluster_name>-<namespace>-<K8s_networkpolicy_uuid>-rule[rule index]-to-<peer index>

cluster_namenamespace 的值被截断为 12 个字节。

要了解系统如何将值分配给 Antrea 组名称中的规则索引和对等索引,请参考以下 K8s 网络策略示例,其中包含三个输入规则。

示例
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: knp3
  namespace: my-ns3
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchExpressions:
            - key: namespace
              operator: In
              values: ["test-ns1"]
        - podSelector:
            matchExpressions:
            - key: app
              operator: In
              values: ["nginx"]
      ports:
        - protocol: TCP
          port: 80
    - from:
        - namespaceSelector:
            matchExpressions:
            - key: namespace
              operator: In
              values: [""]
      ports:
        - protocol: TCP
          port: 443
    - from:
        - namespaceSelector:
            matchExpressions:
            - key: namespace
              operator: In
              values: ["test-ns4"]
      ports:
        - protocol: TCP
          port: 8080
          endPort: 8090

下面我们来看第一个 ingress.from 规则的代码段,如下所示:

ingress:
    - from:
        - namespaceSelector:
            matchExpressions:
            - key: namespace
              operator: In
              values: ["test-ns1"]
        - podSelector:
            matchExpressions:
            - key: app
              operator: In
              values: ["nginx"]
      ports:
        - protocol: TCP
          port: 80

此输入规则中的“from”部分包含两个元素。一个元素使用命名空间选择器选择 Pod,另一个元素使用 Pod 选择器选择 Pod。我们将这两个元素称为对等体。

系统会为规则中的每个对等体创建一个 Antrea 组。转换后的 DFW 规则的规则索引为 0,此规则在规则的字段中包含两个 Antrea 组。一个 Antrea 组名称的对等索引为 0,另一个组名称的对等索引为 1,如下所示:

<cluster_name>-my-ns3-knp3-rule[0]-from-0

<cluster_name>-my-ns3-knp3-rule[0]-from-1

现在,请看第二个和第三个 ingress.from 规则的代码段,如下所示:

ingress:
    - from:
        - namespaceSelector:
            matchExpressions:
            - key: namespace
              operator: In
              values: [""]
      ports:
        - protocol: TCP
          port: 443
    - from:
        - namespaceSelector:
            matchExpressions:
            - key: namespace
              operator: In
              values: ["test-ns4"]
      ports:
        - protocol: TCP
          port: 8080
          endPort: 8090

这两个输入规则中每个规则的“from”部分仅包含一个元素,它使用命名空间选择器来选择 Pod。转换后的 DFW 规则的规则索引分别为 1 和 2,并且每个规则在规则的字段中都包含一个 Antrea 组。在这种情况下,不会将对等索引附加到 Antrea 组的名称中。组名称如下:

<cluster_name>-my-ns3-knp3-rule[1]-from

<cluster_name>-my-ns3-knp3-rule[2]-from

使用 API 的简要导入工作流

  1. 确保您满足导入 Kubernetes 网络策略的必备条件,如本文档前面所述。
  2. 运行以下 kubectl 命令,查看给定命名空间中的 Kubernetes 网络策略列表:
    kubectl get networkpolicies -n <namespace>
    例如:
    kubectl get networkpolicies -n test-ns5
    
    NAME     POD-SELECTOR   AGE
    k-np10   app=demo       82m
    k-np11   app=myapp      82m
    k-np12   app=demo       82m
    k-np9    app=myapp      82m

    在此示例中,test-ns5 命名空间包含四个 Kuberentes 网络策略。在此过程中,我们会将“k-np9”和“k-np11”策略导入到 NSX 中。

  3. 运行以下 kubectl 命令,检索要导入的每个 Kubernetes 网络策略的 ID。
    kubectl get networkpolicies <policy-name> -n <namespace> -o yaml

    例如,要检索“k-np9”网络策略和“k-np11”网络策略的 ID,请运行以下命令:

    kubectl get networkpolicies k-np9 -n test-ns5 -o yaml
    kubectl get networkpolicies k-np11 -n test-ns5 -o yaml
    在这两个 kubectl 命令的输出中,记下您在 metadata.uid 字段中看到的 ID。在我们的 K8s 集群中,策略 ID 如下所示:
    • 对于 k-np9:e5a59ae6-cc0e-42a5-80bd-f6fa13b5b70d
    • 对于 k-np11:84b850fb-69ad-4e95-a563-a95ce6b70557

    这些策略 ID 仅用于示例目的。它们在 K8s 集群中可能会有所不同。您需要这些策略 ID 才能运行导入 API,将在下一步中进行介绍。

  4. 运行以下 NSX API 以导入 Kubernetes 网络策略:

    例如:

    POST https://<nsx-mgr>/policy/api/v1/infra/import-k8s-np-to-dfw?on_error=ABORT  -k
    {
        "network_policy_ids" : ["e5a59ae6-cc0e-42a5-80bd-f6fa13b5b70d", "84b850fb-69ad-4e95-a563-a95ce6b70557"],
        "sequence_number_upper" : 1000,
        "sequence_number_lower" : 2000
    }

    network_policy_ids 参数为必需参数,而 sequence_number_uppersequence_number_lower 参数为可选参数。

    在此示例中,指定了将导入到 NSX 的 K8s 网络策略(k-np9 和 k-np11)的 ID。

    有关这些请求参数、API 示例请求和 API 示例响应的详细信息,请参见NSX API 指南

    on_error 查询参数用于确定发生错误时 API 必须执行的操作。下表介绍了此查询参数的有效值。

    描述
    中止

    此值为默认值。

    如果导入 K8s 网络策略时出错,系统将阻止提交所有转换的 DFW 策略和 Antrea 组。导入操作提前结束,并且不会转换任何 K8s 网络策略。API 响应会针对导致错误的每个 K8s 网络策略返回相应的错误消息。

    示例:

    假定在 API 请求正文中指定了两个 K8s 网络策略(如 knp1 和 knp2)的 UUID。knp1 策略在输出规则规范中包含不支持的 SCTP 协议。运行导入 API 时,转换 knp1 网络策略过程中会引发错误,并且导入操作提前结束。系统不会转换下一个 K8s 网络策略 (knp2),即使此网络策略有效也是如此。

    继续

    如果导入当前 K8s 网络策略时出错,系统将跳过此策略并继续导入下一个 K8s 网络策略。API 响应会针对导入操作期间跳过的每个 K8s 网络策略返回相应的错误消息。

    小心: 如果将导入的 K8s 网络策略和跳过的 K8s 网络策略应用于同一个 Pod,则流量行为可能会发生变化。

    示例:

    继续看上一行中提到的相同示例。如果导入 knp1 网络策略时引发错误,系统会继续导入 knp2 网络策略,并成功转换此网络策略。API 响应会针对 knp1 网络策略返回相同的错误消息,此策略在转换过程中失败。

    在单个 API 请求中导入的 K8s 网络策略可以属于不同的已注册 Antrea Kubernetes 集群。或者,它们可以属于单个 Antrea Kubernetes 集群内的多个命名空间。

    如果命名空间包含多个 K8s 网络策略,我们建议在单个 API 请求中导入这些策略。原因是命名空间内的 K8s 网络策略可能会相互关联。这种做法有助于确保在将网络策略导入到 NSX 后,流量行为不会发生变化。

  5. 导入成功后,转到 NSX Manager UI,查看 Antrea 组和 DFW 策略的配置。
  6. 可选:通过运行以下 kubectl 命令查看实现的 Antrea 集群网络策略,检查 ACNP 规范和 ClusterGroup 规范:
    kubectl get acnp
    kubectl get acnp <acnp-id> -o yaml
    kubectl get cg <cg-id> -o yaml
  7. 可选:通过运行以下 kubectl 命令,确认 K8s 集群中不会显示已成功导入到 NSX 的 K8s 网络策略:
    kubectl get networkpolicies -n <namespace>

    对于我们的示例,命令如下所示:

    kubectl get networkpolicies -n test-ns5
    
    NAME     POD-SELECTOR   AGE
    k-np10   app=demo       84m
    k-np12   app=demo       84m
    

    可以发现,在 K8s 集群中不再显示导入的 Kubernetes 网络策略(k-np9 和 k-np11)。

不支持的 Kubernetes 网络策略功能

Kubernetes 网络策略中的某些功能当前不支持转换为 NSX DFW 策略和 Antrea 组。当转换由于以下任何不支持的功能而失败时,API 响应会显示相应的错误消息。

  • 不会转换对 Pod 使用 L4 端口名称的 K8s 网络策略。DFW 策略仅支持端口号。
  • 不会转换包含 SCTP 协议的 K8s 网络策略。NSX DFW 策略不支持 SCTP 流量。
  • K8s 网络策略在 podSelectorNetworkPolicyPeer 部分中可以具有大量 matchLabelsmatchExpressions。但是,Antrea 组中的动态成员资格条件最多可以支持 15 个混合成员类型的条件和 5 个相同成员类型的条件。当组成员资格条件中超出此最大限制时,转换将失败。
  • 包含使用 DoesNotExist 运算符的 matchExpressions 的 Kubernetes 网络策略不会转换为 Antrea 组。Kubernetes 中的 DoesNotExist 运算符将映射到 NSX 中范围运算符的 NotEquals 值。但是,Antrea 组定义中的范围运算符当前不支持此值。
  • 包含使用 In 运算符的 matchExpressions 的 Kubernetes 网络策略只能包含一个值,转换才能成功。当前不支持将 In 运算符中的多个值转换为 Antrea 组。

不同 Antrea NSX 适配器 版本的行为

您可以按任意顺序单独升级 Antrea NSX 适配器NSXAntrea NSX 适配器 中的新更改与 4.2 之前的 NSX 版本兼容。

请考虑以下场景:

NSX 环境的版本为 4.2,并且注册了多个 Antrea Kubernetes 集群。某些 Kubernetes 集群具有新版本的 Antrea NSX 适配器(如 v0.15),而某些集群则具有旧版本的 Antrea NSX 适配器(如 v0.11)。在这种情况下,旧版本的 Antrea NSX 适配器 在转换后不会自动从 Kubernetes 集群中删除原始 Kubernetes 网络策略。Kubernetes 管理员或命名空间管理员需要手动删除原始 Kubernetes 网络策略。请注意,仍会执行到 DFW 策略的转换。转换后的 DFW 允许策略和默认丢弃策略在 Kubernetes 集群中作为 Antrea 集群网络策略实现,并由 Antrea CNI 在原始 Kubernetes 网络策略之前进行评估。如果未从 Kubernetes 集群中删除原始 Kubernetes 策略,转换后的 DFW 策略中定义的流量行为可能会与原始 Kubernetes 网络策略冲突。