K8s更改配置映射并更新应用日志级别

时间:2019-09-14 15:28:09

标签: go kubernetes

我想更改在K8S上运行的Golang应用程序上的日志配置, 我已经在本地尝试了以下代码,并且可以正常使用 我正在使用毒蛇监视配置文件的更改

这是带有日志配置的配置图

apiVersion: v1
kind: ConfigMap
data:
  config.yaml: 'log.level: error'
metadata:
  name: app-config
  namespace: logger

在部署Yaml中,我添加了以下内容

...
spec:
  containers:
    - name: gowebapp
      image: mvd/myapp:0.0.3
      ports:
        - containerPort: 80
      envFrom:
        - configMapRef:
            name: app-config

这是代码

package configuration

import (
   "fmt"
   "os"
   "strings"

   "github.com/fsnotify/fsnotify"
   "github.com/sirupsen/logrus"
   "github.com/spf13/viper"
)

const (
   varLogLevel     = "log.level
"
   varPathToConfig = "config.file"
)

type Configuration struct {
   v *viper.Viper
}

func New() *Configuration {
   c := Configuration{
      v: viper.New(),
   }

   c.v.SetDefault(varPathToConfig, "./config.yaml")
   c.v.SetDefault(varLogLevel, "info")
   c.v.AutomaticEnv()
   c.v.SetConfigFile(c.GetPathToConfig())
   err := c.v.ReadInConfig() // Find and read the config file
   logrus.WithField("path", c.GetPathToConfig()).Warn("loading config")
   if _, ok := err.(*os.PathError); ok {
      logrus.Warnf("no config file '%s' not found. Using default values", c.GetPathToConfig())
   } else if err != nil { // Handle other errors that occurred while reading the config file
      panic(fmt.Errorf("fatal error while reading the config file: %s", err))
   }
   setLogLevel(c.GetLogLevel())
   c.v.WatchConfig()
   c.v.OnConfigChange(func(e fsnotify.Event) {
      logrus.WithField("file", e.Name).Warn("Config file changed")
      setLogLevel(c.GetLogLevel())
   })
   return &c
}

// GetLogLevel returns the log level
func (c *Configuration) GetLogLevel() string {
   s := c.v.GetString(varLogLevel)
   return s
}

// GetPathToConfig returns the path to the config file
func (c *Configuration) GetPathToConfig() string {
   return c.v.GetString(varPathToConfig)
}

func setLogLevel(logLevel string) {
   logrus.WithField("level", logLevel).Warn("setting log level")
   level, err := logrus.ParseLevel(logLevel)
   if err != nil {
      logrus.WithField("level", logLevel).Fatalf("failed to start: %s", err.Error())
   }
   logrus.SetLevel(level)
}

现在,当我再次应用yaml文件并将值从error更改为warndebug等时, 没什么变化...知道我在这里错过了什么吗?

我在K8S仪表板中看到配置映射已分配给应用程序,并且当我更改该值时,我看到环境已更改...

更新

在本地运行时,我使用以下配置进行测试 但是在使用配置映射时,我根据配置映射的规范使用了data条目...

apiVersion: v1
kind: ConfigMap
log.level: 'warn'
#data:
#  config.yaml: 'log.level: error'
metadata:
  name: app-config

这是配置环境在k8s仪表板中的外观

enter image description here

3 个答案:

答案 0 :(得分:3)

envFrom从配置映射中创建环境变量。没有文件更改。如果您执行到容器中,可能会看到一个名为config.yaml或CONFIG.YAML或类似名称的环境变量(不知道它是否适用于点)。

如果将config.yaml作为文件挂载在pod中,则可能会更好,例如Add ConfigMap data to a Volume

答案 1 :(得分:1)

我知道毒蛇可以帮助您实时进行配置更改,而无需使用OnConfigChange事件重新启动应用程序,但是您是否尝试过在基本ConfigMap中设置日志级别,然后启动应用程序,只是为了确保不是OnConfigChange事件触发和k8s中的特定配置(而不是您测试过的本地环境)的问题。

最后,您的本地测试环境(正在运行的环境)与另一个环境在无法运行的环境之间有什么区别?

在一个环境中是否有任何环境变量可能对此产生不同的影响?

答案 2 :(得分:1)

如果使用卷挂载ConfigMap,则每当更新ConfigMap时,卷updates automatically就会出现。

但是,如果使用环境变量挂载ConfigMap,即使更新ConfigMap,环境变量也不会在容器内更新。

如果您想在容器内更新配置,我建议您:

  • 使用卷挂载ConfigMap。
  • 如果使用环境变量挂载,则每次更新ConfigMap时都要重新启动容器。