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

I want to change config of log on Golang application which run on K8S, I’ve tried the following code locally and it works as expected I'm using viper to watch for config file changes

This is the config map with the log configuration

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

In the deployment yaml I’ve added the following

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

This is the code

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

Now when I apply the yaml file again and changing the value from error to warn or debug etc Nothing change … any idea what I miss here ?

I see in the K8S dashboard that the config map is assigned to the application and when I change the value I see that the env was changed...

update

when run it locally I use the following config just for testing but when using config map I've used the data entry according to the spec of configmap ...

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

This is how the config env looks in k8s dashboard

enter image description here

3个回答



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

如果将config.yaml作为文件挂载在pod内则更好,例如将ConfigMap数据添加到卷 </ p>
</ div>

展开原文

原文

envFrom creates environment variables from the config map. There is no file that changes. If you exec into the container you'll probably see an environment variable named config.yaml or CONFIG.YAML or similar (don' t know if it works with dots).

You are probably better of if you mount config.yaml as a file inside your pods, like this Add ConfigMap data to a Volume

dsfgdsjfd78773
dsfgdsjfd78773 所以我不知道毒蛇,但看起来它监视文件,而不是环境变量列表。 在您的情况下,它将监视默认文件,并且该文件永远不会更改。 最好的选择是将configMap挂载为该默认文件,然后在检测到更改时重新配置pod。
大约一年之前 回复
dsfdfdfd6576578
dsfdfdfd6576578 谢谢,我看到了这个选项,但是我尝试实现的是当configmap文件中的env更改然后更新日志级别时,我的意思是当我再次以不同的日志级别应用CM文件时,它将使用cvAutomaticEnv( 毒蛇...有可能吗? 不挂载到文件
大约一年之前 回复
doukongyong44772
doukongyong44772 是的,那是环境变量,而不是文件。 您应该将配置挂载为文件,然后可以使用viper对其进行监视。 我会更新我的答案
大约一年之前 回复
drgd73844
drgd73844 我已经用env值从k8s仪表板上的图片更新了问题
大约一年之前 回复
duanke2503
duanke2503 关于第2点,是的,在CM中没有这样的属性,您是对的:),这只是为了在本地进行测试,这就是我在CM中的data属性下添加该属性的原因
大约一年之前 回复



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

最后,您的本地测试环境(在此环境中有效)与其他环境在不起作用之间有什么区别?</ p>

p>

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

展开原文

原文

I understand that viper can help with live changing out of configuration without restarting your app using the OnConfigChange event, but have you tried setting the log level in your base ConfigMap and then starting up the app, just to make sure it's not an issue with the OnConfigChange event firing and your particular config in k8s (and not your local environment where you've tested it works).

Lastly, what is the difference between your local test environment (where this is working) and the other environment where this is not working?

Are there any environment variables that might be affecting this differently in the one environment?

dthjnc306679
dthjnc306679 关于其他env变量,没有什么可以引起冲突的,日志和端口是我使用过的唯一env ...
大约一年之前 回复
dongsechuan0535
dongsechuan0535 谢谢,请参阅我的更新
大约一年之前 回复



如果使用卷安装ConfigMap,则每当更新ConfigMap时,卷自动更新。</ p>

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

如果需要 配置以在容器内更新,我建议您:</ p>


  • 使用卷来装载ConfigMap。</ li>
  • 每次重新启动容器时, 如果使用环境变量挂载,则会更新ConfigMap。</ li>
    </ ul>
    </ div>

展开原文

原文

If you mount a ConfigMap using a volume, whenever you update the ConfigMap, then the volume updates automatically.

However, if you mount a ConfigMap using an environment variable, even if you update the ConfigMap, your environment variables do not get updated inside the containers.

If you want the configurations to update inside your containers, I would suggest you either:

  • use volumes to mount ConfigMaps.
  • restart your containers every time the ConfigMap is updated if you use an environment variable to mount it.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐