kubeedge源碼分析系列之整體架構
本系列的源碼分析是在 commit da92692baa660359bb314d89dfa3a80bffb1d26c 之上進行的矾湃。
kubeedge是一個基于kubernetes構建的開放平臺,使能邊緣計算慷吊,將容器化應用編排功能擴展到邊緣的節(jié)點和設備媚媒,并為云和邊緣之間的網絡榆纽,應用部署和元數據同步提供基礎架構支持蒿叠。
本文概述
本文從kubeedge的整體架構切入善茎,首先梳理它包含的組件功能及組件之間的關系券册,然后分析各組件之間共用的框架和功能,最后分析組件中各模塊之間共用的框架和功能垂涯。具體如下:
- 組件功能及組件之間的關系
- 組件的共用框架和功能
- 組件中模塊的共用框架和功能
組件功能及組件之間的關系
kubeedge中的組件及組件關系烁焙,先從官方的架構圖說起,具體如下:
從官方的架構圖可以清晰地看到耕赘,kubeedge整體分Cloud和Edge兩部分:
- Cloud部分 是kubernetes api server與Edge部分的橋梁骄蝇,負責將kubernetes的指令下發(fā)到Edge,同時將Edge的狀態(tài)和事件同步到的kubernetes api server操骡;
- Edge部分 接受并執(zhí)行Cloud部分下發(fā)的指令九火,管理各種負載,并將Edge部分負載的狀態(tài)和事件同步到Cloud部分册招;
除了官方架構圖展示的Cloud和Edge部分外岔激,還有橫跨Cloud和Edge的部分,具體如下:
- Edgemesh 基于Istio的橫跨Cloud和Edge的服務網格解決方案是掰;
- Edgesite 為滿足在邊緣需要完整集群功能的場景虑鼎,定制的在邊緣搭建既能管理、編排又能運行負責的完整集群解決方案键痛;
組件的共用框架和功能
在源碼層面炫彩,kubeedge核心獨立組件包括cloudcore、edgecore絮短、edge_mesh和edge_site江兢,除此之外還有mappers和keadm,具體如下下表:
組件名 | 組件功能 | 備注 |
---|---|---|
cloudcore | Cloud部分各功能模塊的集合 | |
edgecore | Cloud部分各功能模塊的集合 | |
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, args []string) { ... registerModules() //注冊cloudcore中的功能模塊 // start all modules core.Run() //啟動已注冊的cloudcore中的功能模塊 }, } ... }
在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中功能模塊的注冊和已注冊功能模塊的啟動仗扬,本節(jié)就接著往下分析。
-
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(...)函數诅蝶,繼續(xù)進入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()將模塊優(yōu)雅的停止趴捅,至于如何啟動和停止的垫毙,需要進入函數內容一探究竟:
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循環(huán)啟動所有的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循環(huán)等待關閉所有的module膀藐。
edgecore中模塊的共用框架和功能分析
在“組件的共用框架和功能”的“edgecore代碼入口”部分已經分析到edgecore中功能模塊的注冊和已注冊功能模塊的啟動屠阻,本節(jié)就接著往下分析。
-
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(...)函數丁眼,繼續(xù)進入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()) } }
從上面的變量和函數定義可以清楚地看到昭殉,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中功能模塊的注冊和已注冊功能模塊的啟動遵岩,本節(jié)就接著往下分析。
- edgemesh中功能模塊的注冊
edgemesh中功能模塊的注冊可以參考”edgecore中功能模塊的注冊”巡通,這里就不在贅述尘执。
-
edgemesh中功能模塊的啟動
edgemesh目前暫時沒有模塊啟動邏輯。
edgesite中模塊的共用框架和功能分析
在“組件的共用框架和功能”的“edgesite代碼入口”部分已經分析到edgemesh中功能模塊的注冊和已注冊功能模塊的啟動宴凉,本節(jié)就接著往下分析誊锭。
- edgesite中功能模塊的注冊
edgesite中功能模塊的注冊請參考”edgecore中功能模塊的注冊”,這里就不在贅述弥锄。
-
edgesite中功能模塊的啟動
edgesite中功能模塊的啟動請參考”edgecore中功能模塊的啟動”丧靡,這里就不在贅述。
本文是“之江實驗室端邊云操作系統(tǒng)團隊” kubeedge源碼分析系列的第一篇叉讥,接下來會對各組件的源碼進行系統(tǒng)分析窘行。如果有機會我們團隊也會積極解決kubeedge的issue和實現新的feature。
這是我們“之江實驗室端邊云操作系統(tǒng)團隊”維護的“之江實驗室kubeedge源碼分析群“微信群图仓,歡迎大家的參與!5啤救崔!
[圖片上傳失敗...(image-97036-1573916136335)]