一、概述
网络策略(Network Policy),用于限制Pod出入流量(Pod的ACL),提供Pod级别和Namespace级别网络访问控制。
网络策略是有CNI(calico)组件实现的,底层调用iptable实现具体网络规则。
注意:flannel网络插件不支持网络策略
1.1.应用场景
-
应用程序间的访问控制。例如微服务A允许访问微服务B,微服务C不能访问微服务A
-
开发环境命名空间不能访问测试环境命名空间Pod
-
当Pod暴露到外部时,需要做Pod白名单
-
多租户网络环境隔离
1.2.Pod网络入口方向隔离
- 基于Pod级网络隔离:只允许特定对象访问Pod(使用标签定义),允许白名单上的IP地址或者IP段访问Pod
- 基于Namespace级网络隔离:多个命名空间,A和B命名空间Pod完全隔离。
1.3.Pod网络出口方向隔离
- 拒绝某个Namespace上所有Pod访问外部
- 基于目的IP的网络隔离:只允许Pod访问白名单上的IP地址或者IP段
- 基于目标端口的网络隔离:只允许Pod访问白名单上的端口
二、案例
2.1.案例一:对项目Pod入流量访问控制
隔离default命名空间中标签为app=web的Pod,只允许default命名空间中标签为run=client1的Pod访问80端口
a.准备测试环境
kubectl create deployment web --image=nginx
kubectl run client1 --image=busybox -- sleep 36000
kubectl run client2 --image=busybox -- sleep 36000
Pod正常启动,注意标签部分
b.应用策略前的网络访问情况
获取web Pod的PodIP为10.244.235.212
分别进入到client1和client2中访问10.244.235.212
client1
client2
均可以正常访问
c.网络策略network_policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
project: default
- podSelector:
matchLabels:
run: client1
ports:
- protocol: TCP
port: 80
解释:
podSelector:目标Pod,根据标签选择
policyTypes:策略类型,指定策略用于入站、出站流量。
Ingress:from是可以访问的白名单,可以来自于IP段、命名空间、Pod标签等,ports是可以访问的端口。
Egress:这个Pod组可以访问外部的IP段和端口。
kubectl apply -f network_policy.yaml
kubectl get networkpolicy
d.应用策略后的网络访问情况
client1和client2均不能ping通web
client1可以访问web的80端口,client2不可以
2.2.案例二:Namespace级Pod出入流量访问控制
default命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问default命名空间Pod
a.准备测试环境
在kube-system命名空间下创建client3 Pod
kubectl run client3 --image=busybox -nkube-system -- sleep 36000
b.网络策略network_policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
解释:
podSelector: {}:如果未配置,默认所有Pod
from.podSelector: {} : 如果未配置,默认不允许
kaf network_policy.yaml
kubectl get networkpolicy
c.验证,省略
kube-system命名空间中的client3不能访问default命名空间中的web