k8s中网络策略(networkpolicy)的工作原理
1、工作原理说明
1.1、什么是k8s的网络策略?
在k8s中,如何要实现容器访问的安全策略,可以通过网络策略,在pod上增加网络的访问限制,控制哪些客户端可以访问这个pod,也可以控制pod可以访问哪些其他的网络。
k8s的网络策略想要工作,也就是说,真正的实现pod间的访问流量的控制,需要部署k8s的网络插件。
1.2、k8s网络策略的基本实现原理
用下面的公式可以表示:
k8s容器网络流量控制 = 网络策略配置 + 网络控制器插件
1.3、k8s的默认的网络策略
默认情况,在k8s的集群中,允许所有的pod之间的网络访问。
也就是,没有任何的限制。
同时,设置的网络策略,都是允许访问的设置。
1.4、k8s的网络策略的配置模板说明
下面,我们看一个k8s网络策略配置的模板文件:
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
各个参数解释如下:
下面的部分,设置的是,将网络策略设置在哪些pod上
在网络策略的设置中,通过标签匹配的方式,设置作用的pod范围。
spec:
podSelector:
matchLabels:
role: db
策略类型的设置部分,设置允许的规则类型,ingress是入站规则,egress是出站规则。
入站规则:就是哪些条件可以访问目标pod
出站规则:就是目标pod可以访问哪些地址
policyTypes: - Ingress - Egress
是入站规则的设置部分
from中的条件,表示条件可以访问目标pod,在这个例子里面就是哪些条件可以访问,有标签role: db 的pod
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
设置ip的范围,这些范围内的IP地址可以访问目标pod
- ipBlock: cidr: 172.17.0.0/16 except: - 172.17.1.0/24
命名空间的匹配,在这个命名空间中的pod可以访问目标pod
- namespaceSelector:
matchLabels:
project: myproject
客户端的pod,如果有role: frontend这样的标签,就可以访问目标的pod
- podSelector:
matchLabels:
role: frontend
被访问的目标pod的端口的设置,目标pod的6379允许被访问到
ports: - protocol: TCP port: 6379
出站规则设置,允许目标pod访问某个IP范围的5978端口
egress: - to: - ipBlock: cidr: 10.0.0.0/24 ports: - protocol: TCP port: 5978
OK,k8s的网络策略简单的工作原理说明之后,下面通过一些实验,让你直观的感受一下,在k8s的集群中,设置了这些的网络策略之后,对网络的访问,到底有什么影响
2、网络策略实验
如前面所说的,默认的k8s集群中,所有的pod间的访问都是允许的,都是放开的,并且,网络策略的设置,也是允许的访问设置。
这样,就看不出来有哪些的影响了,所以,我们现在做两件事情:
- 部署网络插件(本示例使用calico的网路插件)
- 修改默认的网络策略,禁止所有的pod间的访问。
2.1、网络插件部署
如果使用的是calico的网络插件,需要确保在k8s的集群中,有calico-kube-controllers的pod在运行
[root@nccztsjb-node-23 yamls]# kubectl get pod -n kube-system | grep calico-kube calico-kube-controllers-7cf968cdfd-gghj7 1/1 Running 2 (110d ago) 168d [root@nccztsjb-node-23 yamls]#
在calico-kube-controllers中,包含了policy controller,可以用来同步和管理k8s 网络策略。
2.2、禁止所有的入站访问流量设置
设置如下的网络策略,默认禁止所有的pod的入站访问
kubectl apply -f - <<EOF kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: default-deny-ingress namespace: default spec: podSelector: matchLabels: {} policyTypes: - Ingress EOF
[root@nccztsjb-node-23 yamls]# kubectl get networkpolicy NAME POD-SELECTOR AGE default-deny-ingress <none> 11s
这样,在default命名空间中的pod,就禁止任何其他的pod访问了。
nginx-deployment 这个pod就不允许外部的访问了
就是说,如果在ns1这个命名空间中,有一个pod,这个pod还是允许被访问的。
ns1命名空间中的pod是允许被其他命名空间中的pod访问的。
[root@nccztsjb-node-23 yamls]# kubectl get pod -n ns1 -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ns1-fb8566f97-n4wfn 1/1 Running 0 5m35s 172.39.21.68 nccztsjb-node-25 <none> <none> [root@nccztsjb-node-23 yamls]# [root@nccztsjb-node-23 yamls]# [root@nccztsjb-node-23 yamls]# kubectl exec -it testpod3 -- sh / # / # wget 172.39.21.68 Connecting to 172.39.21.68 (172.39.21.68:80) saving to 'index.html' index.html 100% |****************************************************************************************************************************************************************************************************************************| 615 0:00:00 ETA 'index.html' saved / #
这里有个结论,网络策略的作用范围是在命名空间级别的。
2.3、设置网络策略
这里,通过以下的配置,设置网络策略:
这个网络策略,设置要访问有app=nginx标签的pod,在default命名空间中
并且只允许,有run=testpod3标签的pod进行访问
并且只可以访问80端口
kubectl apply -f - <<EOF apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default # 命名空间名称 spec: podSelector: matchLabels: app: nginx # 标签选择要受影响的 Pod policyTypes: - Ingress # 定义入站规则 ingress: - from: - podSelector: matchLabels: run: testpod3 # 允许来自 app: frontend 标签的 Pod ports: - protocol: TCP port: 80 EOF
在环境里面,就有2个网络策略了
[root@nccztsjb-node-23 yamls]# kubectl get networkpolicy NAME POD-SELECTOR AGE default-deny-ingress <none> 6m3s test-network-policy app=nginx 5s [root@nccztsjb-node-23 yamls]#
这个时候,做下面的访问测试
下面的pod有app=nginx标签
[root@nccztsjb-node-23 yamls]# kubectl get pod -o wide -l app=nginx NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deployment-6bfdb59f47-4qgr4 1/1 Running 0 55d 172.39.157.240 nccztsjb-node-24 <none> <none> nginx-deployment-6bfdb59f47-6kjn5 1/1 Running 0 55d 172.39.21.114 nccztsjb-node-25 <none> <none> nginx-deployment-6bfdb59f47-dlr47 1/1 Running 0 55d 172.39.21.115 nccztsjb-node-25 <none> <none> nginx-deployment-7fbdb85b5b-8vxhp 0/1 CrashLoopBackOff 3947 (3m53s ago) 14d 172.39.21.74 nccztsjb-node-25 <none> <none> [root@nccztsjb-node-23 yamls]#
通过其他的pod进行访问
选择一个标签是run=testpod4的pod进行访问,发现无法访问
[root@nccztsjb-node-23 yamls]# kubectl get pod -o wide --show-labels NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS bash 0/1 ImagePullBackOff 0 56d 172.39.21.110 nccztsjb-node-25 <none> <none> run=bash deployment-nodename-598765fbc9-g9xdj 1/1 Running 0 46d 172.39.157.210 nccztsjb-node-24 <none> <none> app=example-app,pod-template-hash=598765fbc9 deployment-nodename-598765fbc9-rfzkz 1/1 Running 0 46d 172.39.157.199 nccztsjb-node-24 <none> <none> app=example-app,pod-template-hash=598765fbc9 deployment-nodename-598765fbc9-z8qvt 1/1 Running 0 46d 172.39.157.238 nccztsjb-node-24 <none> <none> app=example-app,pod-template-hash=598765fbc9 load-generator 1/1 Running 0 151d 172.39.21.81 nccztsjb-node-25 <none> <none> run=load-generator nginx-deployment-6bfdb59f47-4qgr4 1/1 Running 0 55d 172.39.157.240 nccztsjb-node-24 <none> <none> app=nginx,pod-template-hash=6bfdb59f47 nginx-deployment-6bfdb59f47-6kjn5 1/1 Running 0 55d 172.39.21.114 nccztsjb-node-25 <none> <none> app=nginx,pod-template-hash=6bfdb59f47 nginx-deployment-6bfdb59f47-dlr47 1/1 Running 0 55d 172.39.21.115 nccztsjb-node-25 <none> <none> app=nginx,pod-template-hash=6bfdb59f47 nginx-deployment-7fbdb85b5b-8vxhp 0/1 Error 3948 (5m22s ago) 14d 172.39.21.74 nccztsjb-node-25 <none> <none> app=nginx,pod-template-hash=7fbdb85b5b nginx-network-75c8777ddf-r7glj 1/1 Running 0 50d 172.39.157.202 nccztsjb-node-24 <none> <none> app=nginx2,pod-template-hash=75c8777ddf nginxhostport 1/1 Running 1 (80d ago) 90d 172.39.157.198 nccztsjb-node-24 <none> <none> app=nginxhostport nginxhostport2 1/1 Running 0 90d 172.39.21.98 nccztsjb-node-25 <none> <none> app=nginxhostport2 nginxhostport3 0/1 Pending 0 90d <none> <none> <none> <none> app=nginxhostport3 php-apache-6cb76cff7b-n5lpt 1/1 Running 0 75d 172.39.157.228 nccztsjb-node-24 <none> <none> pod-template-hash=6cb76cff7b,run=php-apache pod-nodename 1/1 Running 0 46d 172.39.157.204 nccztsjb-node-24 <none> <none> <none> testpod 0/1 ErrImagePull 0 56d 172.39.21.106 nccztsjb-node-25 <none> <none> run=testpod testpod2 0/1 CrashLoopBackOff 15772 (45s ago) 56d 172.39.157.249 nccztsjb-node-24 <none> <none> run=testpod2 testpod3 1/1 Running 1 (55d ago) 56d 172.39.21.113 nccztsjb-node-25 <none> <none> run=testpod3 testpod4 1/1 Running 1 (55d ago) 55d 172.39.157.195 nccztsjb-node-24 <none> <none> run=testpod4 [root@nccztsjb-node-23 yamls]# [root@nccztsjb-node-23 yamls]# [root@nccztsjb-node-23 yamls]# kubectl exec -it testpod4 -- sh / # / # wget 172.39.157.240 Connecting to 172.39.157.240 (172.39.157.240:80)
选择run=testpod3的pod进行访问,发现在testpo3 pod里面,是可以访问任何的app=nginx的pod的
满足预期的目标。
3、附录
前面对禁止所有的入站规则,并且开放某些pod的入站规则,其他的测试也是类似的,可以自行设置。
3.1、禁止所有的出站流量规则设置
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-egress spec: podSelector: {} policyTypes: - Egress
3.2、同时禁止入站、出站的流量规则设置
通过下面的设置,可以同时禁止掉,出站和入站的规则设置。
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all spec: podSelector: {} policyTypes: - Ingress - Egress
3.3、允许所有的入站流量规则设置
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-ingress spec: podSelector: {} ingress: - {} policyTypes: - Ingress
3.4、允许所有的出站流量规则的设置
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-egress spec: podSelector: {} egress: - {} policyTypes: - Egress
你好,
如果你读完了整个技术文章,说明你是个技术爱好者,钻研者。
在4年多的k8s体系运维时间里,我整理了230个,k8s最常见(最关键)的问题。
这些问题,让我轻松地应对几乎所有的k8s问题,并且,都是基于项目及大量的实验的总结。
如果你能够彻底掌握这些问题,你的知识体系,k8s基本功,就可以轻松超过80%的k8s运维人员。
更重要的是,掌握这些知识非常简单,每天5个问题,2个月后,你就可以打下k8s的见识基础,让你在云原生领域游刃有余。
每个问题,都有对应的答案,以及相关的示例演示(有些还有项目背景说明)
只要,一步一步,跟着做,就可以了。
当然,如果你想要在更短的时间内,成为k8s高手,你只需要多练习几次就可以了。
不过,和你自己从头摸索相比较,大大减少了你的学习时间,同时,大大提升了你的学习效力。
更加重要的是,如果你知道20/80原理,你就会明白,这些都是工作中最常用,最有效的20%的问题。
这个资料是第一次公开,为了了解市场上,有多少人在关注k8s的技术,我决定免费赠送这个问题指南,只当交个朋友。
添加微信:13240133388,备注:k8s
我将送你一份免费的PDF报告。
你应该知道,一本k8s权威指南(800页,没几个人看得完),要179.90元,这些问题,是在反复阅读和实践了这本书之后,结合项目实践,得出来的精华。
想想看,这将节省你多少时间?而你得到是最精华的部分?
相信你,掌握之后,立马让你的工作的效率大增,你的领导会对你的进步刮目相看。
PS. 行动是一切的开始,现在立马订阅吧。期待你的蜕变。