K8S原理剖析:Service原理剖析和實踐

大綱

  • Kubernetes的Service機制
  • Iptables實現Service負載均衡
  • 當前Iptables實現存在的問題
  • IPVS實現Service負載均衡
  • Iptables VS. IPVS

Kubernetes的Service機制

但,簡單的生活總是暫時的:

  • - 多個後端實例,如何做到負載均衡?
  • - 如何保持會話親和性?
  • - 容器遷移, IP發生變化如何訪問?
  • - 健康檢查怎麼做?
  • - 怎麼通過域名訪問?

Iptables實現Service負載均衡

用戶空間應用程序,通過配置Netfilter規則表( Xtables )來構建linux內核防火牆。

Iptables實現流量轉發與負載均衡

Iptables如何做流量轉發?

  • DNAT實現IP地址和端口映射
  • iptables -t nat -A PREROUTING -d 1.2.3.4/32 --dport 80 -j DNAT --to-destination 10.20.30.40:8080

Iptables如何做負載均衡?

  • statistic模塊爲每個後端設置權重
  • iptables -t nat -A PREROUTING -d 1.2.3.4 --dport 80 -m statistic --mode random --probability .25 -j DNAT --to-destination 10.20.30.40:8080

Iptables如何做會話保持?

  • recent模塊設置會話保持時間
  • iptables -t nat –A FOO -m recent --rcheck --seconds 3600 --reap --name BAR -j BAR

當前Iptables實現存在的問題

Iptables做負載均衡的問題

規則線性匹配時延

  • - KUBE-SERVICES鏈掛了一長串KUBE-SVC-*鏈;訪問每個service,要遍歷每條鏈直到匹配,時間複雜度O(N)

 

規則更新時延

  • - 非增量式


 可擴展性

  • - 當系統存在大量iptables規則鏈時,增加/刪除規則會出現kernel lock
  • kernel lock: Another app is currently holding the xtables lock. Perhaps you want to use the -w option?

 

可用性

  • - 後端實例擴容,服務會話保持時間更新等都會導致連接斷開

更新Iptables規則的時延

時延出現在哪?

  • - 非增量式,即使加上—no-flush(iptables-restore)選項
  • - Kube-proxy定期同步iptables狀態:
    • * 拷貝所有規則: iptables-save
    • * 在內存中更新規則
    • * 在內核中修改規則: iptables-restore
    • * 規則更新期間存在kernel lock


5K service( 40K 規則),增加一條iptables規則,耗時11min
20K service( 160K 規則),增加一條iptables規則,耗時5h

K8S Scalability

  • 5K Nodes, 100K Pod
  • 1K Services ??

IPVS實現Service負載均衡

什麼是IPVS( IP Virtual Server)

Linux內核實現的L4 LB, LVS負載均衡的實現
基於netfilter, hash table
支持TCP, UDP, SCTP協議, IPV4, IPV6
 支持多種負載均衡策略

  • - rr, wrr, lc, wlc, sh, dh, lblc…

 支持會話保持

  • - persistent connection調度算法

IPVS三種轉發模式

支持三種LB模式: Direct Routing(DR), Tunneling, NAT

  • - DR模式工作在L2,最快,但不支持端口映射
  • - Tunneling模式用IP包封裝IP包,也稱IPIP模式,不支持端口映射
  • - DR和Tunneling模式,回程報文不會經過IPVS Director
  • - NAT模式支持端口映射,回程報文經過IPVS Director
    • * 內核原生版本只做DNAT,不做SNAT

IPVS工作流

IPVS做L4轉發

1. 綁定VIP

  • - dummy網卡
    • # ip link add dev dummy0 type dummy
    • # ip addr add 192.168.2.2/32 dev dummy0
  • - 本地路由表
    • # ip route add to local 192.168.2.2/32 dev eth0 proto kernel
  • - 網卡別名
    • # ifconfig eth0:1 192.168.2.2 netmask 255.255.255.255 up


2. 創建IPVS Virtual Server

  • # ipvsadm -A -t 192.168.60.200:80 -s rr -p 600


3. 創建IPVS Real Server

  • # ipvsadm -a -t 192.168.60.200:80 -r 172.17.1.2:80 –m
  • # ipvsadm -a -t 192.168.60.200:80 -r 172.17.2.3:80 –m

Kubernetes支持IPVS模式

社區1.8 Alpha特性, Owner @m1093782566
社區1.9進beta, Owner @m1093782566
社區1.11進GA,廣泛使用下一步成爲默認模式


支持ClusterIP, NodePort, External IP, Load Balancer…類型Service

  • – iptables模式的特性, IPVS模式都支持!

兼容Network Policy
依賴iptables做SNAT和訪問控制

Iptables VS. IPVS

Iptables VS. IPVS 規則刷新時延

Service基數 1 5000 20000
Rules基數 8 40000 160000
增加1條Iptables規則 50 us 11 min 5 hours
增加1條IPVS規則 30 us 50 us 70 us

觀察結果:

  • 增加一條Iptables的時延,隨着規則數的增加“指數”上升
  • 增加一條IPVS的時延,規則基數對其幾乎沒影響

Iptables VS. IPVS 網絡帶寬

Service基數 1 5000 20000
Rules基數 8 40000 160000
增加1條Iptables規則 50 us 11 min 5 hours
增加1條IPVS規則 30 us 50 us 70 us

觀察結果:

  • 增加一條Iptables的時延,隨着規則數的增加“指數”上升
  • 增加一條IPVS的時延,規則基數對其幾乎沒影響

Iptables VS. IPVS 資源消耗

消耗資源 Service數量 IPVS Iptables
內存 1000 386 MB 1.1 G
5000 N/A 1.9 G
10000 542 MB 2.3 G
15000 N/A OOM
50000 1272 MB OOM
CPU 1000 0% N/A
5000 50% - 85%
10000 50%-100%
15000 N/A
50000 N/A

Iptables VS. IPVS TPS與時延

Iptables

  • 靈活,功能強大
  • 在prerouting, postrouting, forward, input, output不同階段都能對包進行操作

IPVS

  • 更好的性能(hash vs. chain)
  • 更多的負載均衡算法
    • - rr, wrr, lc, wlc, ip hash…
  • 連接保持
    • - IPVS service更新期間,保持連接不斷開
  • 預先加載內核模
    • - nf_conntrack_ipv4, ip_vs, ip_vs_rr, ip_vs_wrr, ipvs_sh…
  • # echo 1 > /proc/sys/net/ipv4/vs/conntrack

爲什麼還需要Iptables

因爲我們訪問了一層Service IP!
Node IP -> Service IP( Gateway) -> C

客戶端:( Node IP, Service IP), 期望:( Service IP, Node IP)
但實際,經過IPVS一層轉發,包地址變成了( Node IP, C)

服務端發出:( C, Node IP)  這個包的源/目的地址與客戶端期望的不一樣! 故將被丟棄
因此,需要一次SNAT( masquerade)!!
( Node IP, Service IP) -> ( IPVS director IP, C)
這也是爲什麼IPVS NAT模式要求回程報文必須經過director!


提問:爲什麼Container A -> Cluster IP -> Container B?

IPSet - 把O(N)的iptables規則降爲O(1)

但,不想要太多iptables…
ipset create KUBE-LOOP-BACK hash:ip,port,ip
ipset add KUBE-LOOP-BACK 192.168.1.1,udp:53,192.168.1.1
ipset add KUBE-LOOP-BACK 192.168.1.2,tcp:80,192.168.1.2
iptables -t nat -A POSTROUTING -m set --match-set KUBE-LOOP-BACK dst,dst,src -j MASQUERADEOUTING O(1)

ipset支持“增量”式增/刪/改,而非iptables式全量更新

 

發佈了410 篇原創文章 · 獲贊 1345 · 訪問量 208萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章