本系列的源碼分析是在 commit da92692baa660359bb314d89dfa3a80bffb1d26c 之上進行的。git
kubeedge是一個基於kubernetes構建的開放平臺,使能邊緣計算,將容器化應用編排功能擴展到邊緣的節點和設備,併爲雲和邊緣之間的網絡,應用部署和元數據同步提供基礎架構支持。github
本文從kubeedge的總體架構切入,首先梳理它包含的組件功能及組件之間的關係,而後分析各組件之間共用的框架和功能,最後分析組件中各模塊之間共用的框架和功能。具體以下:api
kubeedge中的組件及組件關係,先從官方的架構圖提及,具體以下:微信
從官方的架構圖能夠清晰地看到,kubeedge總體分Cloud和Edge兩部分:網絡
除了官方架構圖展現的Cloud和Edge部分外,還有橫跨Cloud和Edge的部分,具體以下:架構
在源碼層面,kubeedge核心獨立組件包括cloudcore、edgecore、edge_mesh和edge_site,除此以外還有mappers和keadm,具體以下下表:app
組件名 | 組件功能 | 備註 |
---|---|---|
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 ,具體以下:tcp
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中功能模塊的註冊
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中功能模塊的註冊
// 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())
} 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中功能模塊的註冊能夠參考」edgecore中功能模塊的註冊」,這裏就不在贅述。
edgemesh中功能模塊的啓動
edgemesh目前暫時沒有模塊啓動邏輯。
在「組件的共用框架和功能」的「edgesite代碼入口」部分已經分析到edgemesh中功能模塊的註冊和已註冊功能模塊的啓動,本節就接着往下分析。
edgesite中功能模塊的註冊請參考」edgecore中功能模塊的註冊」,這裏就不在贅述。
edgesite中功能模塊的啓動
edgesite中功能模塊的啓動請參考」edgecore中功能模塊的啓動」,這裏就不在贅述。
本文是「之江實驗室端邊雲操做系統團隊」 kubeedge源碼分析系列的第一篇,接下來會對各組件的源碼進行系統分析。若是有機會咱們團隊也會積極解決kubeedge的issue和實現新的feature。
這是咱們「之江實驗室端邊雲操做系統團隊」維護的"之江實驗室kubeedge源碼分析羣"微信羣,歡迎你們的參與!!!