写在前面

为了不违反广告法,我竭尽全力,不过“最佳实践”确是标题党无疑,如果硬要说的话 只能是个人最佳实践。

问题引出

可能很多新手都会遇到同样的问题:我要我的Asp.net Core 应用传统方式直接部署(host),docker部署(docker-compose),kubernetes(以下称k8s)下部署,都用统一的方式读取配置,怎么实现呢?。

大家知道,我们默认平时配置文件以appsettings.jsonappsettings.{EnvironmentName}.json 形式存在,这样在host方式下面没有问题,但在docker下,如果直接把配置打包到镜像,那每次改一下下配置就需要重新打包,那成本太大了。另外在k8s下面又有Secret、ConfigMap等多种方式管理配置,如何把多种配置存储和读取,有机结合、同一份代码统一管理使用,是我们今天的主题。

下面我用一个Api网关Ocelot作为示例(demo),讲讲我处理的方式,希望能给大家带来一定启发。

一、先把配置文件改成Yaml格式

注:

其实不改为yml也可以的!!

主要考虑到后面在docker、k8s等里面,更好管理,比如yaml的注释和json的注释语法不一致等等问题;

比如我原来的appsettings.json长这样:

{"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.yml

Logging:LogLevel:Default: InformationMicrosoft: WarningMicrosoft.Hosting.Lifetime: Information
AllowedHosts: '*'
AddAdministration:Path: /administrationIdentityServer:Authority: 'http://172.16.3.117:5100'ApiName: ocelotRequireHttpsMetadata: falseApiSecret: secret

是不是看起来简单清晰了很多,其实我现在越来越喜欢用yml了

既然配置源的格式变了,那读取配置的方法也肯定变了,起码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使用

“但在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-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一下,看看效果;

四、k8s使用

前面的docker、docker-compose 的方式还是非常容易理解的,就是挂载;那我们在k8s下面运行的时候,它的容器实例是动态的运行到集群的各台机器上的,那如果我们我们只用文件挂载很明显就不满足要求了,我们来看看怎么实现。

先准备一个configMap,hei-ocelot-config.yml

apiVersion: v1
kind: ConfigMap
metadata:name: hei-ocelot-apigatewaynamespace: dotnetcore
data:appsettings.yml: |Logging:LogLevel:Default: InformationMicrosoft: WarningMicrosoft.Hosting.Lifetime: InformationAllowedHosts: '*'AddAdministration:Path: /administrationIdentityServer:Authority: 'http://172.16.1.30:31100' #这里的授权中心可以配置你自己的ApiName: ocelotRequireHttpsMetadata: falseApiSecret: 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-apigatewaynamespace: dotnetcore
spec:replicas: 1selector:matchLabels:app: hei-ocelot-apigatewaytemplate:metadata:labels:app: hei-ocelot-apigatewayspec:containers:- name: hei-ocelot-apigatewayimage: gebiwangshushu/hei-ocelot-apigateway:1.1ports:- containerPort: 80volumeMounts:- name: hei-ocelot-apigatewaymountPath: "/app/config"readOnly: truevolumes:- name: hei-ocelot-apigatewayconfigMap:name: hei-ocelot-apigateway

可以看到我们在k8s下面也是用volumes的方式使用我们的configMap的,其中挂载目录volumeMounts:mountPath是”/app/config”,我们进入运行中pod看下配置:

kubectl exec -it hei-ocelot-apigateway-795495f7c8-vpmhb sh -n dotnetcorecd /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

文章博客园地址请点击“阅读原文”

可能是Asp.net Core On host、 docker、kubernetes(K8s) 配置读取的最佳实践相关推荐

  1. Docker ASP.NET Core (5):Docker Compose

    Docker & ASP.NET Core (5):Docker Compose 原文:Docker & ASP.NET Core (5):Docker Compose 第一篇:把代码 ...

  2. ASP.NET Core 部署到docker

    ASP.NET Core 部署到docker ASP.NET Core:ASP.NET Core程序使用Docker部署 前提:本地已有 ASP.NET Core web应用程序,并且已安装docke ...

  3. asp.net core 发布到 docker 容器时文件体积过大及服务端口的配置疑问

    在 asp.net core 发布时,本人先后产生了3个疑问. 1.发布的程序为什么不能在docker容器中运行 当时在window开发环境中发布后,dotnet xxx.dll可以正常运行:但放入d ...

  4. 基于VS2017的Docker Support体检ASP.NET Core站点的Docker部署

    最近在学习如何用 Docker 部署生产环境中的 ASP.NET Core 站点,作为一个 Docer 新手,从何处下手更容易入门呢?一开始就手写 Docker 配置文件(Docfile, docke ...

  5. ASP.NET Core 网站在Docker中运行

    Docker作为新一代的虚拟化方式,未来肯定会得到广泛的应用,传统虚拟机的部署方式要保证开发环境.测试环境.UAT环境.生产环境的依赖一致性,需要大量的运维人力,使用Docker我们可以实现一次部署, ...

  6. ASP.NET Core 缓存技术 及 Nginx 缓存配置

    前言 在Asp.Net Core Nginx部署一文中,主要是讲述的如何利用Nginx来实现应用程序的部署,使用Nginx来部署主要有两大好处,第一是利用Nginx的负载均衡功能,第二是使用Nginx ...

  7. asp.net core轻松入门之MVC中Options读取配置文件

    接上一篇中讲到利用Bind方法读取配置文件 ASP.NET Core轻松入门Bind读取配置文件到C#实例 那么在这篇文章中,我将在上一篇文章的基础上,利用Options方法读取配置文件 首先注册MV ...

  8. ASP.NET Core和Blazor Code Venture:配置Azure AD身份验证

    目录 介绍 背景 安装开发环境 先决条件 安装框架和工具 安装Azure Active Directory 创建一个新用户 使用Azure AD进行服务器端Blazor身份验证 第一次运行 下载ToD ...

  9. docker 日志_Docker容器日志管理最佳实践

    博客园:https://www.cnblogs.com/operationhome/p/10907591.html 本文所有内容基于: Docker-CE Server Version: 18.09. ...

最新文章

  1. 火遍全国的网络热梗“yyds”,创造者被判刑3年
  2. mxnet基础到提高(21)-配置mxnet并运行第一个C++程序
  3. 最新数据显示,全国有580万人被限制乘坐高铁,大家怎么看?
  4. 【PostgreSQL-9.6.3】使用pg_settings表查看参数的生效条件
  5. 复制百度文库内容方法
  6. mysql中修改表字段的类型长度_mysql中修改表字段名/字段长度/字段类型详解
  7. nx零件库插件_3DSource企业自定义零件库插件
  8. matlab j计算丰水期的值,科学计算与MATLAB语言超星2020期末考试查题公众号答案
  9. excel表格筛选某一列重复数据
  10. 普惠联接,让人类诗意地栖居在大地上
  11. 解决导入protobuf源代码Unity报错的问题
  12. 计算机系统概论第2版答案第七章,计算机系统概论(第七章).ppt
  13. modules node 太大了_解决node_modules文件名太长无法删除的两个方法-文件名太长
  14. pagehelper不调用startpage依旧执行分页问题处理
  15. 裸辞3个月,空白期啥都没干,怎么办?
  16. QQ秀已然式微,而同时迭代的厘米秀正在雄起。
  17. 项目进度紧张,如何确保保质保量完成?
  18. JS替换字符串中所有指定的字符(串)
  19. numpy的通用函数
  20. Windows上使用C#控制台应用程序打开指定路径的文件

热门文章

  1. 题目1023:EXCEL排序---------Case后面的是count,不是C
  2. web上传大文件的配置
  3. Codeforces Round #323 (Div. 1) B. Once Again... 暴力
  4. MongoDB基本命令的使用
  5. Dom4J 解析xml ,类查询
  6. 读jquery 权威指南[7]-性能优化与最佳实践
  7. 遍历DataTable内存数据的三种方法性能对比
  8. 2007武汉.NET俱乐部沙龙-VS2008、WPF、Silverlight
  9. 如何在OS X中打开或关闭鼠标定位器
  10. python实现异步的几种方式_终于搞明白了,异步Python比同步Python究竟快在哪里?...