kubeedge原始碼分析系列之整體架構
本系列的原始碼分析是在 commit da92692baa660359bb314d89dfa3a80bffb1d26c 之上進行的。
kubeedge是一個基於kubernetes構建的開放平臺,使能邊緣計算,將容器化應用編排功能擴充套件到邊緣的節點和裝置,併為雲和邊緣之間的網路,應用部署和元資料同步提供基礎架構支援。
本文概述
本文從kubeedge的整體架構切入,首先梳理它包含的元件功能及元件之間的關係,然後分析各元件之間共用的框架和功能,最後分析元件中各模組之間共用的框架和功能。具體如下:
- 元件功能及元件之間的關係
- 元件的共用框架和功能
- 元件中模組的共用框架和功能
元件功能及元件之間的關係
kubeedge中的元件及元件關係,先從官方的架構圖說起,具體如下:
從官方的架構圖可以清晰地看到,kubeedge整體分Cloud和Edge兩部分:
- Cloud部分 是kubernetes api server與Edge部分的橋樑,負責將kubernetes的指令下發到Edge,同時將Edge的狀態和事件同步到的kubernetes api server;
- Edge部分 接受並執行Cloud部分下發的指令,管理各種負載,並將Edge部分負載的狀態和事件同步到Cloud部分;
除了官方架構圖展示的Cloud和Edge部分外,還有橫跨Cloud和Edge的部分,具體如下:
- Edgemesh 基於Istio的橫跨Cloud和Edge的服務網格解決方案;
- Edgesite 為滿足在邊緣需要完整叢集功能的場景,定製的在邊緣搭建既能管理、編排又能執行負載的完整叢集解決方案;
元件的共用框架和功能
在原始碼層面,kubeedge核心獨立元件包括cloudcore、edgecore、edge_mesh和edge_site,除此之外還有mappers和keadm,具體如下下表:
元件名 | 元件功能 | 備註 |
---|---|---|
cloudcore | Cloud部分各功能模組的集合 | |
edgecore | Edge部分各功能模組的集合 | |
edge_mesh | 服務網格解決方案 | 原始碼目錄中缺少makefile檔案 |
edge_site | 邊緣獨立叢集解決方案 | |
mappers | 物聯網協議實現包 | 本原始碼分析系列不涉及 |
keadm | kubeedge的一鍵部署工具 | 目前支援unbuntu,本原始碼分析系列不涉及 |
以上元件中的cloudcore、edgecore、edge_mesh和edge_site具有類似的程式碼結構,具體如下表:
元件名 | 程式碼目錄 | 元件啟動入口 |
---|---|---|
cloudcore | kubeedge/cloud | kubeedge/cloud/cloudcore/cloudcore.go,kubeedge/cloud/admission/admission.go,kubeedge/cloud/csidriver/csidriver.go |
edgecore | kubeedge/edge | kubeedge/edge/cmd/edgecore/edgecore.go |
edge_mesh | kubeedge/edgemesh | kubeedge/edgemesh/cmd/edgemesh.go |
edge_site | kubeedge/edgesite | kubeedge/edgesite/cmd/edgesite.go |
在cloudcore、edgecore、edge_mesh和edge_site元件的原始碼中都使用了命令列框架cobra,具體如下:
-
cloudcore程式碼入口
kubeedge/cloud/cloudcore/cloudcore.go
func main() { command := app.NewCloudCoreCommand() //此函式是對cobra呼叫的封裝 ... } 複製程式碼
進入app.NewCloudCoreCommand()函式內部,也就是kubeedge/cloud/cloudcore/app/server.go中的NewCloudCoreCommand()函式中,具體如下:
func NewCloudCoreCommand() *cobra.Command { ... cmd := &cobra.Command{ ... Run: func(cmd *cobra.Command,args []string) { ... registerModules() //註冊cloudcore中的功能模組 // start all modules core.Run() //啟動已註冊的cloudcore中的功能模組 },} ... } 複製程式碼
在NewCloudCoreCommand()函式中,通過 registerModules()函式註冊cloudcore中的功能模組,通過core.Run()函式啟動已註冊的cloudcore中的功能模組,至於registerModules()函式註冊了哪些功能模組,core.Run()函式怎麼啟動已註冊功能模組的,詳見“元件中模組的共用框架和功能”。
注意:kubeedge/cloud/admission/admission.go,kubeedge/cloud/csidriver/csidriver.go兩個入口,目前貌似還沒有用到,暫不分析。
-
edgecore程式碼入口
kubeedge/edge/cmd/edgecore/edgecore.go
func main() { command := app.NewEdgeCoreCommand()//此函式是對cobra呼叫的封裝 ... } 複製程式碼
進入app.NewEdgeCoreCommand()函式內部,也就是kubeedge/edge/cmd/edgecore/app/server.go中的NewEdgeCoreCommand()函式中,具體如下:
func NewEdgeCoreCommand() *cobra.Command {
...
cmd := &cobra.Command{
...
Run: func(cmd *cobra.Command,args []string) {
...
registerModules() //註冊cloudcore中的功能模組
// start all modules
core.Run() //啟動已註冊的cloudcore中的功能模組
},}
...
}
在NewEdgeCoreCommand()函式中,通過 registerModules()函式註冊edgecore中的功能模組,通過core.Run()函式啟動已註冊的edgecore中的功能模組,至於registerModules()函式註冊了哪些功能模組,core.Run()函式怎麼啟動已註冊功能模組的,詳見“元件中模組的共用框架和功能”。
複製程式碼
-
edge_mesh程式碼入口
kubeedge/edgemesh/cmd/edgemesh.go
func main() { ... pkg.Register() //註冊edgemesh的功能模組 //Start server server.StartTCP() //啟動一個tcp服務 } 複製程式碼
從main()函式中可以看到,edgemesh沒有使用cobra,而是直接註冊功能模組,然後啟動了一個TCP服務。
-
edge_site程式碼入口
kubeedge/edgesite/cmd/edgesite.go
func NewEdgeSiteCommand() *cobra.Command { ... cmd := &cobra.Command{ ... Run: func(cmd *cobra.Command,} ... } 複製程式碼
在NewEdgeSiteCommand()函式中,通過 registerModules()函式註冊edgesite中的功能模組,通過core.Run()函式啟動已註冊的edgecore中的功能模組,至於registerModules()函式註冊了哪些功能模組,core.Run()函式怎麼啟動已註冊功能模組的,詳見“元件中模組的共用框架和功能”。
到此,元件(cloudcore、edgecore、edge_mesh和edge_site)層面的原始碼共用框架和功能分析就結束了,下面深入分析各元件中功能模組的共用框架和功能。
元件中模組的共用框架和功能
kubeedge元件中各個功能模組之間是通過Beehive來組織和管理的,Beehive是一個基於go-channels的訊息框架,但本文的重點不是不是Beehive,所以只會分析kubeedge中用到的Beehive的相關功能。下面來深入cloudcore、edgecore、edge_mesh和edge_site元件中,一起探究元件內部各功能模組的共用框架。
cloudcore中模組的共用框架和功能分析
在“元件的共用框架和功能”的“cloudcore程式碼入口”部分已經分析到cloudcore中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。
-
cloudcore中功能模組的註冊
func registerModules() { cloudhub.Register() edgecontroller.Register() devicecontroller.Register() } 複製程式碼
從registerModules()函式中,可以知道cloudcore中有cloudhub、edgecontroller和devicecontroller共3個功能模組,進入Register()函式中來探索一下在模組註冊中具體做了什麼:
func Register() { core.Register(&cloudHub{}) } 複製程式碼
在kubeedge/cloud/pkg/cloudhub/cloudhub.go中的Register()函式只是呼叫了kubeedge/beehive/pkg/core/module.go中的Register(...)函式,繼續進入Register(...)函式,會看到:
... var ( // Modules map modules map[string]Module disabledModules map[string]Module ) ... func Register(m Module) { if isModuleEnabled(m.Name()) { modules[m.Name()] = m klog.Infof("Module %v registered",m.Name()) } else { disabledModules[m.Name()] = m klog.Warningf("Module %v is not register,please check modules.yaml",m.Name()) } } 複製程式碼
從上面的變數和函式定義可以清楚地看到,cloudhub模組註冊最終會將該模組的結構體放入一個map[string]Module型別的全域性變數modules中。
按照cloudhub模組註冊的思路分析,edgecontroller和devicecontroller也做了相同的事情,最終把各自的結構體放入一個map[string]Module型別的全域性變數modules中。
cloudhub、edgecontroller和devicecontroller三個功能模組,之所以能夠採用相同的註冊流程,是因為它們都實現了kubeedge/beehive/pkg/core/module.go中的Module介面,Module介面具體內容如下:
type Module interface { Name() string Group() string Start(c *context.Context) Cleanup() } 複製程式碼
可以分別在kubeedge/cloud/pkg/cloudhub/cloudhub.go,kubeedge/cloud/pkg/controller/controller.go,kubeedge/cloud/pkg/devicecontroller/module.go中找到cloudhub、edgecontroller和devicecontroller三個功能模組對Module介面的具體實現。
-
cloudcore中功能模組的啟動
kubeedge/beehive/pkg/core/core.go
//Run starts the modules and in the end does module cleanup func Run() { //Address the module registration and start the core StartModules() // monitor system signal and shutdown gracefully GracefulShutdown() } 複製程式碼
從上面的Run()函式中可以知道,該函式通過StartModules()啟動已經註冊的modules,通過GracefulShutdown()將模組優雅的停止,至於如何啟動和停止的,需要進入函式內容一探究竟:
kubeedge/beehive/pkg/core/core.go
// StartModules starts modules that are registered func StartModules() { coreContext := context.GetContext(context.MsgCtxTypeChannel) modules := GetModules() for name,module := range modules { //Init the module coreContext.AddModule(name) //Assemble typeChannels for sendToGroup coreContext.AddModuleGroup(name,module.Group()) go module.Start(coreContext) klog.Infof("Starting module %v",name) } } 複製程式碼
從上面 StartModules()函式的定義,可以清楚地知道該函式首先獲得已經註冊的module,然後通過一個for迴圈啟動所有的module。
kubeedge/beehive/pkg/core/core.go
// GracefulShutdown is if it gets the special signals it does modules cleanup func GracefulShutdown() { c := make(chan os.Signal) signal.Notify(c,syscall.SIGINT,syscall.SIGHUP,syscall.SIGTERM,syscall.SIGQUIT,syscall.SIGILL,syscall.SIGTRAP,syscall.SIGABRT) select { case s := <-c: klog.Infof("Get os signal %v",s.String()) //Cleanup each modules modules := GetModules() for name,module := range modules { klog.Infof("Cleanup module %v",name) module.Cleanup() } } } 複製程式碼
GracefulShutdown()函式與StartModules()函式的邏輯類似,也是首先獲得已經註冊的module,然後通過一個for迴圈等待關閉所有的module。
edgecore中模組的共用框架和功能分析
在“元件的共用框架和功能”的“edgecore程式碼入口”部分已經分析到edgecore中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。
-
edgecore中功能模組的註冊
// registerModules register all the modules started in edgecore func registerModules() { devicetwin.Register() edged.Register() edgehub.Register() eventbus.Register() edgemesh.Register() metamanager.Register() servicebus.Register() test.Register() dbm.InitDBManager() } 複製程式碼
從registerModules()函式中,可以知道edgecore中有devicetwin、edged、edgehub、eventbus、edgemesh、metamanager、servicebus、和test共8個功能模組,還有一個db初始化函式,進入Register()函式中來探索一下在模組註冊中具體做了什麼:
// Register register devicetwin func Register() { dtclient.InitDBTable() dt := DeviceTwin{} core.Register(&dt) } 複製程式碼
在kubeedge/edge/pkg/devicetwin/devicetwin.go中的Register()函式只是呼叫了kubeedge/beehive/pkg/core/module.go中的Register(...)函式,繼續進入Register(...)函式,會看到:
... var ( // Modules map modules map[string]Module disabledModules map[string]Module ) ... func Register(m Module) { if isModuleEnabled(m.Name()) { modules[m.Name()] = m klog.Infof("Module %v registered",m.Name()) } } 複製程式碼
從上面的變數和函式定義可以清楚地看到,devicetwin模組註冊最終會將該模組的結構體放入一個map[string]Module型別的全域性變數modules中。
按照cloudhub模組註冊的思路分析,edged、edgehub、eventbus、edgemesh、metamanager、servicebus、和test也做了相同的事情,最終把各自的結構體放入一個map[string]Module型別的全域性變數modules中。
devicetwin、edged、edgehub、eventbus、edgemesh、metamanager、servicebus、和test共8個功能模組,之所以能夠採用相同的註冊流程,是因為它們都實現了kubeedge/beehive/pkg/core/module.go中的Module介面,Module介面具體內容如下:
type Module interface { Name() string Group() string Start(c *context.Context) Cleanup() } 複製程式碼
可以分別在kubeedge/edge/pkg/devicetwin/devicetwin.go,kubeedge/edge/pkg/edged/edged.go,kubeedge/edge/pkg/edgehub/module.go,kubeedge/edge/pkg/eventbus/event_bus.go,kubeedge/edge/pkg/edgemesh/module.go,kubeedge/edge/pkg/metamanager/module.go,kubeedge/edge/pkg/servicebush/servicebus.go,kubeedge/edge/pkg/test/test.go中找到devicetwin、edged、edgehub、eventbus、edgemesh、metamanager、servicebus、和test共8個功能模組對Module介面的具體實現。
-
edgecore中功能模組的啟動
dgecore中功能模組的啟動與“cloudcore中模組的共用框架和功能分析”中的“cloudcore中功能模組的啟動”流程完全相同,大家可以參考改部分。
edgemesh中模組的共用框架和功能分析
在“元件的共用框架和功能”的“edgemesh程式碼入口”部分已經分析到edgemesh中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。
- edgemesh中功能模組的註冊
edgemesh中功能模組的註冊可以參考”edgecore中功能模組的註冊”,這裡就不在贅述。
-
edgemesh中功能模組的啟動
edgemesh目前暫時沒有模組啟動邏輯。
edgesite中模組的共用框架和功能分析
在“元件的共用框架和功能”的“edgesite程式碼入口”部分已經分析到edgemesh中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。
- edgesite中功能模組的註冊
edgesite中功能模組的註冊請參考”edgecore中功能模組的註冊”,這裡就不在贅述。
-
edgesite中功能模組的啟動
edgesite中功能模組的啟動請參考”edgecore中功能模組的啟動”,這裡就不在贅述。
本文是“之江實驗室端邊雲作業系統團隊” kubeedge原始碼分析系列的第一篇,接下來會對各元件的原始碼進行系統分析。如果有機會我們團隊也會積極解決kubeedge的issue和實現新的feature。
這是我們“之江實驗室端邊雲作業系統團隊”維護的"之江實驗室kubeedge原始碼分析群"微信群,歡迎大家的參與!!!