网络策略用来说明一组 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有以下规则:
- 在入口和出口流量的“default”命名空间中隔离“role = db” 的pod(如果它们尚未被隔离)
- 允许“default”命名空间中任任何含有标签“role = frontend”的Pod连接到“default”命名空间中“role = db”,TCP端口为6379的Pod。
- 允许命名空间中任任何含有标签“project=myproject”的Pod连接到“default”命名空间中“role = db”,TCP端口为6379的Pod。
- 允许 IP 地址范围在CIDR 172.17.0.0/16,并且不在172.17.1.0/24网段的Pod连接到“default”命名空间中“role = db”,TCP端口为6379的Pod。
- 允许从“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也不会被允许通过入口或出口流量。