为了避免违反广告法,我不遗余力,不过“最佳实践”确是标题党无疑,若是硬要说的话 只能是我的最佳实践。git
可能不少新手都会遇到一样的问题:我要个人Asp.net Core 应用传统方式直接部署(host),docker部署(docker-compose),kubernetes(如下称k8s)下部署,都用统一的方式读取配置,怎么实现呢?。github
你们知道,咱们默认平时配置文件以appsettings.json
、appsettings.{EnvironmentName}.json
形式存在,这样在host方式下面没有问题,但在docker下,若是直接把配置打包到镜像,那每次改一下下配置就须要从新打包,那成本太大了。另外在k8s下面又有Secret、ConfigMap等多种方式管理配置,如何把多种配置存储和读取,有机结合、同一份代码统一管理使用,是咱们今天的主题。docker
下面我用一个Api网关Ocelot做为示例(demo),讲讲我处理的方式,但愿能给你们带来必定启发。json
注:c#
其实不改成yml也能够的!!api
主要考虑到后面在docker、k8s等里面,更好管理,好比yaml的注释和json的注释语法不一致等等问题;app
好比我原来的appsettings.json长这样:ide
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "AddAdministration": { "Path": "/administration", "IdentityServer": { "Authority": "http://172.16.3.117:5100", "ApiName": "ocelot", "RequireHttpsMetadata": false, "ApiSecret": "secret" } } }
改为 appsettings.ymlui
Logging: LogLevel: Default: Information Microsoft: Warning Microsoft.Hosting.Lifetime: Information AllowedHosts: '*' AddAdministration: Path: /administration IdentityServer: Authority: 'http://172.16.3.117:5100' ApiName: ocelot RequireHttpsMetadata: false ApiSecret: secret
是否是看起来简单清晰了不少,其实我如今愈来愈喜欢用yml了spa
既然配置源的格式变了,那读取配置的方法也确定变了,起码config.AddJsonFile(“xx.json”) 要改成 config.AddYamlFile(“xx.yml”)
新增引用的扩展:NetEscapades.Configuration.Yaml
加载配置文件改写为:
.AddYamlFile("appsettings.yml", optional: false, reloadOnChange: true) .AddYamlFile($"appsettings.{env.EnvironmentName}.yml", optional: true, reloadOnChange: true)
“但在docker下,若是直接把配置打包到镜像,那每次改一下下配置就须要从新打包,那成本太大了”
我前面提出了这个问题,如想不从新打包,Volume(挂载)就行了。
把你的配置文件放到/home/heidemo/config
目录后,好比咱们什么的示例配置文件: appsettings.yml
docker run --rm=true -v /home/heidemo/config:/config gebiwangshushu/hei-ocelot-apigateway:1.0
这样就能够随性更新/home/heidemo/config下的配置信息而不须要每次都从新build镜像了,这样是支持热更新的,固然若是你修改的那个配置是须要重启程序才能够加载的,那仍是要用docker-compose 重启下对应服务的;
咱们知道 Docker是 官方编排(Orchestration)项目之一,若是咱们在Docker环境下挂载配置的话,那在docker-compose下面的配置也是挂载的,咱们来看下咱们掐头去尾后的 docker-compose.yml
:
version: '3.4' services: hei.ocelot.apigateway: ... volumes: - /home/heidemo/config:/app/config ...
没错,docker-compose 额挂载就这么定义,这样能够实现跟Docker同样的挂载效果;
你们能够用以上配置 clone个人demo,而后 docker-compose up
一下,看看效果;
前面的docker、docker-compose 的方式仍是很是容易理解的,就是挂载;那咱们在k8s下面运行的时候,它的容器实例是动态的运行到集群的各台机器上的,那若是咱们咱们只用文件挂载很明显就不知足要求了,咱们来看看怎么实现。
先准备一个configMap,hei-ocelot-config.yml
apiVersion: v1 kind: ConfigMap metadata: name: hei-ocelot-apigateway namespace: dotnetcore data: appsettings.yml: | Logging: LogLevel: Default: Information Microsoft: Warning Microsoft.Hosting.Lifetime: Information AllowedHosts: '*' AddAdministration: Path: /administration IdentityServer: Authority: 'http://172.16.1.30:31100' #这里的受权中心能够配置你本身的 ApiName: ocelot RequireHttpsMetadata: false ApiSecret: secret
完整请看这里
你们能够看到,咱们的data节点是跟咱们程序里面的appsettings.json
同样同样的,这也是咱们比较喜欢再也不用json的缘由。
建立configMap:
kubectl apply -f hei-ocelot-config.yml
查看configMap:
kubectl describe configmaps hei-ocelot-apigateway -n dotnetcore
使用configMap:
这里是使用示例,在个人demo根目录下面完整配置deploy.yml 是能够直接部署的。
apiVersion: apps/v1 kind: Deployment metadata: name: hei-ocelot-apigateway namespace: dotnetcore spec: replicas: 1 selector: matchLabels: app: hei-ocelot-apigateway template: metadata: labels: app: hei-ocelot-apigateway spec: containers: - name: hei-ocelot-apigateway image: gebiwangshushu/hei-ocelot-apigateway:1.1 ports: - containerPort: 80 volumeMounts: - name: hei-ocelot-apigateway mountPath: "/app/config" readOnly: true volumes: - name: hei-ocelot-apigateway configMap: name: hei-ocelot-apigateway
能够看到咱们在k8s下面也是用volumes的方式使用咱们的configMap的,其中挂载目录volumeMounts:mountPath是"/app/config",咱们进入运行中pod看下配置:
kubectl exec -it hei-ocelot-apigateway-795495f7c8-vpmhb sh -n dotnetcore cd /app/config
咱们能够看到咱们的pod里面的/app/config ,确确实实有咱们要的配置;
这里由于咱们是volumes 的方式的,你们能够试着改下上面的configMap-- hei-ocelot-config.yml 再从新apply 一下,会看到这里的配置是几乎是即时更新的(有一点点延迟);
PS:有一个问题有些在startup使用的配置,即时更新了也须要重启下应用,这个我暂时还没想到什么办法好办法,各位老哥有什么思路的能够直接甩我一脸~
其实写完我以为也有点怪怪,说新手引导吧,不够保姆式、说经验分享,不够精简,下次我定好好想,认真写好点;
而后个人主题,其实思考过一样问题的读者,全文就一句:volumes挂载配置作到各类环境下的配置统一;
最后,我抛出了一个问题:On K8s的时候, 程序启动使用的配置,如何在配置文件更新的状况后重启程序应用新配置(或者叫热加载配置?固然这里不是指配置文件的reloadOnChange=true);
github:https://github.com/gebiWangshushu/Hei.Ocelot.ApiGateway