kubeedge源碼分析系列之整體架構

kubeedge源碼分析系列之整體架構

本系列的源碼分析是在 commit da92692baa660359bb314d89dfa3a80bffb1d26c 之上進行的。

kubeedge是一個基于kubernetes構建的開放平臺,使能邊緣計算,將容器化應用編排功能擴展到邊緣的節(jié)點和設備,并為云和邊緣之間的網(wǎng)絡,應用部署和元數(shù)據(jù)同步提供基礎架構支持。

本文概述

本文從kubeedge的整體架構切入,首先梳理它包含的組件功能及組件之間的關系,然后分析各組件之間共用的框架和功能,最后分析組件中各模塊之間共用的框架和功能。具體如下:

  1. 組件功能及組件之間的關系
  2. 組件的共用框架和功能
  3. 組件中模塊的共用框架和功能

組件功能及組件之間的關系

kubeedge中的組件及組件關系,先從官方的架構圖說起,具體如下:

kubeedge整體架構圖

從官方的架構圖可以清晰地看到,kubeedge整體分Cloud和Edge兩部分:

  1. Cloud部分 是kubernetes api server與Edge部分的橋梁,負責將kubernetes的指令下發(fā)到Edge,同時將Edge的狀態(tài)和事件同步到的kubernetes api server;
  2. Edge部分 接受并執(zhí)行Cloud部分下發(fā)的指令,管理各種負載,并將Edge部分負載的狀態(tài)和事件同步到Cloud部分;

除了官方架構圖展示的Cloud和Edge部分外,還有橫跨Cloud和Edge的部分,具體如下:

  1. Edgemesh 基于Istio的橫跨Cloud和Edge的服務網(wǎng)格解決方案;
  2. Edgesite 為滿足在邊緣需要完整集群功能的場景,定制的在邊緣搭建既能管理、編排又能運行負責的完整集群解決方案;

組件的共用框架和功能

在源碼層面,kubeedge核心獨立組件包括cloudcore、edgecore、edge_mesh和edge_site,除此之外還有mappers和keadm,具體如下下表:

組件名 組件功能 備注
cloudcore Cloud部分各功能模塊的集合
edgecore Cloud部分各功能模塊的集合
edge_mesh 服務網(wǎng)格解決方案 源碼目錄中缺少makefile文件
edge_site 邊緣獨立集群解決方案
mappers 物聯(lián)網(wǎng)協(xié)議實現(xiàn)包 本源碼分析系列不涉及
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 ,具體如下:

  1. cloudcore代碼入口

    kubeedge/cloud/cloudcore/cloudcore.go

     func main() {
         command := app.NewCloudCoreCommand() //此函數(shù)是對cobra調用的封裝
         ...
     }
    

    進入app.NewCloudCoreCommand()函數(shù)內部,也就是kubeedge/cloud/cloudcore/app/server.go中的NewCloudCoreCommand()函數(shù)中,具體如下:

     func NewCloudCoreCommand() *cobra.Command {
         ...
         cmd := &cobra.Command{
             ...
             Run: func(cmd *cobra.Command, args []string) {
             ... 
             registerModules() //注冊cloudcore中的功能模塊
             // start all modules
             core.Run() //啟動已注冊的cloudcore中的功能模塊
         },
       }
       ...
     }
    

    在NewCloudCoreCommand()函數(shù)中,通過 registerModules()函數(shù)注冊cloudcore中的功能模塊,通過core.Run()函數(shù)啟動已注冊的cloudcore中的功能模塊,至于registerModules()函數(shù)注冊了哪些功能模塊,core.Run()函數(shù)怎么啟動已注冊功能模塊的,詳見“組件中模塊的共用框架和功能”。

注意:kubeedge/cloud/admission/admission.go,kubeedge/cloud/csidriver/csidriver.go兩個入口,目前貌似還沒有用到,暫不分析。

  1. edgecore代碼入口

    kubeedge/edge/cmd/edgecore/edgecore.go

    func main() {
        command := app.NewEdgeCoreCommand()//此函數(shù)是對cobra調用的封裝
        ...
    }
    

進入app.NewEdgeCoreCommand()函數(shù)內部,也就是kubeedge/edge/cmd/edgecore/app/server.go中的NewEdgeCoreCommand()函數(shù)中,具體如下:

    func NewEdgeCoreCommand() *cobra.Command {
        ...
        cmd := &cobra.Command{
            ...
            Run: func(cmd *cobra.Command, args []string) {
            ... 
            registerModules() //注冊cloudcore中的功能模塊
            // start all modules
            core.Run() //啟動已注冊的cloudcore中的功能模塊
        },
      }
      ...
    }
    
在NewEdgeCoreCommand()函數(shù)中,通過 registerModules()函數(shù)注冊edgecore中的功能模塊,通過core.Run()函數(shù)啟動已注冊的edgecore中的功能模塊,至于registerModules()函數(shù)注冊了哪些功能模塊,core.Run()函數(shù)怎么啟動已注冊功能模塊的,詳見“組件中模塊的共用框架和功能”。
  1. edge_mesh代碼入口

    kubeedge/edgemesh/cmd/edgemesh.go

     func main() {
         
         ...
         pkg.Register() //注冊edgemesh的功能模塊
    
         //Start server
         server.StartTCP() //啟動一個tcp服務
     }
    

    從main()函數(shù)中可以看到,edgemesh沒有使用cobra,而是直接注冊功能模塊,然后啟動了一個TCP服務。

  2. 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()函數(shù)中,通過 registerModules()函數(shù)注冊edgesite中的功能模塊,通過core.Run()函數(shù)啟動已注冊的edgecore中的功能模塊,至于registerModules()函數(shù)注冊了哪些功能模塊,core.Run()函數(shù)怎么啟動已注冊功能模塊的,詳見“組件中模塊的共用框架和功能”。

到此,組件(cloudcore、edgecore、edge_mesh和edge_site)層面的源碼共用框架和功能分析就結束了,下面深入分析各組件中功能模塊的共用框架和功能。

組件中模塊的共用框架和功能

kubeedge組件中各個功能模塊之間是通過Beehive來組織和管理的,Beehive是一個基于go-channels的消息框架,但本文的重點不是不是Beehive,所以只會分析kubeedge中用到的Beehive的相關功能。下面來深入cloudcore、edgecore、edge_mesh和edge_site組件中,一起探究組件內部各功能模塊的共用框架。

cloudcore中模塊的共用框架和功能分析

在“組件的共用框架和功能”的“cloudcore代碼入口”部分已經(jīng)分析到cloudcore中功能模塊的注冊和已注冊功能模塊的啟動,本節(jié)就接著往下分析。

  1. cloudcore中功能模塊的注冊

     func registerModules() {
         cloudhub.Register()
         edgecontroller.Register()
         devicecontroller.Register()
     }
    

    從registerModules()函數(shù)中,可以知道cloudcore中有cloudhub、edgecontroller和devicecontroller共3個功能模塊,進入Register()函數(shù)中來探索一下在模塊注冊中具體做了什么:

     func Register() {
         core.Register(&cloudHub{})
     }
    

    在kubeedge/cloud/pkg/cloudhub/cloudhub.go中的Register()函數(shù)只是調用了kubeedge/beehive/pkg/core/module.go中的Register(...)函數(shù),繼續(xù)進入Register(...)函數(shù),會看到:

     ...
     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())
         }
     }
    

    從上面的變量和函數(shù)定義可以清楚地看到,cloudhub模塊注冊最終會將該模塊的結構體放入一個map[string]Module類型的全局變量modules中。

    按照cloudhub模塊注冊的思路分析,edgecontroller和devicecontroller也做了相同的事情,最終把各自的結構體放入一個map[string]Module類型的全局變量modules中。

    cloudhub、edgecontroller和devicecontroller三個功能模塊,之所以能夠采用相同的注冊流程,是因為它們都實現(xiàn)了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接口的具體實現(xiàn)。

  2. 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()函數(shù)中可以知道,該函數(shù)通過StartModules()啟動已經(jīng)注冊的modules,通過GracefulShutdown()將模塊優(yōu)雅的停止,至于如何啟動和停止的,需要進入函數(shù)內容一探究竟:

    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()函數(shù)的定義,可以清楚地知道該函數(shù)首先獲得已經(jīng)注冊的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()函數(shù)與StartModules()函數(shù)的邏輯類似,也是首先獲得已經(jīng)注冊的module,然后通過一個for循環(huán)等待關閉所有的module。

edgecore中模塊的共用框架和功能分析

在“組件的共用框架和功能”的“edgecore代碼入口”部分已經(jīng)分析到edgecore中功能模塊的注冊和已注冊功能模塊的啟動,本節(jié)就接著往下分析。

  1. 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()函數(shù)中,可以知道edgecore中有devicetwin、edged、edgehub、eventbus、edgemesh、metamanager、servicebus、和test共8個功能模塊,還有一個db初始化函數(shù),進入Register()函數(shù)中來探索一下在模塊注冊中具體做了什么:

     // Register register devicetwin
     func Register() {
         dtclient.InitDBTable()
         dt := DeviceTwin{}
         core.Register(&dt)
     }
    

    在kubeedge/edge/pkg/devicetwin/devicetwin.go中的Register()函數(shù)只是調用了kubeedge/beehive/pkg/core/module.go中的Register(...)函數(shù),繼續(xù)進入Register(...)函數(shù),會看到:

         ...
     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())
         }
     }
    

    從上面的變量和函數(shù)定義可以清楚地看到,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個功能模塊,之所以能夠采用相同的注冊流程,是因為它們都實現(xiàn)了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接口的具體實現(xiàn)。

  2. edgecore中功能模塊的啟動

dgecore中功能模塊的啟動與“cloudcore中模塊的共用框架和功能分析”中的“cloudcore中功能模塊的啟動”流程完全相同,大家可以參考改部分。

edgemesh中模塊的共用框架和功能分析

在“組件的共用框架和功能”的“edgemesh代碼入口”部分已經(jīng)分析到edgemesh中功能模塊的注冊和已注冊功能模塊的啟動,本節(jié)就接著往下分析。

  1. edgemesh中功能模塊的注冊

edgemesh中功能模塊的注冊可以參考”edgecore中功能模塊的注冊”,這里就不在贅述。

  1. edgemesh中功能模塊的啟動

    edgemesh目前暫時沒有模塊啟動邏輯。

edgesite中模塊的共用框架和功能分析

在“組件的共用框架和功能”的“edgesite代碼入口”部分已經(jīng)分析到edgemesh中功能模塊的注冊和已注冊功能模塊的啟動,本節(jié)就接著往下分析。

  1. edgesite中功能模塊的注冊

edgesite中功能模塊的注冊請參考”edgecore中功能模塊的注冊”,這里就不在贅述。

  1. edgesite中功能模塊的啟動

    edgesite中功能模塊的啟動請參考”edgecore中功能模塊的啟動”,這里就不在贅述。

本文是“之江實驗室端邊云操作系統(tǒng)團隊” kubeedge源碼分析系列的第一篇,接下來會對各組件的源碼進行系統(tǒng)分析。如果有機會我們團隊也會積極解決kubeedge的issue和實現(xiàn)新的feature。

這是我們“之江實驗室端邊云操作系統(tǒng)團隊”維護的“之江實驗室kubeedge源碼分析群“微信群,歡迎大家的參與?。?!

[圖片上傳失敗...(image-97036-1573916136335)]

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容