从CNCF基金会的成立,到Kubernetes社区蓬勃发展,历经6载,17年异军突起,在mesos、swarm等项目角逐中,拔得头筹,继而一统容器编排,其成功的关键原因可概括为以下几点:
今天zouyee为大家带来《一文搞懂Kubernetes网络策略(中)》,其中《kuberneter调度由浅入深:框架》正在编写中,敬请期待,当前涉及版本均为1.20.+
。
kubectl run web --image=nginx --labels app=web --expose --port 80
# 未有策略限制时,可以访问
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- http://web
创建网络策略
# cat web-deny-all.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-deny-all
spec:
podSelector:
matchLabels:
app: web
ingress: []
$ kubectl apply -f web-deny-all.yaml
networkpolicy "web-deny-all" created
访问测试
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web
wget: download timed out
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z51BXeZ7-1610540947696)(https://github.com/feiskyer/kubernetes-handbook/raw/master/concepts/images/15022447799137.jpg)]
kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8zb81ipb-1610540947700)(https://github.com/feiskyer/kubernetes-handbook/raw/master/concepts/images/15022448622429.jpg)]
创建网络策略
# cat api-allow.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: api-allow
spec:
podSelector:
matchLabels:
app: bookstore
role: api
ingress:
- from:
- podSelector:
matchLabels:
app: bookstore
# kubectl apply -f api-allow.yaml
networkpolicy "api-allow" created
访问测试
创建不加label的pod,预期结果,访问被限制
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://apiserver
wget: download timed out
/ # exit
创建带app=bookstore标签的pod,预期结果,访问被限制
$ kubectl run busybox --rm -ti --image=busybox --labels app=bookstore,role=frontend /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://apiserver
/ # exit
kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
应用a中的网络策略,限制所有流量
# cat web-deny-all.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-deny-all
spec:
podSelector:
matchLabels:
app: web
ingress: []
$ kubectl apply -f web-deny-all.yaml
networkpolicy "web-deny-all" created
创建放通通网络策略
# cat web-deny-all.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-all
namespace: default
spec:
podSelector:
matchLabels:
app: web
ingress:
- {}
$ kubectl apply -f web-allow-all.yaml
networkpolicy "web-allow-all" created
# 需要注意deny跟allow的细微差别就是[]与{},其中{}代表
- from:
podSelector: {}
namespaceSelector: {}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-37ZH9o67-1610540947701)(https://github.com/feiskyer/kubernetes-handbook/raw/master/concepts/images/15022451724392.gif)]
创建网络策略
# cat default-deny-all.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
ingress: []
# kubectl apply -f default-deny-all.yaml
说明:
namespace: default
该策略部署于default
podSelector
为{}
指匹配所有pod,因而该策略对default命名空间的所有pod都有效
ingress
未指定,因而对于所有进入流量都禁止
kubectl create namespace secondary
kubectl run web --namespace secondary --image=nginx \
--labels=app=web --expose --port 80
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pg0T7LVz-1610540947704)(https://github.com/feiskyer/kubernetes-handbook/raw/master/concepts/images/15022452203435.gif)]
创建网络配置
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: secondary
name: web-deny-other-namespaces
spec:
podSelector:
matchLabels:
ingress:
- from:
- podSelector: {}
访问测试
# default命名空间访问
$ kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.secondary
wget: download timed out
/ # exit
# secondary命名空间访问
$ kubectl run busybox --rm -ti --image=busybox --namespace=secondary /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.secondary
kubectl run web --image=nginx --labels app=web --expose --port 80
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jU76Cogk-1610540947705)(https://github.com/ahmetb/kubernetes-network-policy-recipes/raw/master/img/5.gif)]
创建网络策略
# cat web-allow-all-namespaces.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
namespace: default
name: web-allow-all-namespaces
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector: {}
# kubectl apply -f web-allow-all-namespaces.yaml
# kubectl create namespace secondary
说明:
app: web
网络策略应用到该标签podnamespaceSelector: {}
匹配所有命名空间访问测试
# kubectl run busybox --rm -ti --image=busybox --namespace=secondary /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.secondary
# kubectl run web --image=nginx \
--labels=app=web --expose --port 80
# kubectl create namespace dev
# kubectl label namespace/dev purpose=testing
# kubectl create namespace prod
# kubectl label namespace/prod purpose=production
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MpE9ybpr-1610540947706)(https://github.com/feiskyer/kubernetes-handbook/raw/master/concepts/images/15022453441751.gif)]
创建网络策略
# cat web-allow-prod.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-prod
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: production
# kubectl apply -f web-allow-prod.yaml
⚠️ Kubernetes 1.11后支持podSelector
与namespaceSelector
的运算符操作,同时需要网络插件支持
# kubectl run web --image=nginx \
--labels=app=web --expose --port 80
# kubectl create namespace other
# kubectl create namespace other
创建网络策略
# cat web-allow-all-ns-monitoring.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-all-ns-monitoring
namespace: default
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector: # 选择namespaces中带有team=operations标签的pod
matchLabels:
team: operations
podSelector: # 选择带有type=monitoring标签的pod
matchLabels:
type: monitoring
# kubectl apply -f web-allow-all-ns-monitoring.yaml
访问测试
kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
wget: download timed out
(访问限制)
/ # exit
# kubectl run busybox --rm -ti --image=busybox --labels type=monitoring /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
wget: download timed out
(访问限制)
# kubectl run busybox --rm -ti --image=busybox --namespace=other /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
wget: download timed out
(访问限制)
# kubectl run busybox --rm -ti --image=busybox --namespace=other --labels type=monitoring /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://web.default
...
(允许访问)
kubectl run web --image=nginx --labels=app=web --port 80
kubectl expose pod/web --type=LoadBalancer
kubectl get svc web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web LoadBalancer 10.233.54.206 80:32548/TCP 40s
直至EXTERNAL-IP分配IP为止
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dn1GgTua-1610540947707)(https://github.com/feiskyer/kubernetes-handbook/raw/master/concepts/images/15022454444461.gif)]
创建网络策略
# cat web-allow-external.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: web-allow-external
spec:
podSelector:
matchLabels:
app: web
ingress:
- ports:
- port: 80
from: []
# kubectl apply -f web-allow-external.yaml
# kubectl run busybox -ti --image=busybox --labels=app=apiserver /bin/sh
If you don't see a command prompt, try pressing enter.
# nohup python3 -m http.server 8001 &
# nohup python3 -m http.server 5001 &
# exit
# kubectl create service clusterip apiserver \
--tcp 8001:8000 \
--tcp 5001:5000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZccFMn4h-1610540947708)(https://github.com/ahmetb/kubernetes-network-policy-recipes/raw/master/img/9.gif)]
创建网络策略
# cat api-allow-5000.yml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: api-allow-5000
spec:
podSelector:
matchLabels:
app: apiserver
ingress:
- ports:
- port: 5000
from:
- podSelector:
matchLabels:
role: monitoring
# kubectl apply -f api-allow-5000.yml
访问测试
# 启动pod未携带指定label时,访问受限
# kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget -qO- --timeout=2 http://apiserver:8001
wget: download timed out
/ # wget -qO- --timeout=2 http://apiserver:5001/metrics
wget: download timed out
# 启动pod携带指定label时,访问不受限
$ kubectl run busybox --rm -ti --image=busybox --labels=role=monitoring /bin/sh
/ # wget -qO- --timeout=2 http://apiserver:8001
...
/ # wget -qO- --timeout=2 http://apiserver:5001/
...
说明:Network Policy定义一组微服务访问某一应用,如下述示例中,一组微服务共享redis服务
kubectl run db --image=redis:4 --port 6379 --expose \
--labels app=bookstore,role=db
以下服务共享redis服务
service | labels |
---|---|
search |
app=bookstore role=search |
api |
app=bookstore role=api |
catalog |
app=inventory role=web |
创建网络策略
# cat redis-allow-services.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: redis-allow-services
spec:
podSelector:
matchLabels:
app: bookstore
role: db
ingress:
- from:
- podSelector:
matchLabels:
app: bookstore
role: search
- podSelector:
matchLabels:
app: bookstore
role: api
- podSelector:
matchLabels:
app: inventory
role: web
# kubectl apply -f redis-allow-services.yaml
访问测试
$ kubectl run busybox --rm -ti --image=curl --labels=app=inventory,role=web /bin/sh
/ # nc -v -w 2 db 6379
db (10.233.27.143:6379) open
(works)
$ kubectl run busybox --rm -ti --image=curl --labels=app=other /bin/sh
/ # nc -v -w 2 db 6379
nc: db (10.233.27.143:6379): Operation timed out
(访问受限)
kubectl run web --image=nginx --labels app=web --expose --port 80
创建网络策略
# cat foo-deny-egress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: foo-deny-egress
spec:
podSelector:
matchLabels:
app: foo
policyTypes:
- Egress
egress: []
# kubectl apply -f foo-deny-egress.yaml
说明:
policyTypes: ["egress"]
该策略类型为出口流量egress: []
策略为空说明出口流量全部禁止创建网络策略
# cat default-deny-all-egress.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny-all-egress
namespace: default
spec:
policyTypes:
- Egress
podSelector: {}
egress: []
# kubectl apply -f default-deny-all-egress.yaml
说明:
podSelector
为空,说明匹配所有podegress
为空数组,说明禁止所有符合podSelector
的出口流量后续相关内容,请查看公众号:DCOS