NetworkPolicy 介绍
Network Policy 是 k8s 用于控制集群pod流量的组件
默认情况下,pod是非隔离的,集群中的pod之间是可以互相通信和访问的
pod 在被某个 Network Policy 选中是进入隔离状态,一旦命名空间有pod被 Network Policy 选择,那么这个pod会拒绝 Network Policy 的流量,这个网络策略之间是不会冲突的,多个策略是累加的
Network Policy 字段
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
spec.podSelector: NetWork policy 是通过 这个字段来选择pod的,多个网络策略可以选择同一组pod,这个情况多个ingress 的规则效果会被叠加,空值的podSelector 匹配对应命名空间的所有规则
spec.policyType: 这个是规则类型的列表,用来定义规则类型列表,这个字段有效选项有三个,["ingress"] 这个代表入站流量,["Egress"]这个代表出站流量,["Ingress","Egress"] 入站和出站
spec.ingress: 这个是pod的入站规则列表,用来定义对应的规则,如果这个字段为空,那么,这个NetworkPolicy 是不允许任何入站流量的,这个只有满足from条件的客户端才可以访问 ports 定义的目标pod端口号
spec.ingress.from: 对符合条件的客户端pod 进行网络放行
spec.ingress.from.ipBlock: 如果设置了这个字段是不可以设置其他字段的,这个字段是通过 CIRD来设置范围(例如,192.168.200.0/24,2001.db8::/64),来自这个ip范围的流量才可以访问与 spec.podSelector 匹配的pod集合 ,可以使用 execpt 字段排除在此规则中的pod,实现效果类似于拉黑,如果 except 字段的值超出 ipBlock.cidr 的范围会被视为无效范围
spec.ingress.from.namespaceSelector: 通过命名空间选择,如果此字段是空值,会选择所有的命名空间,如果spec.ingress.from.podSelector 被定义,这个两个规则选择的pod都会进行匹配,反之,就只选择该namespace 匹配的所有pod
spec.ingress.from.podSelector: podSelector 是通过pod的标签来选择,如果字段是空值,则会 选择所有的pod,如果spec.ingress.from.namespaceSelector 被定义,这个两个规则选择的pod都会进行匹配,反之,就只选择该spec.ingress.from.podSelector 匹配的所有pod
spec.ingress.port: 对符合条件的端口进行放行
spec.ingress.endPoet: 如果设置了此字段,那么这个策略是放行 port和endPort之间的所有端口,如果没有定义port是不可以使用这个字段的,这个字段的值必须大于等于 port的值
spec.ingress.protocol: 这个对应的是网络协议(TCP,UDP,SCTP),默认是TCP
spec.egress: 这个是pod的出站规则列表,用来定义对应的规则,如果这个字段为空,那么,这个NetworkPolicy 是不允许任何入站流量的,流量必须同时匹配ports和 to的设置
spec.egress.to: 允许访问的服务端信息 (目的ip)
spec.egess.ports: 允许访问的服务端的端口号 (目的端口)
egress下面的字段和ingress的字段相同,可以参考上面的描述
Network Policy 实战
实验环境说明
创建两个命名空间 network1 和network2
在两个命令空间中分别创建两个 delplyment 工作负载的pod
其中 network1 命名空间下面的工作负载 nginx1 和 nginx2
network2 命令空间下面的工作负载 nginx3
创建实验环境
可以通过apply 如下 yaml创建
apiVersion: v1
kind: Namespace
metadata:
labels:
kubernetes.io/metadata.name: network1 # 创建network1 的命名空间
name: network1
spec:
finalizers:
- kubernetes
---
apiVersion: v1
kind: Namespace
metadata:
labels:
kubernetes.io/metadata.name: network2 # 创建network1 的命名空间
name: network2
spec:
finalizers:
- kubernetes
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
namespace: network1
labels:
app: nginx1
spec:
replicas: 1
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx2
namespace: network1
labels:
app: nginx2
spec:
replicas: 1
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx3
namespace: network2
labels:
app: nginx3
spec:
replicas: 1
selector:
matchLabels:
app: nginx3
template:
metadata:
labels:
app: nginx3
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
network1 下的pod只能在同namespace访问
案例 yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-demo
namespace: network1
spec:
ingress:
- from:
- podSelector: {}
podSelector: {}
policyTypes:
- Ingress
案例 yaml文件说明
这个yaml的spec.podSelector 为空,含义是选择这个命名空间的下面的所有pod
spec.ingress.from 对符合条件的pod进行放行,这个字段下面的podSelector 为空则会选择所有的pod
因此这个yaml文件可以实现只让同namespace 下面的pod访问
实战效果
运行对应的yaml文件
查看创建的 NetworkPolicy 规则
kubectl describe NetworkPolicy network-test-demo -n network1
测试访问效果
nginx1 可以访问 nginx2 nginx3
nginx 3 无法访问 nginx1 和 nginx 2
network1 下的pod不能被任何pod访问
案例 yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-demo1
namespace: network1
spec:
podSelector: {}
policyTypes:
- Ingress
案例 yaml文件说明
spec.podSelector 字段为空,表示选择该nameSpace所有pod
spec.ingress 字段为空, 表示不允许任何入站流量
实战效果
登录nginx1 查看,可以看到访问 nginx2 不通
只让nginx3 的 IP访问 nginx1 的 80端口
查看nginx3 的IP
案例 yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-demo2
namespace: network1
spec:
podSelector:
matchLabels:
app: nginx1
ingress:
- from:
- ipBlock:
cidr: 10.16.4.35/32
ports:
- protocol: TCP
port: 80
policyTypes:
- Ingress
案例 yaml文件说明
spec.podSelector.matchLabels 这里通过标签选择了pod,这里选择的 nginx1,这个规则限制的nginx1 的
在 from中限制,只有来源是 10.16.4.35 的IP才能访问 nginx1 的80端口
实战效果
测试结果。nginx3 可以通, nginx1 不可以通
指定IP段访问,拉黑nginx3的IP
案例 yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-test-demo3
namespace: network1
spec:
podSelector:
matchLabels:
app: nginx1
ingress:
- from:
- ipBlock:
cidr: 10.16.4.0/24
except:
- 10.16.4.35/32
ports:
- protocol: TCP
port: 80
policyTypes:
- Ingress
案例 yaml文件说明
通过 cidr: 10.16.4.0/24 允许这个IP段的访问
排除这个 IP 10.16.4.35 , 这个IP是nginx3 的IP
实战效果
测试结果 nginx2 可以正常访问,nginx3 不可以