默认情况下,Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信,在某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。
网络策略(Network Policy):是一个K8s资源,用于限制Pod出入流量,提供Pod级别和Namespace级别网络访问控制。
网络策略的应用场景:
• 应用程序间的访问控制,例如项目A不能访问项目B的Pod
• 开发环境命名空间不能访问测试环境命名空间Pod
• 当Pod暴露到外部时,需要做Pod白名单
• 多租户网络环境隔离
官方文档说明:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
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
说明:
podSelector:目标Pod,根据标签选择。
policyTypes:策略类型,指定策略用于入站、出站流量。
Ingress:from是可以访问的白名单,可以来自于IP段、命名空间、入流量
Pod标签等,ports是可以访问的端口。
Egress:这个Pod组可以访问外部的IP段和端口,出流量
案例一、拒绝namespace下所有的pod出入站流量
[root@master1 np]# kubectl create ns test #创建测试ns
namespace/test created
[root@master1 np]# kubectl run web --image=nginx -n test #创建测试pod web
pod/web created
[root@master1 np]# kubectl run busybox --image=busybox -n test -- sleep 12h #创建测试pod
pod/busybox created
#验证pod可正常访问
[root@master1 np]# kubectl exec busybox -n test -- ping baidu.com
PING baidu.com (39.156.69.79): 56 data bytes
64 bytes from 39.156.69.79: seq=0 ttl=127 time=44.998 ms
64 bytes from 39.156.69.79: seq=1 ttl=127 time=91.008 ms
64 bytes from 39.156.69.79: seq=2 ttl=127 time=76.516 ms
^C
创建应用拒绝访问test ns的规则
[root@master1 np]# kubectl apply -f test.yaml
networkpolicy.networking.k8s.io/deny-all-test created
[root@master1 np]# cat test.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-test
namespace: test #匹配的ns
spec:
podSelector: {} #匹配所有的pod
policyTypes:
- Ingress
- Egress
## ingress和egress没有指定规则,则不允许任何流量进出pod
[root@master1 np]# kubectl get networkpolicy -n test
NAME POD-SELECTOR AGE
deny-all-test <none> 4m13s
#测试是否拒绝
[root@master1 np]# kubectl exec busybox -n test -- ping baidu.com
ping: bad address 'baidu.com'
command terminated with exit code 1
#测试无法访问规则生效
案例二:拒绝其他命名空间Pod访问
需求:test命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问test命名空间Pod。
[root@master1 np]# cat test.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-test
namespace: test
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
案例三:允许其他命名空间Pod访问指定应用
[root@master1 np]# cat test.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-test
namespace: test
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
案例四、同一个命名空间下应用之间限制访问
需求:将标签为run=web的pod隔离,只允许标签为run=client1的pod访问80端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-test
namespace: test
spec:
podSelector:
matchLabels:
run: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
run: client1
ports:
- protocol: TCP
port: 80
注:原生使用k8s网络策略 flannel不支持,需要切换成calico.这个在k8s官方有说明
云上环境使用网络策略Network Policy 参考:https://help.aliyun.com/document_detail/97621.html?spm=a2c4g.11186623.6.763.6f575ffeTaThH4