kubernetes network policy學習筆記

簡介

network policy顧名思義就是對pod進行網絡策略控制。 k8s自己並不支持,由於k8s有許多種網絡的實現方式,企業內部可使用簡單的flannel、weave、kube-router等,適合公有云的方案則有calico等。不一樣的網絡實現原理(vethpair、bridge、macvlan等)並不能統一地支持network policy。node

network policy 策略模型

使用network policy資源能夠配置pod的網絡,networkPolicy是namespace scoped的,他只能影響某個namespace下的pod的網絡出入站規則。nginx

  • metadata 描述信息
  • podSelector pod選擇器,選定的pod全部的出入站流量要遵循本networkpolicy的約束
  • policyTypes 策略類型。包括了Ingress和Egress,默認狀況下一個policyTypes的值必定會包含Ingress,當有egress規則時,policyTypes的值中會包含Egress
  • ingress 入站
  • egress 出站

策略模型能夠參考官方文檔, 這裏舉個例子:正則表達式

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的實現

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)性能

思考:與neutron 網絡中安全組的區別

其實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級別的策略可能會影響其性能。

相關文章
相關標籤/搜索