配置文件的读取

截至目前,已经分析了Kubeedge整体架构,Kubeedge的cloudcore部分,Kubeedge edgecore部分的devicetwin,Kubeedge edgecore部分的edged,Kubeedge edgecore部分的edgehub,但却忽略了一个重要环节,那就是配置文件的读取。本文对Kubeedge的配置文件读取流程进行剖析。

配置文件读取流程剖析

Kubeedge各模块配置文件读取使用的库是相同,流程也是高度相似的,所以本文只对Kubeedge其中一个模块读取配置文件的流程进行深入剖析,其他模块的配置文件读取,可以在本文的基础上自行剖析。

本文在kubeedge的cloudcore部分“cloudhub剖析”的“初始化cloudhub的配置”基础上展开,进入“初始化cloudhub的配置”:

kubeedge/cloud/edge/pkg/cloudhub/cloudhub.go
func (a *cloudHub) Start(c *beehiveContext.Context) { 
            ...
 initHubConfig() 
            ... 
}

进入initHubConfig()函数:

kubeedge/cloud/pkg/cloudhub/cloudhub.go

import(
           ...
           "github.com/kubeedge/beehive/pkg/common/config"
            ... 
) 
 func initHubConfig() { 
             cafile, err := config.CONFIG.GetValue("cloudhub.ca").ToString()
             ...
             certfile, err := config.CONFIG.GetValue("cloudhub.cert").ToString()
             ... 
             keyfile, err := config.CONFIG.GetValue("cloudhub.key").ToString()
             ... 

             util.HubConfig.ProtocolUDS, _ = config.CONFIG.GetValue("cloudhub.enable_uds").ToBool() 

             util.HubConfig.Address, _ = config.CONFIG.GetValue("cloudhub.address").ToString() 
             util.HubConfig.Port, _ = config.CONFIG.GetValue("cloudhub.port").ToInt() 
             util.HubConfig.QuicPort, _ = config.CONFIG.GetValue("cloudhub.quic_port").ToInt() 
             util.HubConfig.MaxIncomingStreams, _ = config.CONFIG.GetValue("cloudhub.max_incomingstreams").ToInt() 
             util.HubConfig.UDSAddress, _ = config.CONFIG.GetValue("cloudhub.uds_address").ToString() 
             util.HubConfig.KeepaliveInterval, _ = config.CONFIG.GetValue("cloudhub.keepalive-interval").ToInt()
             util.HubConfig.WriteTimeout, _ = config.CONFIG.GetValue("cloudhub.write-timeout").ToInt()
             util.HubConfig.NodeLimit, _ = config.CONFIG.GetValue("cloudhub.node-limit").ToInt() 
             ...
 }

根据initHubConfig()函数定义和相关import导入,config是import进来的package,真正起作用的是config.CONFIG,进入config.CONFIG的定义:

kubeedge/beehive/pkg/common/config/config.go
// CONFIG conf 
var CONFIG archaius.ConfigurationFactory

从定义中可以知道,config.CONFIG是定义的一个archaius.ConfigurationFactory类型的全局变量,剖析到此,同学们肯定会疑惑,只定义怎么一个全局变量怎么来读取配置文件呢?目测,肯定会有函数对这个全局变量进行赋值,根据以往经验,这样的全局变量会被所在文件的init()函数初始化,检查该变量所在文件的init()函数:

kubeedge/beehive/pkg/common/config/config.go

func init() {
             InitializeConfig()
 }

进入InitializeConfig()函数定义:

kubeedge/beehive/pkg/common/config/config.go

import ( 
            ... 
            archaius "github.com/go-chassis/go-archaius" 
            ... 
) 

// config file  only support .yml or .yaml  !
 func InitializeConfig() { 
        once.Do(func() {
                     err := archaius.Init() 
                     ...
                     CONFIG = archaius.GetConfigFactory() 
                     ms := memoryconfigsource.NewMemoryConfigurationSource() 
                     CONFIG.AddSource(ms) 

                     cmdSource := commandlinesource.NewCommandline
                     ConfigSource() 
                     CONFIG.AddSource(cmdSource) 

                     envSource := envconfigsource.NewEnvConfigurationSource()
                     CONFIG.AddSource(envSource) 
                     confLocation := getConfigDirectory() + "/conf" 
                     _, err = os.Stat(confLocation)
                     if !os.IsExist(err) { 
                              os.Mkdir(confLocation, os.ModePerm) 
                    } 
                   err = filepath.Walk(confLocation, func(location string, f os.FileInfo, err error) error {
                            if f == nil { 
                                      return err
                            }
                            if f.IsDir() { 
                            return nil
                            } 
                            ext := strings.ToLower(path.Ext(location))
                            if ext == ".yml" || ext == ".yaml" { 
                                         archaius.AddFile(location)
                            } 
                            return nil
                  }) 
                  ...
           }) 
}

从函数内容来看, InitializeConfig()函数对config.CONFIG进行了赋值,也是读取配置文件内容的真身,下面剖析一下InitializeConfig()具体做了什么事情:

  1. 配置模块初始化
err := archaius.Init() 
 ... 
 CONFIG = archaius.GetConfigFactory()
  1. 获取内存配置源
ms := memoryconfigsource.NewMemoryConfigurationSource() 
CONFIG.AddSource(ms)
  1. 获取命令行配置源
cmdSource := commandlinesource.NewCommandlineConfigSource() CONFIG.AddSource(cmdSource)
  1. 获取环境变量配置源
envSource := envconfigsource.NewEnvConfigurationSource() CONFIG.AddSource(envSource)
  1. 根据配置文件路径获取配置源
     confLocation := getConfigDirectory() + "/conf"
      _, err = os.Stat(confLocation) 
      if !os.IsExist(err) { 
                  os.Mkdir(confLocation, os.ModePerm) 
      } 
      err = filepath.Walk(confLocation, func(location string, f os.FileInfo, err error) error {
                  if f == nil {
                            return err 
      }
                  if f.IsDir(){
                            return nil
      } 
      ext := strings.ToLower(path.Ext(location))
      if ext == ".yml" || ext == ".yaml" { 
                           archaius.AddFile(location) 
      } 
      return nil
      }) 
      ... 
 })

kubeedge目前所用的读取配置文件的方式是“5.根据配置文件路径获取配置源”,下面深入剖析该配置文件读取方式,首先确定配置所在路径confLocation,进入getConfigDirectory()函数定义:

kubeedge/beehive/pkg/common/config/config.go

//constants to define config paths 
const ( 
          ParameterConfigPath     = "config-path"
          EnvironmentalConfigPath = "GOARCHAIUS_CONFIG_PATH" 
) 
...
 // get the configuration file path 
func getConfigDirectory() string { 
             if config, err := CONFIG.GetValue(ParameterConfigPath).ToString(); err == nil {
                       return config 
             }
             if config, err := CONFIG.GetValue(EnvironmentalConfigPath).ToString(); err == nil{
                       return config 
             } 
             return util.GetCurrentDirectory() 
}

getConfigDirectory()函数中获取配置文件所在目录的方式有3种:

  1. 根据ParameterConfigPath获取
// get the configuration file path 
 func getConfigDirectory() string { 
                    if config, err := CONFIG.GetValue(ParameterConfigPath).ToString(); err == nil { 
                   return config
}
  1. 根据EnvironmentalConfigPath获取
if config, err := CONFIG.GetValue(EnvironmentalConfigPath).ToString(); err == nil { 
                return config
 }
  1. 根据可执行文件运行所在的当前目录下获取
    return util.GetCurrentDirectory()

kubeedge目前获取配置文件的方式是“3. 根据可执行文件运行所在的当前目录下获取”,到此就确定了kubeedge读取配置文件的路径,接着分析怎么读入配置文件的:

kubeedge/beehive/pkg/common/config/config.go

confLocation := getConfigDirectory() + "/conf"
 _, err = os.Stat(confLocation)
 if !os.IsExist(err) { 
             os.Mkdir(confLocation, os.ModePerm) 
 } 
 err = filepath.Walk(confLocation, func(location string, f os.FileInfo, err error) error {
             if f == nil { 
                      return err 
             } 
             if f.IsDir() { 
                     return nil
             } 
 ext := strings.ToLower(path.Ext(location))
             if ext == ".yml" || ext == ".yaml" { 
                     archaius.AddFile(location)}return nil})
              ...
 })

在获取了配置文件所在的目录confLocation后,干了下面几件事:

  1. 判断目录是否存在,如果不存在创建该目录
confLocation := getConfigDirectory() + "/conf"
 _, err = os.Stat(confLocation)
 if !os.IsExist(err) { 
              os.Mkdir(confLocation, os.ModePerm)
}
  1. 遍历配置文件目录下符合条件的文件,加入配置信息源
err = filepath.Walk(confLocation, f
 err = filepath.Walk(confLocation, func(location string, f os.FileInfo, err error) error { 

               if f == nil { 
                         return err
                }
                if f.IsDir() { 
                         return nil 
                } 
                ext := strings.ToLower(path.Ext(location)) 
                if ext == ".yml" ||
                ext == ".yaml" { 
                archaius.AddFile(location) }
                         return nil })
                ... 
 })

到此 config.CONFIG就获取了kubeedge所需配置文件内容。

通过上面的分析,kubeedge是通过kubeedge/beehive/pkg/common/config来读去所需的配置文件的,而kubeedge/beehive/pkg/common/config又封装了go-archaius。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容