多是Asp.net Core On host、 docker、kubernetes(K8s) 配置讀取的最佳實踐

寫在前面

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

問題引出

​ 可能不少新手都會遇到一樣的問題:我要個人Asp.net Core 應用傳統方式直接部署(host),docker部署(docker-compose),kubernetes(如下稱k8s)下部署,都用統一的方式讀取配置,怎麼實現呢?。github

​ 你們知道,咱們默認平時配置文件以appsettings.jsonappsettings.{EnvironmentName}.json 形式存在,這樣在host方式下面沒有問題,但在docker下,若是直接把配置打包到鏡像,那每次改一下下配置就須要從新打包,那成本太大了。另外在k8s下面又有Secret、ConfigMap等多種方式管理配置,如何把多種配置存儲和讀取,有機結合、同一份代碼統一管理使用,是咱們今天的主題。docker

​ 下面我用一個Api網關Ocelot做爲示例(demo),講講我處理的方式,但願能給你們帶來必定啓發。json

1、先把配置文件改爲Yaml格式

注: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)

2、Docker使用

「但在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 重啓下對應服務的;

3、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 一下,看看效果;

4、k8s使用

前面的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

1596101753461

使用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 ,確確實實有咱們要的配置;

1596383131953

這裏由於咱們是volumes 的方式的,你們能夠試着改下上面的configMap-- hei-ocelot-config.yml 再從新apply 一下,會看到這裏的配置是幾乎是即時更新的(有一點點延遲);

PS:有一個問題有些在startup使用的配置,即時更新了也須要重啓下應用,這個我暫時還沒想到什麼辦法好辦法,各位老哥有什麼思路的能夠直接甩我一臉~

總結

其實寫完我以爲也有點怪怪,說新手引導吧,不夠保姆式、說經驗分享,不夠精簡,下次我定好好想,認真寫好點;

而後個人主題,其實思考過一樣問題的讀者,全文就一句:volumes掛載配置作到各類環境下的配置統一;

最後,我拋出了一個問題:On K8s的時候, 程序啓動使用的配置,如何在配置文件更新的狀況後重啓程序應用新配置(或者叫熱加載配置?固然這裏不是指配置文件的reloadOnChange=true);

github:https://github.com/gebiWangshushu/Hei.Ocelot.ApiGateway

相關文章
相關標籤/搜索