Kubernetes kube-proxy iptables 模式深刻剖析(一)-Kubernetes商業環境實戰

專一於大數據及容器雲核心技術解密,可提供全棧的大數據+雲原平生臺諮詢方案,請持續關注本套博客。若有任何學術交流,可隨時聯繫。更多內容請關注《數據雲技術社區》公衆號。 node

1 何爲Iptables

1.1 基本功能

  • 流量轉發:DNAT 實現 IP 地址和端口的映射;
  • 負載均衡:statistic 模塊爲每一個後端設置權重;
  • 會話保持:recent 模塊設置會話保持時間;

1.2 五條鏈

  • iptables 有五張表和五條鏈,五條鏈分別對應爲:
  • PREROUTING 鏈:數據包進入路由以前,能夠在此處進行 DNAT;
  • INPUT 鏈:通常處理本地進程的數據包,目的地址爲本機;
  • FORWARD 鏈:通常處理轉發到其餘機器或者 network namespace 的數據包;
  • OUTPUT 鏈:原地址爲本機,向外發送,通常處理本地進程的輸出數據包;
  • POSTROUTING 鏈:發送到網卡以前,能夠在此處進行 SNAT;

1.3 五張表:

這五張表是對 iptables 全部規則的邏輯集羣且是有順序的,當數據包到達某一條鏈時會按表的順序進行處理,表的優先級爲:raw、mangle、nat、filter、security。算法

  • filter 表:用於控制到達某條鏈上的數據包是繼續放行、直接丟棄(drop)仍是拒絕(reject);
  • nat 表:network address translation 網絡地址轉換,用於修改數據包的源地址和目的地址;
  • mangle 表:用於修改數據包的 IP 頭信息;
  • raw 表:iptables 是有狀態的,其對數據包有連接追蹤機制,鏈接追蹤信息在 /proc/net/nf_conntrack 中能夠看到記錄,而 raw 是用來去除連接追蹤機制的;
  • security 表:最不經常使用的表,用在 SELinux 上;

2 kube-proxy 的 iptables 模式

2.1 kube-proxy

  • kube-proxy 組件負責維護 node 節點上的防火牆規則和路由規則。
  • 在 iptables 模式下,會根據 service 以及 endpoints 對象的改變來實時刷新規則,kube-proxy 使用了 iptables 的 filter 表和 nat 表,並對 iptables 的鏈進行了擴充,自定義了 KUBE-SERVICES、KUBE-EXTERNAL-SERVICES、KUBE-NODEPORTS、KUBE-POSTROUTING、KUBE-MARK-MASQ、KUBE-MARK-DROP、KUBE-FORWARD 七條鏈。
  • 另外還新增了以「KUBE-SVC-xxx」和「KUBE-SEP-xxx」開頭的數個鏈,除了建立自定義的鏈之外還將自定義鏈插入到已有鏈的後面以便劫持數據包。

2.2 clusterIP 訪問方式

2.2.1 非本機訪問

PREROUTING --> KUBE-SERVICE --> KUBE-SVC-XXX --> KUBE-SEP-XXX
複製代碼

2.2.2 本機訪問

OUTPUT --> KUBE-SERVICE --> KUBE-SVC-XXX --> KUBE-SEP-XXX
複製代碼

2.2.3 訪問流程:

  • 1.對於進入 PREROUTING 鏈的都轉到 KUBE-SERVICES 鏈進行處理;
  • 2.在 KUBE-SERVICES 鏈,對於訪問 clusterIP 爲 10.110.243.155 的轉發到 KUBE-SVC-5SB6FTEHND4GTL2W;
  • 3.訪問 KUBE-SVC-5SB6FTEHND4GTL2W 的使用隨機數負載均衡,並轉發到 KUBE-SEP-CI5ZO3FTK7KBNRMG 和 KUBE-SEP-OVNLTDWFHTHII4SC 上;
  • 4.KUBE-SEP-CI5ZO3FTK7KBNRMG 和 KUBE-SEP-OVNLTDWFHTHII4SC 對應 endpoint 中的 pod 192.168.137.147 和 192.168.98.213,設置 mark 標記,進行 DNAT 並轉發到具體的 pod 上,若是某個 service 的 endpoints 中沒有 pod,那麼針對此 service 的請求將會被 drop 掉;
// 1.對於進入 PREROUTING 鏈的都轉到 KUBE-SERVICES 鏈進行處理;
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES

// 2.在 KUBE-SERVICES 鏈,對於訪問 clusterIP 爲 10.110.243.155 的轉發到 KUBE-SVC-5SB6FTEHND4GTL2W;
-A KUBE-SERVICES -d 10.110.243.155/32 -p tcp -m comment --comment "pks-system/tenant-service: cluster IP" -m tcp --dport 7000 -j KUBE-SVC-5SB6FTEHND4GTL2W

// 3.訪問 KUBE-SVC-5SB6FTEHND4GTL2W 的使用隨機數負載均衡,並轉發到 KUBE-SEP-CI5ZO3FTK7KBNRMG 和 KUBE-SEP-OVNLTDWFHTHII4SC 上;
-A KUBE-SVC-5SB6FTEHND4GTL2W -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-CI5ZO3FTK7KBNRMG
-A KUBE-SVC-5SB6FTEHND4GTL2W -j KUBE-SEP-OVNLTDWFHTHII4SC

// 4.KUBE-SEP-CI5ZO3FTK7KBNRMG 和 KUBE-SEP-OVNLTDWFHTHII4SC 對應 endpoint 中的 pod 192.168.137.147 和 192.168.98.213,
設置 mark 標記,進行 DNAT 並轉發到具體的 pod 上,若是某個 service 的 endpoints 中沒有 pod,那麼針對此 service 的請求將會被 drop 掉;
-A KUBE-SEP-CI5ZO3FTK7KBNRMG -s 192.168.137.147/32 -j KUBE-MARK-MASQ
-A KUBE-SEP-CI5ZO3FTK7KBNRMG -p tcp -m tcp -j DNAT --to-destination 192.168.137.147:7000

-A KUBE-SEP-OVNLTDWFHTHII4SC -s 192.168.98.213/32 -j KUBE-MARK-MASQ
-A KUBE-SEP-OVNLTDWFHTHII4SC -p tcp -m tcp -j DNAT --to-destination 192.168.98.213:7000
複製代碼

2.3 nodePort 訪問方式

  • 在 nodePort 方式下,會用到 KUBE-NODEPORTS 規則鏈,經過 iptables -t nat -L -n 能夠看到 KUBE-NODEPORTS 位於 KUBE-SERVICE 鏈的最後一個,iptables 在處理報文時會優先處理目的 IP 爲clusterIP 的報文,在前面的 KUBE-SVC-XXX 都匹配失敗以後再去使用 nodePort 方式進行匹配。
  • 建立一個 nodePort 訪問方式的 service 以及帶有兩個副本,訪問 nodeport 的 iptables 規則流向爲:

2.3.1 非本機訪問

PREROUTING --> KUBE-SERVICE --> KUBE-NODEPORTS --> KUBE-SVC-XXX --> KUBE-SEP-XXX
複製代碼

2.3.2 本機訪問

OUTPUT --> KUBE-SERVICE --> KUBE-NODEPORTS --> KUBE-SVC-XXX --> KUBE-SEP-XXX
複製代碼

2.2.4 訪問流程:

該服務的 nodePort 端口爲 30070,其 iptables 訪問規則和使用 clusterIP 方式訪問有點相似,不過 nodePort 方式會比 clusterIP 的方式多走一條鏈 KUBE-NODEPORTS,其會在 KUBE-NODEPORTS 鏈設置 mark 標記並轉發到 KUBE-SVC-5SB6FTEHND4GTL2W,nodeport 與 clusterIP 訪問方式最後都是轉發到了 KUBE-SVC-xxx 鏈。後端

  • 一、通過 PREROUTING 轉到 KUBE-SERVICES
  • 二、通過 KUBE-SERVICES 轉到 KUBE-NODEPORTS
  • 三、通過 KUBE-NODEPORTS 轉到 KUBE-SVC-5SB6FTEHND4GTL2W
  • 四、通過KUBE-SVC-5SB6FTEHND4GTL2W 轉到 KUBE-SEP-CI5ZO3FTK7KBNRMG 和 KUBE-SEP-VR562QDKF524UNPV
  • 五、通過 KUBE-SEP-CI5ZO3FTK7KBNRMG 和 KUBE-SEP-VR562QDKF524UNPV 分別轉到 192.168.137.147:7000 和 192.168.89.11:7000
// 1.
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES

// 2.
......
-A KUBE-SERVICES xxx
......
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS

// 3.
-A KUBE-NODEPORTS -p tcp -m comment --comment "pks-system/tenant-service:" -m tcp --dport 30070 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment "pks-system/tenant-service:" -m tcp --dport 30070 -j KUBE-SVC-5SB6FTEHND4GTL2W

// 四、
-A KUBE-SVC-5SB6FTEHND4GTL2W -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-CI5ZO3FTK7KBNRMG
-A KUBE-SVC-5SB6FTEHND4GTL2W -j KUBE-SEP-VR562QDKF524UNPV

// 五、
-A KUBE-SEP-CI5ZO3FTK7KBNRMG -s 192.168.137.147/32 -j KUBE-MARK-MASQ
-A KUBE-SEP-CI5ZO3FTK7KBNRMG -p tcp -m tcp -j DNAT --to-destination 192.168.137.147:7000
-A KUBE-SEP-VR562QDKF524UNPV -s 192.168.89.11/32 -j KUBE-MARK-MASQ
-A KUBE-SEP-VR562QDKF524UNPV -p tcp -m tcp -j DNAT --to-destination 192.168.89.11:7000

複製代碼

2.3 iptables 模式問題分析

  • iptables規則複雜零亂,真要出現什麼問題,排查iptables規則必然得掉層皮。LOG+TRACE大法也很差使。
  • iptables規則多了以後性能降低,這是由於iptables規則是基於鏈表實現,查找複雜度爲O(n),當規模很是大時,查找和處理的開銷就特別大。據官方說法,當節點到達5000個時,假設有2000個NodePort Service,每一個Service有10個Pod,那麼在每一個Node節點中至少有20000條規則,內核根本支撐不住,iptables將成爲最主要的性能瓶頸。
  • iptables主要是專門用來作主機防火牆的,而不是專長作負載均衡的。雖然經過iptables的 statistic模塊以及DNAT可以實現最簡單的只支持機率輪詢的負載均衡,可是每每咱們還須要更多更靈活的算法,好比基於最少鏈接算法、源地址HASH算法等。而一樣基於netfilter的ipvs倒是專門作負載均衡的,配置簡單,基於散列查找O(1)複雜度性能好,支持數十種調度算法。所以顯然IPVS比iptables更適合作kube-proxy的後端,畢竟專業的人作專業的事,物盡其美。

2.4 最後

專一於大數據及容器雲核心技術解密,可提供全棧的大數據+雲原平生臺諮詢方案,請持續關注本套博客。若有任何學術交流,可隨時聯繫。更多內容請關注《數據雲技術社區》公衆號。 bash

相關文章
相關標籤/搜索