.NET 6在使用 ConfigMap的情况下,自动刷新配置文件的方法

132 阅读1分钟

本文介绍的方法仅适用于 .NET 6及以上版本

.Net的Configuration系统,在加载json格式的配置文件时,可以选择reloadOnChange,即当文件发生变化时自动重新加载。

如果是运行在Kubernetes中的服务,并且将配置文件放在了ConfigMap里,那么mount之后,即使ConfigMap发生了变化,也不会触发重新加载。

原因在于,ConfigMap里的改动并不会触发相应的IO事件,而且里面的文件本质上是link,所以最后修改时间以及大小都不会发生改变。

ls.png

.NET 6里增加了对link文件所指向的源文件的监听,使针对ConfigMap的自动加载成为可能。github.com/dotnet/runt…

首先要注意的是,mount ConfigMap时,必须mount到一个文件夹里,不能使用subPath,否则在不重启pod的情况下,配置文件是不会发生变化的。

其次,需要配置一个环境变量,让ConfigrationProvider使用PhysicalFilesWatcher而不是默认的FileSystemWatcher。github.com/dotnet/runt…

var config = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile($"config/config.json", optional: true, reloadOnChange: true)
    .Build();
apiVersion: apps/v1
kind: Deployment
metadata:
  name: worker
  labels:
    app.kubernetes.io/name: worker
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: worker
  template:
    metadata:
      labels:
        app.kubernetes.io/name: worker
    spec:
      containers:
        - name: worker
          image: worker:0.2
          env:
            - name: DOTNET_USE_POLLING_FILE_WATCHER # 需要指定这个环境变量
              value: "true"
          resources:
            limits:
              cpu: 500m
              memory: 200Mi
            requests:
              cpu: 300m
              memory: 200Mi
          volumeMounts:
            - name: config
              mountPath: "/app/config" # mount成一个文件夹
              readOnly: true
      volumes:
        - name: config
          configMap:
            name: worker-config