1. 程式人生 > 程式設計 >kubeedge原始碼分析系列之整體架構

kubeedge原始碼分析系列之整體架構

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

kubeedge是一個基於kubernetes構建的開放平臺,使能邊緣計算,將容器化應用編排功能擴充套件到邊緣的節點和裝置,併為雲和邊緣之間的網路,應用部署和元資料同步提供基礎架構支援。

本文概述

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

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

元件功能及元件之間的關係

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

kubeedge整體架構圖

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

  1. Cloud部分 是kubernetes api server與Edge部分的橋樑,負責將kubernetes的指令下發到Edge,同時將Edge的狀態和事件同步到的kubernetes api server;
  2. Edge部分 接受並執行Cloud部分下發的指令,管理各種負載,並將Edge部分負載的狀態和事件同步到Cloud部分;

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

  1. Edgemesh 基於Istio的橫跨Cloud和Edge的服務網格解決方案;
  2. 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,具體如下:

  1. 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兩個入口,目前貌似還沒有用到,暫不分析。

  1. 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()函式怎麼啟動已註冊功能模組的,詳見“元件中模組的共用框架和功能”。
複製程式碼
  1. edge_mesh程式碼入口

    kubeedge/edgemesh/cmd/edgemesh.go

     func main() {
     	
     	...
     	pkg.Register() //註冊edgemesh的功能模組
    
     	//Start server
     	server.StartTCP() //啟動一個tcp服務
     }
    複製程式碼

    從main()函式中可以看到,edgemesh沒有使用cobra,而是直接註冊功能模組,然後啟動了一個TCP服務。

  2. 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中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。

  1. 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介面的具體實現。

  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()函式中可以知道,該函式通過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中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。

  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()函式中,可以知道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介面的具體實現。

  2. edgecore中功能模組的啟動

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

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

在“元件的共用框架和功能”的“edgemesh程式碼入口”部分已經分析到edgemesh中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。

  1. edgemesh中功能模組的註冊

edgemesh中功能模組的註冊可以參考”edgecore中功能模組的註冊”,這裡就不在贅述。

  1. edgemesh中功能模組的啟動

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

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

在“元件的共用框架和功能”的“edgesite程式碼入口”部分已經分析到edgemesh中功能模組的註冊和已註冊功能模組的啟動,本節就接著往下分析。

  1. edgesite中功能模組的註冊

edgesite中功能模組的註冊請參考”edgecore中功能模組的註冊”,這裡就不在贅述。

  1. edgesite中功能模組的啟動

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

本文是“之江實驗室端邊雲作業系統團隊” kubeedge原始碼分析系列的第一篇,接下來會對各元件的原始碼進行系統分析。如果有機會我們團隊也會積極解決kubeedge的issue和實現新的feature。

這是我們“之江實驗室端邊雲作業系統團隊”維護的"之江實驗室kubeedge原始碼分析群"微信群,歡迎大家的參與!!!

kubeedge原始碼分析群二維碼入口