天天看點

他們居然用這種方式實作了Kubernetes與Dubbo互通!

一.案例背景

在容器雲項目剛剛開始的時候,發現了這樣一個問題:當一個應用遷移到 k8s 叢集上之後,叢集外部的子系統通過 Dubbo 方式調用它,直接報錯,無法連接配接。檢查 SOA 的 Zookeeper(在叢集之外)發現,應用注冊到 Zookeeper 裡的 IP 是容器的 IP!容器的 IP 對 k8s 叢集外不可見,必然連不通。

二.案例分析

為什麼容器注冊到 SOA 中的會是容器的 IP?這在當時我們有些不解,要知道容器發出的資料包出叢集時是要做 SNAT 轉換成主控端的 IP 的,是以按說在 SOA 注冊中心看到的應該是主控端的 IP 才對。經了解才知道,SOA 服務注冊采取的是“用戶端發現”機制,它并不是站在 SOA 注冊中心一端看向它發注冊請求的機器來自于哪個 IP,而是發注冊請求的機器收集自己的本地網卡 IP,然後把這個 IP 報送給注冊中心,現在應用是跑在容器裡的,它收集到的自然是容器内的本地網卡 IP,也就是容器的 IP。

衆所周知,針對叢集外主機想通路叢集内的應用,k8s 隻提供一種形式:暴露一個 nodeport 類型的服務(使用主控端 IP + 端口),映射轉發到容器中(通過一系列 iptables 規則實作)。可現在叢集外主機偏偏要用容器 IP 去找應用,無疑給我們出了一個大難題。

k8s 的各種網絡元件,Flannel、Calico、Weave等,解決了跨主機間容器直接使用自身 IP 進行通信的問題,遺憾的是它們的作用範圍僅限于叢集内部主控端。仔細研究他們的工作原理,不難發現有幾個共同點:

1、容器網絡模式使用網橋(Bridge)模式。

2、負責容器啟動時的 IP 位址配置設定,每台主控端上運作的容器都屬于同一個網段,不同主控端上的容器網段必不相同,了解整個叢集内的容器網段與主控端對應關系。

和任何一個容器 IP 通信時,根據其網段查找,資料包轉發到對應主控端(差別僅在于有的通過打 VXLAN 隧道方式轉發,如 Flannel,有的使用三層路由方式轉發,如 Calico),然後通過主控端内的網橋到達容器内部。

這些元件的工作原理給了我們很大啟發,不管主機位于何處,要想直接和容器 IP 通信,就得了解叢集内容器網段與主控端對應關系,沿用此思路我們想到一個辦法:向叢集外釋出到達各主控端容器網段的路由。

三.具體實施

我們使用 Flannel 作為 k8s 網絡元件,Flannel 的特點是每個主控端上的容器網段是固定的,部署完不會再變,那我們隻需要在主控端的網關裝置上添加靜态路由就好。

假設叢集有兩個節點:

節點 1

主機IP:10.132.2.22

netmask:255.255.255.0

Gateway:10.132.2.254

容器網段:10.131.10.0/24

節點 2

主機IP:10.132.2.23

netmask:255.255.255.0

Gateway:10.132.2.254

容器網段:10.131.73.0/24

那麼我們就在網關裝置 10.132.2.254 上添加下列路由:

ip route 10.131.101.0/24 10.132.2.22

ip route 10.131.73.0/24 10.132.2.23

如果你的網絡中運作着路由協定(OSPF、EIGRP、IS-IS…),把上述靜态路由重釋出(Route Redistribution)到路由協定中即可,沒有,就隻能一跳一跳添加靜态路由了。

邏輯拓撲大緻如下:

他們居然用這種方式實作了Kubernetes與Dubbo互通!

細心的讀者可能會問,前面說到容器資料包出叢集的時候要做 SNAT 的,那外部通路容器 IP,如果回包出叢集時 SNAT 成主控端 IP,那 TCP 三次握手不就無法建立了麼,怎麼能通呢?經抓包測試,k8s 隻有在容器主動發起連接配接叢集外的時候才做 SNAT,回包不做轉換。

這樣我們就将容器網段“透”到了叢集之外,實作容器網段在機房内全網可達。

溫馨提示:叢集的容器網段範圍在叢集搭建前就要統一規劃好,不能和機房任何現有網段沖突。

四.總結

此法簡單有效地實作了叢集内外 Dubbo 方式互相調用,雖然它還不夠優雅,每增加一個計算節點就要增加一條靜态路由,如果叢集節點數量比較多,維護就比較麻煩,但它實實在在的解決了我們的問題,對業務系統遷移容器雲工作具有重大意義。

未來随着叢集規模加大,我們将考慮采用 Calico 網絡元件,Calico 是在每個主控端上運作一個虛拟路由器(VR),它們之間跑 BGP 協定,發現并公告自己之上的容器網段,隻要主控端的網關裝置上支援 BGP,也參與其中,就可學到容器網段路由,釋出到全網,無需人工幹預。此外,我們還會考慮引入 SDN 技術與容器網絡進行對接的可行性,敬請期待!