参考链接

网络策略用来说明一组 Pod 之间是如何被允许互相通信,以及如何与其它网络 Endpoint 进行通信。 NetworkPolicy 资源使用标签来选择 Pod,并定义了一些规则,这些规则指明允许什么流量进入到选中的 Pod 上。

前提条件

网络策略通过网络插件来实现,所以必须使用一种支持 NetworkPolicy 的网络方案(如Calico,wave等) —— 非 Controller 创建的资源,是不起作用的。

隔离的与未隔离的 Pod

默认 Pod 是未隔离的,它们可以从任何的源接收请求。 具有一个可以选择 Pod 的网络策略后,Pod 就会变成隔离的。 一旦 Namespace 中配置的网络策略能够选择一个特定的 Pod,这个 Pod 将拒绝任何该网络策略不允许的连接。(Namespace 中其它未被网络策略选中的 Pod 将继续接收所有流量)

NetworkPolicy 资源

这里创建一个NetworkPolicy的示例:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress                      # 入方向流量
  - Egress                       # 出方向流量
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16      # 允许的网段
        except:
        - 172.17.1.0/24          # 拒绝的网段
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

如果将上面配置 POST 到 API Server 将不起任何作用,除非选择的网络方案支持网络策略。 必选字段:像所有其它 Kubernetes 配置一样, NetworkPolicy 需要 apiVersion、kind 和 metadata这三个字段。

spec: NetworkPolicy spec 中给定 Namespace 中定义特定网络的全部信息。

podSelector: 每个 NetworkPolicy 都包含一个 podSelector,它可以选择一组应用了网络策略的 Pod。示例中的策略选择了标签为 “role=db” 的 Pod。如果 podSelector为空, 则表示选择了该 Namespace 中的所有Pod。

policyTypes:每个NetworkPolicy都包含一个policyTypes列表,其中可能包含Ingress或Egress。 policyTypes字段指示给定策略是匹配上指定pod的入方向流量,或出方向流量。 如果在NetworkPolicy上未指定policyTypes,则默认情况下将始终设置Ingress,并且如果NetworkPolicy具有任何出口流量规则,则将设置Egress规则。

ingress:每个NetworkPolicy 包含了一个白名单入口(ingress) 规则列表。每个规则只允许能够匹配 from和 ports配置段的流量。示例策略包含了单个规则,它匹配单个端口上的流量,来自三个源中的一个,第一个通过ipBlock指定,第二个通过namespaceSelector,第三个通过podSelector。

egress: 每个NetworkPolicy可以包括白名单出口(egress)规则的列表。 每个规则允许匹配to和ports部分的流量。 示例策略包含单个规则,该规则将单个端口上的流量与10.0.0.0/24中的任何目标进行匹配。

示例中的NetworkPolicy有以下规则:

  1. 在入口和出口流量的“default”命名空间中隔离“role = db” 的pod(如果它们尚未被隔离)
  2. 允许“default”命名空间中任任何含有标签“role = frontend”的Pod连接到“default”命名空间中“role = db”,TCP端口为6379的Pod。
  3. 允许命名空间中任任何含有标签“project=myproject”的Pod连接到“default”命名空间中“role = db”,TCP端口为6379的Pod。
  4. 允许 IP 地址范围在CIDR 172.17.0.0/16,并且不在172.17.1.0/24网段的Pod连接到“default”命名空间中“role = db”,TCP端口为6379的Pod。
  5. 允许从“default”命名空间中的任何标记“role = db”的pod连接到TCP端口5978上的CIDR 10.0.0.0/24

默认策略

在默认情况下,如果在namespaces中没有指定网络策略,那么所有的流量都是允许的,下面的示例会演示如何修改在namespace中的默认策略。

设置默认拒绝所有流入的流量

我们可以创建一个默认的隔离策略,在一个namespace中的所有Pod拒绝所有流入的流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress

这可确保即使是任何其他NetworkPolicy未选中的pod也仍会被隔离。 此策略不会更改默认的出口隔离行为。

设置默认允许所有流入流量

如果要允许所有流量到namespace中的所有Pod(即使添加了导致某些Pod被视为“隔离”的策略),您也可以创建一个明确允许该命名空间中所有流量的策略。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  ingress:
  - {}

设置默认拒绝所有流出的流量

您可以通过创建NetworkPolicy来为命名空间创建“default”出口隔离策略,该策略选择所有Pod但不允许来自这些Pod的任何出口流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Egress

设置默认允许所有流出的流量

如果要允许来自命名空间中所有Pod的所有流量(即使添加了导致某些Pod被视为“隔离”的策略),您也可以创建一个明确允许该命名空间中所有出口流量的策略。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress

设置拒绝所有入方向和出方向的流量

您可以为命名空间创建“default”策略,通过在该命名空间中创建以下NetworkPolicy来阻止所有入口和出口流量。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

这可确保即使是未被任何其他NetworkPolicy选择的pod也不会被允许通过入口或出口流量。