官网链接:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/#networkpolicy-resource
1 什么是NetworkPolicy
首先NetworkPolicy是k8s的一种resource,它可以根据多种形式限制pod的网络策略。
通过以下三种维度限制pod的流量:pod(允许那些pod)、namespace(允许那些namespace访问)、ip段(CIDR,但是pod锁运行node节点始终可以访问该pod)
当时定义基于pod和namespace的NetworkPolicy时,需要根据标签来选择对应的pod或者namespace。
另外当需要使用NetworkPolicy资源时,k8s集群采用的网络插件必须支持,比如calico
2 隔离和非隔离pod
默认情况所有的pod都是非隔离的,当pod被NetworkPolicy选择后,那么pod就是一个隔离的pod,出栈和入栈都要遵循NetworkPolicy的策略,并且如果有多个NetworkPolicy时,他们是叠加的而不是冲突的。
限制一个pod的NetworkPolicy需要从两个方向去考虑:ingress和egress。
3 基于namespace的NetworkPolicy
以下yaml文件代表在hanju下创建一个NetworkPolicy资源,该策略作用在所有被打了app=nginx-test标签的pod,策略内容为只接受来自namespace为wangjiaying的访问。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ns-network-policy
namespace: hanju
spec:
#定义策略的类型:值是一个列表,支持Ingress和Egress两种,默认Egress不做任何限制
policyTypes: ["Ingress"]
#表示该策略作用的pod,以标签匹配,当该值是一个{}空字典时,代表所有POD
podSelector:
matchLabels:
app: nginx-test
#以下表示ingress策略
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: wangjiaying
验证如下:
4 基于POD的NetworkPolicy
以下yaml文件策略表示:允许带有app=nginx-test的所有pod访问app=nginx-test的pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ns-network-policy
namespace: hanju
spec:
policyTypes: ["Ingress"]
podSelector:
matchLabels:
app: nginx-test
ingress:
- from:
- podSelector:
matchLabels:
app: nginx-test2
验证:
5 基于IP段的NetworkPolicy
以下yaml文件表示策略为:允许10.244.206.0/16段但是不包括10.244.206.7/32来访问带有app=nginx-test的pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ns-network-policy
namespace: hanju
spec:
policyTypes: ["Ingress"]
podSelector:
matchLabels:
app: nginx-test
ingress:
- from:
- ipBlock:
cidr: 10.244.206.0/16
except:
- 10.244.206.7/32
验证如下图所示:
6 关于端口号的限制
创建一个双容器的pod,两个容器分别为nginx和mysql,端口号为80和3306,yaml文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
namespace: hanju
spec:
replicas: 1
selector:
matchLabels:
app: test
template:
metadata:
labels:
app: test
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
- image: mysql:5.7
imagePullPolicy: Always
name: mysql
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: root
第一种策略,只允许wangjiaying名称空间下的pod连接80端口,具体策略如下
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: hanju
spec:
policyTypes: ["Ingress"]
podSelector:
matchLabels:
app: test
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: wangjiaying
ports:
- protocol: TCP
port: 80
将上述创建双容器的yaml文件内的namespace字段修改为wangjiaying再创建一次,这是因为要测试mysql连通性必须有mysql的客户端,这样方便测试。
我们在网络策略里增加3306端口,在进行测试
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: hanju
spec:
policyTypes: ["Ingress"]
podSelector:
matchLabels:
app: test
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: wangjiaying
ports:
- protocol: TCP
port: 80
- protocol: TCP
port: 3306