分享一個用 go 開發的一款跨雲 vpc 通訊專案
cframe 介紹
cframe 是我個人利用業務時間開發的跨雲 vpc 通訊專案,如果要用一句話總結,那可以理解為: 使用 cframe 能夠讓任意不衝突的網路進行互聯互通。
下面展示的是使用 cframe 將六個不衝突的網路進行打通,只要我身處任何一個網路當中,都可以通過內網 IP 訪問到其他網路的主機。
➜ ~ cfctl edge list
edge list:
Name Listener CIDR
-----------------------------------------------------------
1 edge-gcl-tc x.x.x.x:58423 10.0.8.6
2 edge-sz-branch x.x.x.x:48423 10.60.6.0/24
3 edge-sz-home x.x.x.x:58424 192.168.31.0/24
4 edge-us-aws x.x.x.x:58423 172.31.39.169
5 edge-aliyun-hk x.x.x.x:58423 172.17.8.10
6 edge-aliyun-sz x.x.x.x:58423 172.18.0.0/16
關於 cframe 的程式碼可以檢視cframe 的專案主頁。目前整個系統的程式碼也非常少,只有兩千多行程式碼,只需要半天時間即可閱讀完。
本文首先介紹 cframe 以及 cframe 的整體框架,然後針對整體框架當中的每個角色進行逐步細化,並從如何實現的,為什麼這樣實現進行闡述。
整體框架
正如上圖所示,cframe 包含三個角色以及一個開源元件(etcd)
- cfctl - 一個 cli 工具,給使用者進行系統管理的
- controller - 全域性控制器
- edge - 邊緣節點
- etcd - 儲存系統
首先是 cfctl 工具,用來管理namespace
,edge
以及路由,在最初的版本當中,並沒有考慮設計這個工具,當時設計的是一個apiserver
的服務,通過 http 介面的方式管理叢集,甚至還希望能夠在此之上做一個控制皮膚。但是後面版本當中並沒有繼續採用這種方案,主要原因是: apiserver 的方式固然可以讓使用者更加方便,但是畢竟不是我所擅長的領域,目前階段不願意過多的投入,倒不如集中力量把最核心的功能做好,當然如果有人願意參與進來的話我也是非常歡迎的。
其次是 controller,controller 是為了方便給使用者一個入口的,試想一下,如果沒有 controller,那麼新增 edge 節點時,就需要在每個 edge 節點上加網路配置,一方面容易出錯,另外一方面需要對網路比較熟悉,設計了 controller 之後,controller 就是一個統一的入口,與所有 edge 互動,下發變更,edge 程式自動執行變更操作。
接下來是 edge 節點,edge 節點的功能只有一個路由轉發。每個 edge 節點最初只設計包含一個 VPC 網路,也就是如果有三個 edge 節點,那麼整個系統就只有三個網路,但是後來發現,像部署在公有云上的 k8s 叢集,VPC 有一個網路,service 有一個網路,pod 還有一個網路,那麼也就是說一個 edge 下面掛了三個網路,因此除了 edge 節點自身的網路之外,還設計了全域性路由功能,在 controller 上新增路由之後,這個 edge 的就會新增一個網路,其他 edge 的發往這個網路的資料就會被該 edge 包接收,詳細設計在後續章節會有討論。
最後是 etcd,最初的版本也沒有考慮使用儲存系統,資料都儲存在記憶體當中,但是會存在多節點資料不一致的問題,而且還需要變更配置,為了簡化互動過程,最後索性用了 etcd。
瞭解了整體框架之後,那麼接下來會實現細節進行詳細闡述。
租戶隔離
租戶隔離 cframe 採用的是 namespace 的概念,每個 namespace 下的 edge,路由不會相互影響,從而實現隔離。正是因為設計了 namespace,所以在 cfctl 當中,每個命令基本上都需要帶--ns
的引數指定 namespace 名稱。
最初的設計是按使用者進行隔離,但是詳細考慮了下,需要做一個使用者系統,顯然這個不是我目前所希望進行的,這裡的 namespace 應該和程式語言當中的 namespace 的概念和作用類似。
當然現在的設計也有問題,不允許不同的使用者有相同的 namespace,但是針對開源專案而言我覺得這個是可以接受的,如果是打磨成一款產品,這裡可能還需要琢磨下。
etcd 儲存設計
在 etcd 當中主要儲存以下三種資訊:
- edge 節點的資訊
- 路由資訊
- namespace 資訊
其目錄設計如下:
/edges/$namespace/$edgename
/routes/$namespace/$routename
/namespaces/$namespace_name
除了對上述 key 進行增刪查之外,還需要實時 watch /edges/*
和/routes/*
的變化,當發生變更時,及時下發到所有執行中的 edge 節點當中,使配置生效。
controller 和 edge 的設計
controller 和 edge 是最核心的部分,最核心的地方我希望保持最簡單,只做最核心的一件事,controller 和 edge 無疑保持了我這樣的想法。
controller 只做路由下發,edge 只做路由,兩者配合,前者給菜譜,後者做菜。
controller
controller 的工作非常的存粹,負責與客戶端保持長連線,並在 etcd 的/edges/*
和/routes/*
兩個目錄發生變更時,通過長連線通知 edge 節點。
edge
edge 則相對要多一點設計,edge 維護與 controller 的連線,以及三種路由關係,這三種路由分別是:
- VPC 路由,目的是讓本 VPC 當中其他雲伺服器的流量發往 edge 所在的例項。
- 系統靜態路由,目的是讓在本機流轉的資料包能夠被 edge 應用程式所劫持
- 程式內部維護的路由,目的是知道下一跳 edge 的公網 IP 和埠
VPC 路由有過一個坎坷的經歷,最初是設計了 VPC 路由,後面又移除,現在還在考慮是否需要加入。
VPC 路由是可以由運維人員在公有云控制皮膚上配置的,這樣子就不需要 VPC 路由,但是又會稍顯麻煩,加入 VPC 路由的話,則需要新增公有云的 accesstoken 資訊,這又是一個比較危險的操作,最終擱置。
controller 與 edge 互動
controller 與 edge 之間的互動方式是 tcp 長連線,在以下幾個時機會觸發配置更新:
- 剛建立連線時,controller 會把當前所有 edge 節點以及路由資訊返回給 edge
- 當 etcd 當中儲存的 edge,路由資訊變更時,會主動推響應的命令以及資料給 edge 節點
- 當 edge 節點被刪除時,會給刪除的 edge 節點傳送 exit 指令。
除此之外 edge 會定時上報一些資料給 controller,當然這部分資料目前還沒用到,也沒有儲存,但是以後如果需要新增的話彼時 controller 將不會那麼存粹。
路由設計
為了實現一個 vpc 當中存在多個網路的問題,設計了路由模組,允許自定義路由。
在路由模組出現之前,只有 edge 模組,edge 模組關聯一個 cidr,這個通常是 VPC 的地址段,只有一個,但是後面為了應付容器,k8s 元件構建的網路,因此設計了自定義路由模組,允許往該 edge 節點下掛多個子網。
在上圖中,三個 edge 節點下分別有其他子網,這一功能是通過自定義路由模組來實現的。
當前不足之處
整個 cframe 目前也僅僅只是一個可用的版本,在資料安全,鏈路監控,安全性檢查方面都沒有做太多的考慮,當前 cframe 還有很多需要打磨的地方,程式碼也還有很多需要不斷優化的地方,也還有許多場景需要測試驗證。
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 開源專案|Go 開發的一款分散式唯一 ID 生成系統Go分散式
- 我用go-zero開發了第一個線上專案Go
- 兩個專案用訊息佇列通訊佇列
- 用JAVA寫一個阿里雲VPC Open API呼叫程式Java阿里API
- 小程式·雲開發 專案開發經驗分享
- 什麼是阿里雲vpc專用網路?阿里
- 用node開發一個生成react專案的cli工具React
- 用原生Go寫一個自己的部落格-搭建專案(一)Go
- 一個使用Go語言和現代Web技術構建跨平臺桌面應用程式開源專案GoWeb
- 專案經理跨部門溝通的幾個方法
- 如何用 Electron + WebRTC 開發一個跨平臺的視訊會議應用Web
- 落地Azure CosmosDb的一個專案分享
- Clusternet:一款開源的跨雲多叢集雲原生管控利器!
- Android技術分享| 視訊通話開發流程(一)Android
- 【譯】Go 專案開發裡最常犯的 10 個錯誤Go
- Vue+ Electron 開發的一個跨三端的應用(Taro開發多端應用)Vue
- ?用 Laravel 開發的一個輕鬆的 Markdown 文件編輯專案Laravel
- 用go設計開發一個自己的輕量級登入庫/框架吧(專案維護篇)Go框架
- 開發參考:介紹一款多專案java開發平臺Java
- Java開源協同辦公開發平臺:做一款辦公專用的雲筆記Java筆記
- 世鏈財經|區塊鏈專案開發指南,如何開發一款區塊鏈專案區塊鏈
- Session:一款不需要電話號碼的開源通訊應用Session
- 分享個 golang 開源小專案Golang
- 分享一個最最基本實用的開發流程
- 分享一款免費體驗的快速開發框架,可以學習用!框架
- 分享一個我的 Django 部落格專案Django
- 寫給go開發者的gRPC教程-通訊模式GoRPC模式
- Container 一款為 Go 開發的依賴注入容器AIGo依賴注入
- vue+cordova專案打包實現跨平臺開發(一)Vue
- 用 Go 快速開發一個 RESTful API 服務GoRESTAPI
- 雲開發實戰分享|一天搭建一個社群
- 2010.03.16專題:一個開發人員的專案煩惱
- 從專案的一個 panic 說起:Go 中 Sync 包的分析應用Go
- 開源專案管理軟體有哪些?分享7個實用開源專案管理軟體專案管理
- 分享一個「實時三維人臉重建」的開源專案
- 騰訊雲Go開發工程師(深圳)Go工程師
- Laravel 中使用 swoole 專案實戰開發案例一 (建立 swoole 和前端通訊)Laravel前端
- 肖威洞察 | 2.5 個人如何開發一款跨終端的產品?[Ruby Tuesday 的分享] · 簡單心理技術團隊...