從CNCF基金會的成立,到Kubernetes社區蓬勃發展,歷經6載,17年異軍突起,在mesos、swarm等項目角逐中,拔得頭籌,繼而一統容器編排,其成功的關鍵緣由可歸納爲如下幾點:html
今天zouyee爲你們帶來《一文搞懂Kubernetes網絡策略(中)》,其中《kuberneter調度由淺入深:框架》正在編寫中,敬請期待,當前涉及版本均爲1.20.+
。python
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
<!DOCTYPE html>
<html>
<head>
複製代碼
建立網絡策略nginx
# 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
複製代碼
訪問測試git
$ 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
複製代碼
kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
複製代碼
建立網絡策略github
# 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
複製代碼
訪問測試web
建立不加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
<!DOCTYPE html>
<html><head>
/ # exit
複製代碼
kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
複製代碼
應用a中的網絡策略,限制全部流量redis
# 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
複製代碼
建立放統統網絡策略api
# 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: {}
複製代碼
建立網絡策略數組
# 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
複製代碼
說明:markdown
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
複製代碼
建立網絡配置
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
<!DOCTYPE html>
<html>
複製代碼
kubectl run web --image=nginx --labels app=web --expose --port 80
複製代碼
建立網絡策略
# 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
<!DOCTYPE html>
<html>
複製代碼
# 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
複製代碼
建立網絡策略
# 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
<!DOCTYPE html>
<html>
<head>
...
(容許訪問)
複製代碼
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 <pending> 80:32548/TCP 40s
直至EXTERNAL-IP分配IP爲止
複製代碼
建立網絡策略
# 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
複製代碼
建立網絡策略
# 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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
...
/ # wget -qO- --timeout=2 http://apiserver:5001/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
...
複製代碼
說明: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