网络策略NetworkPolicy是允许pod组彼此之间以及和其他网络Endpoint端点通信的规则。NetworkPolicy资源使用标签来选择Pods并定义规则,这些规则指定允许所选Pods的流量请求。

前提条件

网络策略由网络插件实现,因此你必须使用支持NetworkPolicy的网络解决方案,例如calico就支持。

隔离和非隔离的Pods

默认情况下,pod是非隔离的; 他们接受任何来源的流量。通过使用选择它们的NetworkPolicy,Pod会变成隔离状态。一旦Namespace中有任何NetworkPolicy选择了指定的pod,该pod将拒绝在NetworkPolicy规则中任何不被允许的连接。(Namespace中未被任何NetworkPolicy选中的其他pod将继续接受所有流量。)

NetworkPolicy

NetworkPolicy示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
  • 必填字段:与所有其他Kubernetes配置一样,NetworkPolicy需要apiVersion,kind和metadata字段。有关使用配置文件的一般信息,请参阅使用ConfigMap配置容器和对象管理
  • spec:NetworkPolicy规范具有在给定Namespace中定义特定网络策略所需的所有信息。
  • podSelector:每个NetworkPolicy都包含一个podSelector,用于选择策略适用的pod分组。示例策略选择标签为“role=db”的pod。podSelector为空则会选择Namespace中的所有pod。
  • policyTypes:每个NetworkPolicy都包含一个policyTypes列表,其中可能包含Ingress,Egress或两者都有。policyTypes字段指示给定策略是否适用于所选Pod的Ingress或Egress流量。如果在NetworkPolicy上未指定policyTypes,除非指定了Egress,否则默认情况下将只设置Ingress流量。
  • ingress(入口):每个NetworkPolicy可能包含Ingress规则白名单列表。每个规则允许匹配from和ports部分的流量。示例策略包含单个规则,该规则匹配单个端口上的流量,来自三个源中的一个,第一个通过ipBlock指定,第二个通过namespaceSelector,第三个通过podSelector。
  • egress(出口):每个NetworkPolicy可以包括Egress规则白名单列表。每个规则允许匹配to和ports部分的流量。示例策略包含单个规则,该规则将单个端口上的流量与10.0.0.0/24中的任何目标进行匹配。

那么,示例NetworkPolicy即表示:

    1. 在“default”命名空间中隔离“role=db”的pod的入口和出口请求流量
    1. (入口规则)允许带有标签“role=db”的以下Pod连接到“default”命名空间中的所有pod的6379端口:
    • “default”命名空间中标签为“role=frontend”的任何pod,
    • 标签带“project=myproject”的任何命名空间中的Pod
    • 172.17.0.0-172.17.0.255和172.17.2.0-172.17.255.255范围内的IP地址(即172.17.0.0/16除172.17.1.0/24外的IP)
    1. (出口规则)允许“default”命名空间中的任何Pod连接到标签带“role=db”且CIDR IP段为10.0.0.0/24的tcp5978端口

出入口选择器行为

通过ingress fromegress to可以指定四种选择器:

  • podSelector:允许与NetworkPolicy同一命名空间中的指定Pod作为入口源或出口目的地。
  • namespaceSelector:允许所有特定命名空间的Pod作为入口源或出口目标的。
  • namespaceSelector和podSelector:指定namespaceSelector和podSelector的单个to/from条目选择特定命名空间中的特定Pod。policy示例:
1
2
3
4
5
6
7
8
9
10
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...

上述示例包含1个from入口流量策略,允许来自命名空间本身带有标签为user=alice、且此命令空间中标签为role=client的Pod的所有连接(and关系)。但是如果二者是并列关系的policy:

1
2
3
4
5
6
7
8
9
10
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...

上述示例相当于包含2个from入口流量策略,允许来自同一Namespace中的Pod带有标签role=client的连接,或来自任何命名空间中具有标签user=alice的任何Pod的连接(or关系)。

  • ipBlock:选择特定的IP CIDR范围以允许作为入口源或出口目的地。这些应该是集群外部IP,因为Pod IP是短暂的和不可预测的。

群集入口和出口机制通常需要重写数据包的源IP或目标IP。如果发生这种情况,则无法确定是在NetworkPolicy处理之前还是之后发生这种情况,并且对于网络插件,云提供商,服务实施等的不同组合,行为可能会有所不同。

在入口的情况下,这意味着在某些情况下,w你可能能够根据实际的原始源IP过滤传入的数据包,而在其他情况下,NetworkPolicy作用的“源IP”可能是LoadBalancer的IP或Pod的节点等,所以需要按实际需求配置。

对于出口,这意味着从pod到服务IP的连接被重写为集群外部IP可能会不受基于ipBlock的策略的约束。

默认策略

默认情况下,如果命名空间中不存在任何NetworkPolicy策略,则允许所有入口和出口流量进出该命名空间中的pod。以下示例为更改该命名空间中的默认策略。

默认拒绝所有入口流量

可以通过创建NetworkPolicy为命名空间创建“默认”隔离策略,该策略选择所有Pod且不允许任何入口流量到这些Pod。

1
2
3
4
5
6
7
8
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress

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

默认允许所有入口流量

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

1
2
3
4
5
6
7
8
9
10
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress

默认拒绝所有出口流量

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

1
2
3
4
5
6
7
8
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Egress

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

默认允许所有出口流量

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

1
2
3
4
5
6
7
8
9
10
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress

默认拒绝所有入口和所有出口流量

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

1
2
3
4
5
6
7
8
9
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress

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