K8s 访问限制之NetworkPolicy
什么是NetworkPolicy
NetworkPolicy负责规范一组pod和其他pod以及网络endpoint的通信行为。
前置要求
NetworkPolicy由网络插件实现。因此我们使用的网络插件必须要支持NetworkPolicy才能启用本配置。
Pod之间的隔离性
默认来说pod之间不会隔离措施。如果有一个NetworkPolicy的选择器匹配了某个pod,这些pod会成为被隔离的pod。这些pod会拒绝所有不被NetworkPolicy允许的通信。(其他未被选择的pod不受影响)
NetworkPolicy不会互相冲突,他们的效果是互相叠加的。NetworkPolicy没有顺序的概念。一个pod的最终网络连通性由选择了这个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
配置讲解
spec.podSelector: 决定了NetworkPolicy影响到的pod。如果这一块儿为空,和该NetworkPolicy处于同一namespace的所有pod都会被影响。
spec.policyTypes: 设置启用了哪些policy。包含Ingress和Egress策略。如果没有配置policyTypes,默认启用的是Ingress策略。此时如果配置了egress规则的话,Egress策略会被启用。
ingress: 配置入站规则。请求必须满足from和ports中规定的条件,才允许访问目标pod。
to和from selector的配置
to和from选择器中可以指定下列更为细化的选择器:
- podSelector
- namespaceSelector
- podSelector和namespaceSelector: 注意这个和分别指定podSelector和namespaceSelector是不同的。分别指定这两个selector他们之间是或的关系。采用这种方式是与的关系。稍后有例子说明。
- ipBlock: IP地址段,使用CIDR范围配置。可以添加except,从CIDR范围中排除一定范围的IP。
下面分析下单独使用podSelector,namespaceSelector和同时使用podSelector和namespaceSelector的不同之处。
同时使用podSelector和namespaceSelector:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
效果为namespaceSelector和podSelector的并集。即需要同时满足:
- namespace具有user: alice标签
- pod具有role: client标签
这些pod的网络流量入站。
下面是单独使用namespaceSelector和podSelector的情况。他们之间是或的关系。
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
允许流量来源于:
- namespace的标签为user: alice或者
- namespace和NetworkPolicy相同,同时pod具有role: client标签的pod
默认策略
默认来说如果一个namespace中没有任何NetworkPolicy,该namespace中的所有pod之间的通信是不受限制的。下面给出一些例子用来改变这个默认行为。
默认禁止所有的入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
配置这个策略之后,没有被任何NetworkPolicy select的pod也会生效,禁止所有的入站流量。
默认允许所有的入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
配置这个策略之后,即便pod被隔离,也会放行这些pod的所有入站流量。原因为NetworkPolicy为正向权限。NetworkPolicy只会配置允许规则,并没有禁止规则。
默认禁止所有的出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Egress
默认允许所有的出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
默认禁止所有的入站和出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress