Rootless Router(Part: 5): 完結
- Rootless Router(Part: 0): 用戶態DN42節點
- Rootless Router(Part: 1): wggo-vpp
- Rootless Router(Re: 0): VPP Host stack
- Rootless Router(Part: 2): BIRD-vpp
- Rootless Router(Part: 3): EtherGuard
- Rootless Router(Extra):蒐集的Userspace 網路棧
- Rootless Router(Part: 4): 被VPP Host Stack衝康
- Rootless Router(Part: 5): 完結
- Rootless Router(Fin): UML版本上線啦!
- Rootless Router(Afterword): Azure App Service真的很靈
唉,忙了5個月,結果一場空。真的是很難過
本地最終測試
大部分的拼圖都造好了,我又花了一個月把這些拼圖拼再一起
總時間花了5個月的RootlessRouter總算能運作上線了
在本地測試,BGP session起來了,路由有廣播出去,也有收到外面的路由
上線後遇到第一個麻煩,赫然發現CPU占用率居然是100% !
才想起來,VPP為了性能,採用的是輪詢模式,而不是中斷模式。所以會直接佔用一顆CPU 100%。因為本地是多核心,所以沒發現。但是雲端上是一核心,直接卡死
首先我想到的是cpulimit。我限制成1%,用了以後CPU降到剩下10%。但是有很大的問題,就是ping超級不穩定。因為她的細粒度太低了,跑0.1秒,卡0.9秒。所以部分ping值直接跳上900
後來找到這篇,解決了VPP CPU 100%的問題。
但是又發現,怎麼換成BIRD的cpu 卡100%了?
然後又找上海交大的這篇,經過一番修改,總算是壓住CPU使用率了
在他的輪巡迴圈裡面加上sleep,解決100%的問題。
我是usleep(1000),延遲還算勉強可用,idle狀態壓在3%左右
我做的修改: https://github.com/KusakabeSi/vpp/commit/73ee9164f8a7c4c65ced4aa61ab865878b2e5d3a
部屬上線
之後我就開始部屬到azure app service的免費容器裡面
一開始的確正常運作,session建立,路由正確
但是時間一長,bgp session開始中斷。
ping測試,網路一切正常。可是BGP session就是開始出事
要嘛Hold time expired,要嘛Ceased
之前我在本地已經測試過無數次了,我在本地又重新測試。
但是這次不一樣的點是,我放著讓他長時間跑。果然,問題出現了
一開始都正常,能ping通外面,looking glass能查到路由。但是時間拉長以後,BGP session就沒了
之後我又用沒有patch的版本,也就是會占用100% CPU的全性能版本,問題依舊,所以不是我的patch出問題
網路品質一定沒問題,都在我內網測試,docker的區網裡面,應該不太會丟封包。
所以可以推斷,一定是VPP Host stack的問題。
放棄VPP
這個問題,就真的很難診斷了。不知道又要讀多少程式碼,才能修好這個問題。
天知道問題是出在他的TCP狀態機維護,還是session讀寫鎖出錯,還是哪邊有別的問題
VPP Host stack那個複雜程度,我也實在沒有信心可以看完他呀.....
再加上幾天前才被他的 Host Stack坑到,對VPP Host stack已經有點沒信心了
讓我決定放棄的最後一根稻草,是這3%的CPU占用。
就算沒有任何活動,還是要不斷占用3%的CPU
而且這已經是我sleep加到極限,性能已經很差了。usleep(5000)就不太能看了
雖然VPP就是主打輪巡代替中斷,取得更好的性能。但是和我的應用場景就不合了
idle狀態下的CPU高占用,說不定哪天被判定挖礦
這一點讓我決定要改變做法了,不再使用VPP了
有那麼多的網路虛擬化方案,最當初,我為什麼這麼堅持要選擇VPP呢?
因為不同的虛擬化方案基於不同的技術。
linux上主流的是network ns / tun tap / veth / ptrace / ld_preload 。
但是除了ptrace / ld_preload,其他的都要Root! 而我想做的是 Rooeless Router
一切處理都在用戶態,不借助kernel的幫忙
最好可以包成容器,docker run,一台BGP Router就起來了。
而且不用 --privileged ,就是普通的docker container
而ptrace預設關閉,那麼我只剩ld_preload這個選項了
我到快弄完的時候才知道,kernel 4.8以後,docker裡面ptrace就可以用了。
但是因為沉沒成本效應,所以想說VPP弄到底吧
最後的結果...如你所見,翻車了。
在最後紀念一下,為了這個RootlessRouter計畫,我所造的拼圖片們吧
- https://github.com/KusakabeSi/EtherGuard-VPN
- https://github.com/KusakabeSi/wireguard-go-vpp
- https://github.com/KusakabeSi/DN42-AutoPeer-vpp
- https://github.com/KusakabeSi/bird-vpp-route-syncer
- https://github.com/KusakabeSi/bird-lg-go
- https://github.com/KusakabeSi/vpp
- https://github.com/KusakabeSi/BIRD-vpp
- https://github.com/KusakabeSi/RootlessRouterDocker
- https://github.com/KusakabeSi/RootlessRouter
- https://github.com/KusakabeSi/RRstate
結論
目前我UML是我心目中的候選人,或是gvisor。
這個userspace network stack必須要有3個功能。
- 提供 bind() listen() 之類的API,維護tcp state machine,做L3-L4的轉換,讓BIRD接入
- 動態新增虛擬網路裝置
- 提供路由表功能。能寫入CIDR/device對應表,能正確把風包發項正確的裝置
心疼你,抱抱~
回覆刪除抱抱~
刪除