爲了避免違反廣告法,我不遺餘力,不過「最佳實踐」確是標題黨無疑,若是硬要說的話 只能是我的最佳實踐。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