IBM Cloud Docs
使用 Kubernetes 策略控制 pod 之间的流量

使用 Kubernetes 策略控制 pod 之间的流量

虚拟私有云

您可以使用 Kubernetes 策略来控制集群中 pod 之间的网络流量,并在名称空间内或名称空间之间隔离应用程序微服务。

应用程序级别: 工作程序节点主机端点

缺省行为: 缺省情况下,集群中不存在 Kubernetes 网络策略。 缺省情况下,任何 pod 都有权访问集群中的任何其他 pod。 此外,任何 pod 都可以访问 pod 网络公开的任何服务,例如度量服务,集群 DNS,API 服务器或您在集群中手动创建的任何服务。

使用案例:Kubernetes 网络策略规定了Pod如何与其他Pod和外部端点通信。 可以根据协议、端口、源IP地址或目标IP地址允许或阻止传入和传出的网络流量。 还可以根据 pod 和名称空间标签对流量进行过滤。 当应用 Kubernetes 网络策略时,它们会自动转换为 Calico 网络策略。 集群中的 Calico 网络插件通过在工作节点上设置 Linux Iptables规则来强制执行这些策略。 iptables 规则充当工作程序节点的防火墙,用于定义网络流量必须满足才能转发到目标资源的特征。

如果大多数或所有 pod 不需要访问特定 pod 或服务,并且您希望确保缺省情况下 pod 无法访问这些 pod 或服务,那么可以创建 Kubernetes 网络策略以阻止流入这些 pod 或服务的流量。 例如,任何 pod 都可以访问 CoreDNS pod 上的度量端点。 要阻止不必要的访问,您可以应用如下策略,该策略允许所有入口到 TCP 和 UDP 端口 53,以便 pod 可以访问 CoreDNS 功能。 但是,它会阻止所有其他入口,例如任何从 CoreDNS pod 收集度量值的尝试,但具有 coredns-metrics-policy: allow 标签的名称空间中的 pod 或服务,或者具有 coredns-metrics-policy: allow 标签的 kube-system 名称空间中的 pod 除外。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: coredns-metrics
  namespace: kube-system
spec:
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          coredns-metrics-policy: allow
    - podSelector:
        matchLabels:
          coredns-metrics-policy: allow
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP
  podSelector:
    matchLabels:
      k8s-app: kube-dns
  policyTypes:
  - Ingress

如需了解 Kubernetes 网络策略如何控制Pod到Pod的流量以及更多示例策略,请参阅 Kubernetes 文档

隔离一个名称空间内的应用程序服务

以下场景演示了如何管理一个名称空间内应用程序微服务之间的流量。

Accounts 团队在一个名称空间中部署了多个应用程序服务,但这些服务需要隔离,以仅允许微服务之间通过公用网络进行必要的通信。 对于应用程序 Srv1,该团队具有前端、后端和数据库服务。 该团队使用 app: Srv1 标签以及 tier: frontendtier: backendtier: db 标签标记了每个服务。

使用网络策略来管理跨名称空间流量。
Use a network policy to manage namespace traffic

Accounts 团队希望允许来自前端的流量流至后端,并允许来自后端的流量流至数据库。 为此,他们在其网络策略中使用了标签,以指定在微服务之间允许哪些流量流动。

首先,他们创建了一个 Kubernetes 网络策略,用于允许来自前端的流量流至后端:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: backend-allow
spec:
  podSelector:
    matchLabels:
      app: Srv1
      tier: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: Srv1
          Tier: frontend

spec.podSelector.matchLabels 部分列出了 Srv1 后端服务的标签,以便该政策仅_适用于_这些pod。 spec.ingress.from.podSelector.matchLabels 部分列出了 Srv1 前端服务的标签,以便仅允许_从_这些标签进入。

接下来,他们创建了一个类似的 Kubernetes 网络策略,允许来自后端的流量流至数据库:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: db-allow
spec:
  podSelector:
    matchLabels:
      app: Srv1
      tier: db
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: Srv1
          Tier: backend

spec.podSelector.matchLabels 部分列出了 Srv1 数据库服务的标签,以便该策略仅_适用于_这些pod。 spec.ingress.from.podSelector.matchLabels 部分列出了 Srv1 后端服务的标签,以便仅允许_来自_这些标签的访问。

现在,来自前端的流量可以流至后端,并且来自后端的流量可以流至数据库。 数据库可以响应后端,并且后端可以响应前端,但无法建立逆向流量连接。

隔离跨名称空间的应用程序服务

以下场景演示了如何管理跨多个名称空间的应用程序微服务之间的流量。

不同子团队拥有的服务需要相互沟通,但这些服务部署在同一集群的不同命名空间中。 Accounts 团队在 accounts 名称空间中为应用程序 Srv1 部署了前端、后端和数据库服务。 Finance 团队在 finance 名称空间中为应用程序 Srv2 部署了前端、后端和数据库服务。 这两个团队使用 app: Srv1app: Srv2 标签以及 tier: frontendtier: backendtier: db 标签标记了每个服务。 他们还使用 usage: accountsusage: finance 标签标记了名称空间。

使用网络策略来管理跨名称空间流量。
Use a network policy to manage cross-namespace traffic

Finance 团队的 Srv2 需要从 Accounts 团队的 Srv1 后端调用信息。 因此,Accounts 团队创建了一个 Kubernetes 网络策略,以使用标签允许来自 finance 名称空间的所有流量流至 accounts 名称空间中的 Srv1 后端。 该团队还指定端口 3111 用于隔离仅通过该端口进行的访问。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  Namespace: accounts
  name: accounts-allow
spec:
  podSelector:
    matchLabels:
      app: Srv1
      Tier: backend
  ingress:
  - from:
    - NamespaceSelector:
        matchLabels:
          usage: finance
      ports:
        port: 3111

spec.podSelector.matchLabels 部分列出了 Srv1 后端服务的标签,以便该政策仅_适用于_这些pod。 spec.ingress.from.NamespaceSelector.matchLabels 部分列出了金融命名空间的标签,以便仅允许_来自_该命名空间的服务进入。

现在,流量可以从 finance 微服务流至 accounts Srv1 后端。 accounts Srv1 后端可以响应 finance 微服务,但无法建立逆向流量连接。

在此示例中,允许来自 finance 名称空间中所有微服务的所有流量。 由于无法组合使用 podSelectornamespaceSelector,因此无法允许来自其他名称空间中的特定应用程序 pod 的流量。

具有在 V 1.28 或更高版本上运行的集群的 VPC 的必需策略规则

在1.27及更早版本中,VPC 群集通过IBM Cloud Container Registry的私有云服务端点从Container Registry 提取映像。 对于1.28及更高版本,该网络路径已更新,因此图像是通过 VPE 网关而不是专用服务端点提取的。 此更改会影响 VPC 中的所有群集;当您将 VPC 中的单个群集创建或更新到版本1.28 时,该 VPC 中的所有群集(无论其版本或类型如何)都会更新其网络路径。 有关更多信息,请参阅 VPC 集群的联网更改

如果 VPC 中有一个集群运行 V 1.28 或更高版本,并且您使用 Calico 策略来限制来自集群工作程序的出站连接,那么必须添加以下策略规则以允许连接到 VPE Gateway for Registry。 必须为 VPC 中的每个区域创建此策略,并且必须将该区域的整个 VPC 地址前缀范围指定为目标 CIDR。 要查找 VPC 中每个专区的 VPC 地址前缀范围,请运行 ibmcloud is vpc-address-prefixes <vpc_name_or_id>

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-vpe-gateway-registry
spec:
  egress:
  - action: Allow
    destination:
      nets:
      - <entire-vpc-address-prefix-range> # example: 10.245.0.0/16
      ports:
      - 443
      - 4443
    protocol: TCP
    source: {}
  order: 500
  selector: ibm.role == 'worker_private'
  types:
  - Egress