一文搞懂Kubernetes网络策略(中)

从CNCF基金会的成立,到Kubernetes社区蓬勃发展,历经6载,17年异军突起,在mesos、swarm等项目角逐中,拔得头筹,继而一统容器编排,其成功的关键缘由可归纳为如下几点:html

  • 项目领导者们的坚守与远见
  • 社区的良好的运做与社区文化
  • 社区与企业落地的正反馈

今天zouyee为你们带来《一文搞懂Kubernetes网络策略(中)》,其中《kuberneter调度由浅入深:框架》正在编写中,敬请期待,当前涉及版本均为1.20.+python

3、应用场景
3.1 通常场景
a. 禁止访问指定服务
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
复制代码

img

b. 限制访问指定服务
kubectl run apiserver --image=nginx --labels app=bookstore,role=api --expose --port 80
复制代码

img

建立网络策略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
复制代码
c. 放通访问限制
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: {}
复制代码
3.2 namespace限制
a. 禁止 namespace 中非白名单流量

img

建立网络策略数组

# 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未指定,于是对于全部进入流量都禁止

b. 禁止其余 namespace 流量
kubectl create namespace secondary
kubectl run web --namespace secondary --image=nginx \
    --labels=app=web --expose --port 80
复制代码

img

建立网络配置

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>
复制代码
c. 运行全部namespace流量
kubectl run web --image=nginx --labels app=web --expose --port 80
复制代码

Diagram of  ALLOW traffic to an application from all namespaces policy

建立网络策略

# 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网络策略应用到该标签pod
  • namespaceSelector: {}匹配全部命名空间

访问测试

# 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>
复制代码
c. 指定 namespace 访问服务
# 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

建立网络策略

# 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
复制代码
d. 容许其余namespace的指定pod的流量

⚠️ Kubernetes 1.11后支持podSelectornamespaceSelector的运算符操做,同时须要网络插件支持

# 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>
...
(容许访问)
复制代码
3.3 容许外网访问服务
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为止
复制代码

img

建立网络策略

# 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
复制代码
3.5 高级功能
a. 容许应用固定端口流量
# 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
复制代码

Diagram of ALLOW traffic only to a port of an application policy

建立网络策略

# 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">
...
复制代码
b. 多标签限制

说明: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

(访问受限)
复制代码
3.6 控制出口流量
a. 禁止应用的出口流量
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: [] 策略为空说明出口流量所有禁止
b. 禁止命名空间非白名单流量

建立网络策略

# 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为空,说明匹配全部pod
  • egress为空数组,说明禁止全部符合podSelector的出口流量

后续相关内容,请查看公众号:DCOS

参考文档
相关文章
相关标签/搜索