网络策略
网络策略
目录
[toc]
介绍
默认情况下,Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他Pod通信
,在某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。
网络策略(Network Policy)
:是一个K8s资源,用于限制Pod出入流量,提供Pod级别和Namespace级别网络访问控制。
默认情况,k8集群里,Pod和Pod,Node和Pod之间都是可以随意通信的。
网络策略的应用场景:
- 应用程序间的访问控制,例如项目A不能访问项目B的Pod
- 开发环境命名空间不能访问测试环境命名空间Pod
- 当Pod暴露到外部时,需要做Pod白名单
- 多租户网络环境隔离
网络策略:yaml文件示例
apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:test-network-policynamespace:defaultspec:podSelector:matchLabels:role:dbpolicyTypes:- Ingress- Egressingress:- from:- ipBlock:cidr:172.17.0.0/16except:- 172.17.1.0/24- namespaceSelector:matchLabels:project:myproject- podSelector:matchLabels:role:frontendports:- protocol:TCPport:6379egress:- to:- ipBlock:cidr:10.0.0.0/24ports:- protocol:TCPport:5978
podSelector:目标Pod,根据标签选择。
policyTypes:策略类型,指定策略用于入站、出站流量。
Ingress:from是可以访问的白名单,可以来自于IP段、命名空间、Pod标签等,ports是可以访问的端口。
Egress:这个Pod组可以访问外部的IP段和端口。
注意:
{} 代表包括所有不写ingress或者egress代表默认行为,拒绝所有。
案例1:拒绝命名空间下所有Pod出入站流量
==💘 案例:拒绝命名空间下所有Pod出入站流量-2023.1.6(测试成功)==
次策略实际过程中不会用到。
- 实验环境
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.22.2containerd:[root@k8s-master1 ~]#kubectl create ns testnamespace/testcreated(2)创建相应pod#在test命名空间下创建2个pod[root@k8s-master1 ~]#kubectl run busybox-test --image=busybox-ntest--sleep12hpod/busybox-testcreated[root@k8s-master1 ~]#kubectl run web-test --image=nginx-ntestpod/web-testcreated[root@k8s-master1 ~]#kubectl get po -owide -ntestNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESbusybox-test1/1Running013s10.244.36.74k8s-node1<none><none>web-test1/1Running08s10.244.169.138k8s-node2<none><none>#在default命名空间下创建1个pod[root@k8s-master1 ~]#kubectl run busybox-default --image=busybox--sleep12hpod/busybox-defaultcreated[root@k8s-master1 ~]#kubectl get po -owideNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESbusybox-default1/1Running05s10.244.169.140k8s-node2<none><none>
2、测试k8s默认网络策略
(1)同命名空间下pod是可以互相访问的[root@k8s-master1 ~]#kubectl exec -it busybox-test -ntest -- sh/#/# ping 10.244.169.138PING10.244.169.138(10.244.169.138):56 data bytes64bytesfrom10.244.169.138:seq=0ttl=62time=0.601ms64bytesfrom10.244.169.138:seq=1ttl=62time=0.393ms^C---10.244.169.138pingstatistics---2packetstransmitted,2packetsreceived,0%packetlossround-tripmin/avg/max=0.393/0.497/0.601ms(2)不同命名空间下pod是可以互相访问的[root@k8s-master1 ~]#kubectl exec -it busybox-test -ntest -- sh/#/# ping 10.244.169.140PING10.244.169.140(10.244.169.140):56 data bytes64bytesfrom10.244.169.140:seq=0ttl=62time=0.657ms^C---10.244.169.140pingstatistics---1packetstransmitted,1packetsreceived,0%packetlossround-tripmin/avg/max=0.657/0.657/0.657ms(3)node是可以访问pod地址的[root@k8s-master1 ~]#ping 10.244.36.74PING10.244.36.74(10.244.36.74) 56(84) bytes of data.64bytesfrom10.244.36.74:icmp_seq=1ttl=63time=0.485ms64bytesfrom10.244.36.74:icmp_seq=2ttl=63time=0.440ms^C---10.244.36.74pingstatistics---2packetstransmitted,2received,0%packetloss,time1000msrttmin/avg/max/mdev=0.440/0.462/0.485/0.031ms
3、为test命名空间配置网络策略
#deny-all.yamlapiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:deny-allnamespace:testspec:podSelector:{} # 匹配本命名空间所有podpolicyTypes:- Ingress- Egress# ingress和egress没有指定规则,则不允许任何流量进出pod
部署:
[root@k8s-master1 ~]#kubectl apply -f deny-all.yamlnetworkpolicy.networking.k8s.io/deny-allcreated[root@k8s-master1 ~]#kubectl get networkpolicy -ntestNAMEPOD-SELECTORAGEdeny-all<none>21s
4、测试
(1)测试访问外部(拒绝访问):[root@k8s-master1 ~]#kubectl exec -it busybox-test -n test -- sh/#/# ping 10.244.169.140PING10.244.169.140(10.244.169.140):56 data bytes^C---10.244.169.140pingstatistics---4packetstransmitted,0packetsreceived,100%packetloss(2)测试外部pod访问(拒绝访问):[root@k8s-master1 ~]#kubectl exec -it busybox-default -- sh/#/# ping 10.244.36.74PING10.244.36.74(10.244.36.74):56 data bytes^C---10.244.36.74pingstatistics---4packetstransmitted,0packetsreceived,100%packetloss/#(3)测试内部pod之间访问(拒绝访问):[root@k8s-master1 ~]#kubectl exec -it busybox-test -n test -- sh/#/# ping 10.244.169.138PING10.244.169.138(10.244.169.138):56 data bytes^C---10.244.169.138pingstatistics---4packetstransmitted,0packetsreceived,100%packetloss/#
测试结束。😘
案例2:拒绝其他命名空间Pod访问
==💘 案例2:拒绝其他命名空间Pod访问-2023.1.6(测试成功)==
案例2:拒绝其他命名空间Pod访问需求:test命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问test命名空间Pod。apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:deny-all-namespacesnamespace:testspec:podSelector:{} # 未配置,匹配本命名空间所有podpolicyTypes:- Ingressingress:- from:- podSelector:{} # 未配置,匹配本命名空间所有pod#说明一般情况,我们配置的ingress规则会多些,而出规则egress很少去配置的;
- 实验环境
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.20.0docker:namespace/testcreated
- 再创建2个pod:
[root@k8s-master np]#kubectl run web --image=nginx-ntestpod/webcreated[root@k8s-master ~]#kubectl run busybox --image=busybox-ntest--sleep24hpod/busyboxcreated#查看[root@k8s-master ~]#kubectl get pod -n testNAMEREADYSTATUSRESTARTSAGEbusybox1/1Running09sweb-96d5df5c8-7r6w61/1Running03m11s[root@k8s-master ~]#kubectl get pod -n test -o wideNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESbusybox1/1Running021h10.244.169.148k8s-node2<none><none>web1/1Running07h26m10.244.169.151k8s-node2<none><none>#默认情况下,`Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信`[root@k8s-master ~]#kubectl exec busybox -n test -- ping 10.244.169.151PING10.244.169.151(10.244.169.151):56 data bytes64bytesfrom10.244.169.151:seq=0ttl=63time=0.283ms64bytesfrom10.244.169.151:seq=1ttl=63time=0.126ms^C[root@k8s-master ~]#
- 我们再次在默认命名空间下创建一个pod,并测试不同命名空间下的pod是否可以进行通信:=>是可以通信的。
[root@k8s-master ~]#kubectl run busybox --image=busybox--sleep24h[root@k8s-master ~]#kubectl get pod -o wide[root@k8s-master ~]#kubectl get pod -o wide -n test[root@k8s-master ~]#kubectl exec busybox -- ping 10.244.169.157
现在进行按题目需求进行限制:
拒绝其他命名空间Pod访问需求:test命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问test命名空间Pod。
- 创建np目录:
[root@k8s-master ~]#mkdir np[root@k8s-master ~]#cd np/[root@k8s-master np]#vim deny-all-namespaces.yaml#配置yaml,这就是所谓的白名单apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:deny-all-namespacesnamespace:testspec:podSelector:{} # 未配置,匹配本命名空间所有podpolicyTypes:- Ingressingress:- from:- podSelector:{} # 未配置,匹配本命名空间所有pod
- apply并测试效果:=>完全符合预期效果。
#apply下[root@k8s-master np]#kubectl apply -f deny-all-namespaces.yamlnetworkpolicy.networking.k8s.io/deny-all-namespacescreated#验证效果[root@k8s-master np]#kubectl exec busybox -- ping 10.244.169.157 #做了网络策略限制后,从默认命名空间下不能ping通test命名空间下的web pod了。^C#但在test下ping不同命名空间下的pod是依然可以访问的[root@k8s-master np]#kubectl exec busybox -n test -- ping 10.244.169.157PING10.244.169.157(10.244.169.157):56 data bytes64bytesfrom10.244.169.157:seq=0ttl=63time=0.245ms64bytesfrom10.244.169.157:seq=1ttl=63time=0.307ms^C#test命名空间下也是可以直接访问外网的;[root@k8s-master np]#kubectl exec busybox -n test -- ping www.baidu.comPINGwww.baidu.com(180.101.49.11):56 data bytes64bytesfrom180.101.49.11:seq=0ttl=127time=12.591ms64bytesfrom180.101.49.11:seq=1ttl=127time=9.736ms^C[root@k8s-master np]##至此,案例2测试成功!
测试结束。😘
案例3:允许其他命名空间Pod访问指定应用
==💘 案例3:允许其他命名空间Pod访问指定应用-2023.5.21(测试成功)==
- 实验环境
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.20.0docker:namespace/testcreated
- 创建网络策略
[root@k8s-master1 ~]#mkdir np[root@k8s-master1 ~]#cd np
[root@k8s-master1 np]#vim allow-all-namespace.yamlapiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:allow-all-namespacesnamespace:testspec:podSelector:matchLabels:run:webpolicyTypes:- Ingressingress:- from:- namespaceSelector:{} # 匹配所有命名空间的pod
- 部署
[root@k8s-master1 np]#kubectl apply -f allow-all-namespace.yaml networkpolicy.networking.k8s.io/allow-all-namespacescreated[root@k8s-master1 np]#kubectl get networkpolicy -ntestNAMEPOD-SELECTORAGEallow-all-namespacesapp=web32s
- 创建测试pod
kubectlrunbusybox--image=busybox-ntest--sleep12hkubectlrunweb--image=nginx-ntestkubectlrunbusybox--image=busybox-sleep12hkubectlrunweb--image=nginx[root@k8s-master1 ~]#kubectl get po -owideNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESbusybox1/1Running084s10.244.169.155k8s-node2<none><none>web1/1Running02m50s10.244.36.90k8s-node1<none><none>[root@k8s-master1 np]#kubectl get po -owide -ntest --show-labels NAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESLABELSbusybox1/1Running06m23s10.244.169.153k8s-node2<none><none>run=busyboxweb1/1Running06m23s10.244.36.89k8s-node1<none><none>run=web
- 在default命名空间下ping测test命名空间下的2个pod,观察效果
[root@k8s-master1 np]#kubectl exec -it busybox -- sh/# ping 10.244.169.153 #ping测buxyboxPING10.244.169.153(10.244.169.153):56 data bytes64bytesfrom10.244.169.153:seq=0ttl=63time=0.168ms^C---10.244.169.153pingstatistics---1packetstransmitted,1packetsreceived,0%packetlossround-tripmin/avg/max=0.168/0.168/0.168ms/# ping 10.244.36.89 #ping测webPING10.244.36.89(10.244.36.89):56 data bytes64bytesfrom10.244.36.89:seq=0ttl=62time=0.504ms64bytesfrom10.244.36.89:seq=1ttl=62time=0.448ms^C---10.244.36.89pingstatistics---2packetstransmitted,2packetsreceived,0%packetlossround-tripmin/avg/max=0.448/0.476/0.504ms/#
- 问题来了:不是已经配置了策略了吗?怎么还能ping通test命名空间下的buxybox pod呢?
这是因为这个策略实际上是没有意义的,因为k8s默认的策略就是各个命名空间下的pod是可以互访的。
网路策略是由网络组件控制的,网络组件是由iptable完成的,iptables是从上到下匹配的。
因此,可以看到,在default命名空间下都是可以ping通test命名空间下2个pod的。
但是,该如何解决呢?
此时就需要配合案例1的网络策略进行使用。
把案例1的网络策略当做一个安全基础,然后在此基础上做白名单限制。
[root@k8s-master1 np]#vim deny-all.yaml#deny-all.yamlapiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:deny-allnamespace:testspec:podSelector:{} # 匹配本命名空间所有podpolicyTypes:- Ingress- Egress# ingress和egress没有指定规则,则不允许任何流量进出pod#部署#注意:此时需要先删除刚才创建的那条策略,然后先部署deny-all.yaml,再部署allow-all-namespace.yamlkubectl delete -f allow-all-namespace.yaml[root@k8s-master1 np]#kubectl apply -f deny-all.yamlnetworkpolicy.networking.k8s.io/deny-all created[root@k8s-master1 np]#kubectl apply -f allow-all-namespace.yamlnetworkpolicy.networking.k8s.io/allow-all-namespaces created
- 再次测试
[root@k8s-master1 np]#kubectl exec -it busybox -- sh/# ping 10.244.36.89 #ping测webPING10.244.36.89(10.244.36.89):56 data bytes64bytesfrom10.244.36.89:seq=0ttl=62time=0.470ms^C---10.244.36.89pingstatistics---1packetstransmitted,1packetsreceived,0%packetlossround-tripmin/avg/max=0.470/0.470/0.470ms/# ping 10.244.169.153 #ping测buxyboxPING10.244.169.153(10.244.169.153):56 data bytes^C---10.244.169.153pingstatistics---3packetstransmitted,0packetsreceived,100%packetloss/#
测试结束。😘
案例4:同一个命名空间下应用之间限制访
==💘 案例4:同一个命名空间下应用之间限制访-2023.5.21(测试成功)==
案例4:同一个命名空间下应用之间限制访问需求:将test命名空间携带run=web标签的Pod隔离,只允许test命名空间携带run=client1标签的Pod访问80端口。apiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:app-to-appnamespace:testspec:podSelector:matchLabels:run:webpolicyTypes:- Ingressingress:- from:- podSelector:matchLabels:run:client1ports:- protocol:TCPport:80
- 实验环境
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.20.0docker:networkpolicy.networking.k8s.io"allow-all-namespaces"deletednetworkpolicy.networking.k8s.io"deny-all"deleted
- 创建2个test命名空间下的不同label的测试pod:
[root@k8s-master np]#kubectl get pod -n test --show-labelsNAMEREADYSTATUSRESTARTSAGELABELSbusybox1/1Running122hrun=busyboxweb1/1Running18hrun=web[root@k8s-master np]#kubectl run client1 -l run=client1--image=busybox-ntest--sleep12hpod/client1created[root@k8s-master np]#kubectl run client2 -l run=client2--image=busybox-ntest--sleep12hpod/client2created[root@k8s-master np]#kubectl get pod -n test --show-labelsNAMEREADYSTATUSRESTARTSAGELABELSbusybox1/1Running122hrun=busyboxclient11/1Running033srun=client1client21/1Running020srun=client2web1/1Running18hrun=web[root@k8s-master np]#
- 配置前测试:默认同一个命名空间下的pod都是可以直接访问的:
- 现在开始配置网络策略:
[root@k8s-master np]#vim app-to-app.yamlapiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:app-to-appnamespace:testspec:podSelector:matchLabels:run:webpolicyTypes:- Ingressingress:- from:- podSelector:matchLabels:run:client1ports:- protocol:TCPport:80[root@k8s-master np]#kubectl apply -f app-to-app.yamlnetworkpolicy.networking.k8s.io/app-to-app created
- 测试失效效果:=>符合预期。
至此,案例4实验完成。😘
案例5:只允许指定命名空间中的应用访问
==💘 案例5:只允许指定命名空间中的应用访问-2023.5.21(测试成功)==
- 实验环境
实验环境:1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,1个master节点,2个node节点k8sversion:v1.20.0docker:namespace/devcreated[root@k8s-master1 np]#kubectl run web --image=nginx-lenv=dev-ndevpod/webcreated[root@k8s-master1 np]#kubectl get po -ndev --show-labels -owideNAMEREADYSTATUSRESTARTSAGEIPNODENOMINATEDNODEREADINESSGATESLABELSweb1/1Running030s10.244.169.156k8s-node2<none><none>env=dev
- 创建ns prod及网络策略.yaml
#创建ns prod并打上标签[root@k8s-master1 np]#kubectl create ns prodnamespace/prod created[root@k8s-master1 np]#kubectl label ns prod env=prodnamespace/prod labeled[root@k8s-master1 np]#kubectl get ns prod --show-labelsNAME STATUS AGE LABELSprod Active 30s env=prod#创建网络策略.yaml[root@k8s-master1 np]#vim test.yamlapiVersion:networking.k8s.io/v1kind:NetworkPolicymetadata:name:dev-webnamespace:devspec:podSelector:matchLabels:env:devpolicyTypes:- Ingressingress:# 满足允许prod命名空间中的pod访问- from:- namespaceSelector:matchLabels:env:prod# 允许pod标签为app=client1的pod访问,所有命名空间- from:- namespaceSelector:{}podSelector:matchLabels:app:client1#部署[root@k8s-master1 np]#kubectl apply -f test.yamlnetworkpolicy.networking.k8s.io/dev-web created
- 测试
#创建测试podkubectlrunbusybox--image=busybox-nprod--sleep12h#预期:会访问成功kubectlrunbusybox--image=busybox--sleep12h#预期:会访问失败kubectlrunbusybox2--image=busybox-lapp=client1--sleep12h#预期:会访问成功#ping测试kubectlrunbusybox--image=busybox-nprod--sleep12h#预期:会访问成功kubectlrunbusybox--image=busybox--sleep12h#预期:会访问失败kubectlrunbusybox2--image=busybox-lapp=client1--sleep12h#预期:会访问成功#测试效果(以下均符合预期效果)[root@k8s-master1 np]#kubectl exec busybox -nprod -- ping 10.244.169.156PING10.244.169.156(10.244.169.156):56 data bytes64bytesfrom10.244.169.156:seq=0ttl=63time=0.161ms^C[root@k8s-master1 np]#kubectl exec -it busybox -- ping 10.244.169.156PING10.244.169.156(10.244.169.156):56 data bytes^C---10.244.169.156pingstatistics---2packetstransmitted,0packetsreceived,100%packetlosscommandterminatedwithexitcode1[root@k8s-master1 np]#kubectl exec -it busybox2 -- ping 10.244.169.156PING10.244.169.156(10.244.169.156):56 data bytes64bytesfrom10.244.169.156:seq=0ttl=62time=0.951ms64bytesfrom10.244.169.156:seq=1ttl=62time=0.600ms^C---10.244.169.156pingstatistics---2packetstransmitted,2packetsreceived,0%packetlossround-tripmin/avg/max=0.600/0.775/0.951ms
测试结束。😘
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码 x2675263825 (舍得), qq:2675263825。
🍀 微信公众号 《云原生架构师实战》
🍀 个人博客站点
上次更新时间: