network policy顧名思義就是對pod進行網絡策略控制。 k8s自己並不支持,由於k8s有許多種網絡的實現方式,企業內部可使用簡單的flannel、weave、kube-router等,適合公有云的方案則有calico等。不一樣的網絡實現原理(vethpair、bridge、macvlan等)並不能統一地支持network policy。node
使用network policy
資源能夠配置pod的網絡,networkPolicy是namespace scoped的,他只能影響某個namespace下的pod的網絡出入站規則。nginx
策略模型能夠參考官方文檔, 這裏舉個例子:正則表達式
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
該例子的效果以下:
一、default
namespace下label包含role=db
的pod,都會被隔絕,他們只能創建「知足networkPolicy的ingress和egress描述的鏈接」。即2-5點:
二、全部屬於172.17.0.0/16
網段的IP,除了172.17.1.0/24
中的ip,其餘的均可以與上述pod的6379端口創建tcp鏈接。
三、全部包含label:project=myproject
的namespace中的pod能夠與上述pod的6379端口創建tcp鏈接;
四、全部default
namespace下的label包含role=frontend
的pod能夠與上述pod的6379端口創建tcp鏈接;
五、容許上述pod訪問網段爲10.0.0.0/24
的目的IP的5978端口。api
再例,若是咱們想要只容許default這個namespace下label包含access=true的pod訪問nginx pod(label:run=nginx),能夠對nginx pod設置入站規則:安全
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: access-nginx namespace: default spec: podSelector: matchLabels: run: nginx ingress: - from: - podSelector: matchLabels: access: "true"
另一些默認的規則:
1.同namespace的pod,入站規則爲所有禁止網絡
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Ingress
2.同namespace的pod,入站規則爲所有開放:frontend
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} ingress: - {}
3.同namespace的pod,出站規則爲所有禁止tcp
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny spec: podSelector: {} policyTypes: - Egress
4.同namespace的pod,出站規則爲所有開放工具
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} egress: - {} policyTypes: - Egress
network policy的實現仰賴CNI插件的支持,目前已經支持的cni插件包括:
Calico 。calico自己經過BGP路由實現容器網絡,network policy大體也是經過它實現的。
Cilium
Kube-router。 這個工具比較吸引人,由於他使用iptables實現networkpolicy,同時它也能成爲kube-proxy組件的替代品。
Romana
Weave Net。也是經過iptables實現出入站策略。(看了社區的例子,裏面針對namespace級別的控制好像要用正則表達式進行匹配)
這些容器網絡解決方案,在支持networkpolicy時,均須要在node上啓動agent(能夠用k8s的daemonset)性能
其實network policy要作的事情,安全組同樣能夠作。但network policy能夠作到namespace範圍的總體控制。
思考一個networkpolicy agent要作的事情,應該包含如下幾點:
一、對networkpolicy進行全namespace範圍的list & watch;
二、對規則原語的解析和定製。(如何將namespace、label等概念具象到iptables中?個人想法比較笨拙:使用正則表達式表述pod name的規則,同時list-watch pod並維護pod name 到pod ip的關係)
三、維護這些規則在本地的實現和記錄(如iptables表)
安全組的規則記錄在上層網關,而不是每個節點上在安全組規則上,可能須要list watch networkPolicy、namespace、pod等資源,所以實現namespace級別的策略可能會影響其性能。