今天zouyee为大家带来《一文搞懂Kubernetes网络策略(下)》,其中《kuberneter调度由浅入深:框架》预期周五出,敬请期待,当前涉及版本均为1.20. ,该篇承接一文搞懂Kubernetes网络策略(上)
注:如果关心各CNI插件的能力评比,可查看第四节。
三、应用场景
外网流量
代码语言:javascript复制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为止
创建网络策略
代码语言:javascript复制# 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
高级功能
a. 允许应用固定端口流量
代码语言:javascript复制# 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
创建网络策略
代码语言:javascript复制# 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
访问测试
代码语言:javascript复制# 启动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服务
代码语言:javascript复制kubectl run db --image=redis:4 --port 6379 --expose
--labels app=bookstore,role=db
以下服务共享redis服务
代码语言:javascript复制app=bookstore role=search
创建网络策略
代码语言:javascript复制# 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
访问测试
代码语言:javascript复制$ 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
(访问受限)
控制出口流量
a. 禁止应用的出口流量
代码语言:javascript复制kubectl run web --image=nginx --labels app=web --expose --port 80
创建网络策略
代码语言:javascript复制# 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
说明:
代码语言:javascript复制 policyTypes: ["egress"] 该策略类型为出口流量
代码语言:javascript复制 egress: [] 策略为空说明出口流量全部禁止
b. 禁止命名空间非白名单流量
创建网络策略
代码语言:javascript复制# 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
的出口流量
四、开发
实现一个支持 Network Policy 的网络扩展需要至少包含两个组件
- CNI 网络插件:负责给 Pod 配置网络接口
- Policy controller:监听 Network Policy 的变化,并将 Policy 应用到相应的网络接口
性能测试
下图基于Kubernetes 1.19版本测试了以下特性(后续接一篇译文):
1)MTU auto config
2)带宽性能: Pod to Pod、Pod to Service(TCP、UDP)
3)资源消耗: Pod to Pod、Pod to Service(TCP、UDP)
4)安全特性:Network Policies、 Encryption等
calico其他详细的能力说明,可参看官网。
五、展望
a. SCTP特性
支持版本:Kubernetes v1.19 [beta]
作为一个 Beta 特性,SCTP 默认是被启用的。要在集群层面禁用 SCTP,需要为 kube-apiserver关闭特性--feature-gates=SCTPSupport=false,... 以禁用 SCTP 。启用该特性后,用户可以将 NetworkPolicy 的 protocol字段设置为 SCTP。
⚠️ CNI插件需要支持SCTP协议
b. 待开发
截止Kubernetes v1.20 ,NetworkPolicy API 还不支持下述功能。
- 强制集群内部流量经过某公用网关(可通过服务网格或其他代理来实现)
- 与 TLS 相关的场景(可使用服务网格或者 Ingress 控制器)
- 实现适用于所有名字空间或 Pods 的默认策略(如calico)
- 高级的策略查询或者策略验证相关工具(如calico)
- 在同一策略声明中选择目标端口范围的能力
- 生成网络安全事件日志的能力(例如,被阻塞或接收的连接请求)
- 禁止本地回路或指向宿主的网络流量(Pod 目前无法阻塞 localhost 访问, 它们也无法禁止来自所在节点的访问请求)。
上述需求可以通过操作系统组件(如 SELinux、OpenVSwitch、IPTables 等) 或者七层技术(Ingress 控制器、服务网格实现)及准入控制器进行功能增强,当然有兴趣的可以参考calico及OPA项目。
参考资料
1. Kubernetes 官网:https://kubernetes.io/docs/concepts/services-networking/network-policies/
2. Declare Network Policy: https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/
3. Securing Kubernetes Cluster Networking: https://ahmet.im/blog/kubernetes-network-policy/
4. fesikyer network policy: https://github.com/feiskyer/kubernetes-handbook/blob/master/concepts/network-policy.md
END
往期 · 精选
1、干货分享 | 一文搞懂Kubernetes网络策略(上)
2、干货分享 | CloudEvents三部曲:实践篇
3、干货分享 | K8S调度系统由浅入深:简介