.NET Core 使用 K8S ConfigMap的正确姿势

640?wx_fmt=png

背景

ASP.NET Core默认的配置文件定义在 appsetings.jsonappsettings.{Environment}.json文件中。这里面有一个问题就是,在使用容器部署时,每次修改配置文件都需要重新构建镜像。当然你也可能会说,我的配置文件很稳定不需要修改,但你又如何确保配置文件中一些机密配置的安全问题呢?比如暴露了你的远程数据库的连接信息,哪天被员工不小心删库跑路了呢?那接下来就来讲解下如何在.NET Core 中正确使用ConfigMap。

ConfigMap/Secret

K8S中引入了ConfigMap/Secret来存储配置数据,分别用于存储非敏感信息和敏感信息。其目的在于将应用和配置解耦,以确保容器化应用程序的可移植性。

创建 ConfigMap

玩耍K8S,请先自行准备环境,Win10用户可以参考我的上篇文章ASP.NET Core 借助 K8S 玩转容器编排来准备环境。

ConfigMap的创建很简单,一句命令就可以直接将 appsettings.json文件转换为ConfigMap。

PS:使用K8S一定要善用帮助命令,比如执行 kubectl create configmap-h,你就可以了解到多种创建ConfigMap的方式。

> kubectl create configmap -h	
Create a configmap based on a file, directory, or specified literal value.	
A single configmap may package one or more key/value pairs.	
When creating a configmap based on a file, the key will default to the basename of the file, and the value will default	
to the file content.  If the basename is an invalid key, you may specify an alternate key.	
When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be	
packaged into the configmap.  Any directory entries except regular files are ignored (e.g. subdirectories, symlinks,	
devices, pipes, etc).	
Aliases:	
configmap, cm	
Examples:	# Create a new configmap named my-config based on folder bar	kubectl create configmap my-config --from-file=path/to/bar	# Create a new configmap named my-config with specified keys instead of file basenames on disk	kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt	# Create a new configmap named my-config with key1=config1 and key2=config2	kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2	# Create a new configmap named my-config from the key=value pairs in the file	kubectl create configmap my-config --from-file=path/to/bar	# Create a new configmap named my-config from an env file	kubectl create configmap my-config --from-env-file=path/to/bar.env

其中我们可以看到可以通过指定 --from-file来从指定文件创建。

kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt

Let's have a try!

1. 先行创建示例项目:dotnetnewmvc-n K8S.NETCore.ConfigMap

2. 默认包含两个配置文件 appsettings.jsonappsettings.Development.json640?wx_fmt=png

3. 先来尝试将 appsettings.json转换为ConfigMap:

> cd K8S.NETCore.ConfigMap	
# 创建一个namespace,此步可选	
> kubectl create namespace demo	
namespace "demo" created	
# -n变量指定configmap创建到哪个namespace下	
> kubectl create configmap appsettings --from-file=appsettings.json=./appsettings.json -n demo	
configmap "appsettings" created	
# 查看刚刚创建的configmap,-o指定输出的格式	
> kubectl get configmap appsettings -n demo -o yaml	
apiVersion: v1	
data:	appsettings.json: "{\r\n  \"Logging\": {\r\n    \"LogLevel\": {\r\n      \"Default\":	\"Warning\"\r\n    }\r\n  },\r\n  \"AllowedHosts\": \"*\"\r\n}\r\n"	
kind: ConfigMap	
metadata:	creationTimestamp: null	name: appsettings	namespace: demo

从上面的输出结果来看,其中包含了 \r\n换行符,显然不是我们想要的结果。猜测是因为Windows和Linux系统换行符的差异导致的。先来插播下换行符的知识:

CR:Carriage Return,对应ASCII中转义字符\r,表示回车 LF:Linefeed,对应ASCII中转义字符\n,表示换行 CRLF:Carriage Return & Linefeed,\r\n,表示回车并换行 众所周知,Windows操作系统采用两个字符来进行换行,即CRLF;Unix/Linux/Mac OS X操作系统采用单个字符LF来进行换行;

所以解决方式就很简单,将换行符切换为Linux系统的 \n即可。操作方式很简单:对于VS Code 只需要按图下所示操作即可,点击右下角的 CRLF,选择 LF即可。640?wx_fmt=png

对于VS,如果VS打开json文件有下面的提示,直接切换就好。没有,可以安装Line Endings Unifier)扩展来统一处理。640?wx_fmt=png

# 先删除之前创建的configmap	
> kubectl delete configmap appsettings -n demo	
> kubectl create configmap appsettings --from-file=appsettings.json=./appsettings.json -n demo	
configmap "appsettings" created	
> kubectl get configmap appsettings -n demo -o yaml	
apiVersion: v1	
data:	appsettings.json: |	{	"Logging": {	"LogLevel": {	"Default": "Warning"	}	},	"AllowedHosts": "*"	}	
kind: ConfigMap	
metadata:	creationTimestamp: null	name: appsettings	namespace: demo

现在ConfigMap的格式正常了。下面我们尝试把 appsettings.Development.json也合并到一个ConfigMap中。

> kubectl delete configmap appsettings -n demo	
> kubectl create configmap appsettings --from-file=appsettings.json=./appsettings.json --from-file=appsettings.Development.json=./appsettings.Development.json -n demo	
configmap "appsettings" created	
> kubectl get configmap appsettings -n demo -o yaml	
apiVersion: v1	
data:	appsettings.Development.json: |	{	"Logging": {	"LogLevel": {	"Default": "Debug",	"System": "Information",	"Microsoft": "Information"	}	}	}	appsettings.json: |	{	"Logging": {	"LogLevel": {	"Default": "Warning"	}	},	"AllowedHosts": "*"	}	
kind: ConfigMap	
metadata:	creationTimestamp: null	name: appsettings	namespace: demo

PS:

  1. 如果你的配置文件包含多余的空格,则生成的ConfigMap可能就会包含 \n字符,就像这样: appsettings.Development.json:"{\n \"Logging\": {\n \"LogLevel\": {\n \"Default\": \"Debug\",\n \"System\": \"Information\",\n \"Microsoft\": \"Information\"\n \ }\n }\n} \n"。解决办法就是保存文件时记得格式化文件就好了,或者手动删除多余空格。

  2. 创建ConfigMap的时候可以指定 --dry-run参数进行试运行,避免直接创建到服务器。

  3. 从文件创建ConfigMap时,可以不指定Key,默认会以文件名为Key。kubectl create configmap appsettings--from-file=./appsettings.json--from-file=./appsettings.Development.json-n demo--dry-run-o yaml

至此,完成了appsetting到configmap的切换。

应用 ConfigMap

ConfigMap的应用很简单,只需要将configmap挂载到容器内的独立目录即可。

先来看一下借助VS帮生成的Dockerfile。

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS base	
WORKDIR /app	
EXPOSE 80	
EXPOSE 443	
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build	
WORKDIR /src	
COPY ["K8S.NETCore.ConfigMap.csproj", ""]	
RUN dotnet restore "./K8S.NETCore.ConfigMap.csproj"	
COPY . .	
WORKDIR "/src/."	
RUN dotnet build "K8S.NETCore.ConfigMap.csproj" -c Release -o /app	
FROM build AS publish	
RUN dotnet publish "K8S.NETCore.ConfigMap.csproj" -c Release -o /app	
FROM base AS final	
WORKDIR /app	
COPY --from=publish /app .	
ENTRYPOINT ["dotnet", "K8S.NETCore.ConfigMap.dll"]

可以看出文件中定义的 WORKDIR/app指定的工作目录为 /app,所以需要把ConfigMap挂载到 /app目录下。先执行 docker build-t k8s.netcore.configmap:dev. 构建镜像。

我们来新建一个 configmap-deploy.yaml文件配置如下:

apiVersion: extensions/v1beta1	
kind: Deployment	
metadata:	name: k8s-configmap-demo	
spec:	selector:	matchLabels:	app: k8s-configmap-demo	template:	metadata:	labels:	app: k8s-configmap-demo	spec:	containers:	- name: k8s-configmap-demo	image: k8s.netcore.configmap:dev	imagePullPolicy: IfNotPresent	resources:	limits:	memory: "128Mi"	cpu: "500m"	ports:	- containerPort: 80	volumeMounts:	- mountPath: /app/appsettings.json	name: test	readOnly: true	subPath: appsettings.json	- mountPath: /app/appsettings.Development.json	name: test	readOnly: true	subPath: appsettings.Development.json	volumes:	- configMap:	defaultMode: 420	name: appsettings	name: test

这里有必要解释两个参数:

  1. volumes:-configMap:指定引用哪个ConfigMap

  2. volumeMounts:用来指定将ConfigMap中的配置挂载到容器的哪个路径

  3. subPath:用来指定引用ConfigMap的哪个配置节点。

创建Deployment之前先修改下ConfigMap的配置,以方便确认最终成功从ConfigMap挂载配置。将 Logging:LogLevel:Default:节点的默认值改为Error。

> kubectl edit configmap appsettings -n demo	
configmap/appsettings edited	
> kubectl get cm appsettings -n demo -o yaml	
apiVersion: v1	
data:	appsettings.Development.json: |-	{	"Logging": {	"LogLevel": {	"Default": "Error",	"System": "Information",	"Microsoft": "Information"	}	}	}	appsettings.json: |	{	"Logging": {	"LogLevel": {	"Default": "Error"	}	},	"AllowedHosts": "*"	}	
kind: ConfigMap	
metadata:	creationTimestamp: "2019-09-02T22:50:14Z"	name: appsettings	namespace: demo	resourceVersion: "445219"	selfLink: /api/v1/namespaces/demo/configmaps/appsettings	uid: 07048d5a-cdd4-11e9-ad6d-00155d3a3103

修改完毕后,执行后续命令来创建Deployment,并验证。

# 创建deployment	
> kubectl apply -f .\k8s-deploy.yaml -n demo	
deployment.extensions/k8s-configmap-demo created	
# 获取创建的pod	
> kubectl get pods -n demo	
NAME                                  READY   STATUS    RESTARTS   AGE	
k8s-configmap-demo-7cfbdfff67-xdrcx   1/1     Running   0          12s	
# 进入pod内部	
> kubectl exec -it k8s-configmap-demo-7cfbdfff67-xdrcx /bin/bash -n demo	
root@k8s-configmap-demo-7cfbdfff67-xdrcx:/app# cat appsettings.json	
{	"Logging": {	"LogLevel": {	"Default": "Error"	}	},	"AllowedHosts": "*"	
}	
root@k8s-configmap-demo-7cfbdfff67-xdrcx:/app# cat appsettings.Development.json	
{	"Logging": {	"LogLevel": {	"Default": "Error",	"System": "Information",	"Microsoft": "Information"	}	}	
}

从以上输出可以看出,默认的配置项已被ConfigMap的配置覆盖。

热更新

以Volume方式挂载的ConfigMap支持热更新(大概需要10s左右)。但一种情况例外,就是指定subPath的情况下,更新ConfigMap,容器中挂载的ConfigMap是不会自动更新的。

 A container using a ConfigMap as a subPath volume will not receive ConfigMap updates.

对于这种情况,也很好处理,将ConfigMap挂载到 /app目录下一个单独目录就好,比如挂载到 /app/config目录,然后修改配置文件的加载路径即可。

hostBuilder.ConfigureAppConfiguration((context, builder) =>	
{	builder.SetBasePath(Path.Join(AppContext.BaseDirectory, "config"))	.AddJsonFile("appsettings.json")	.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", true, true);	
});

最后

本文就.NET Core如何应用ConfigMap进行了详细的介绍。其中最关键在于appsettings.json到ConfigMap的转换,以及挂载目录的指定。希望对你有所帮助。而至于Secret的应用,原理相通了,关键在于Secret的生成,这里就交给你自己探索了。

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019-03-22-算法-进化(环形链表)

题目描述 给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 示例 1: 输入&#xf…

ASP.NET Core on K8S深入学习(9)Secret Configmap

本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。01—Secret关于Secret在应用启动过程中需要一些敏感信息,比如数据库用户名、密码,如果直接明文存储在容器镜像中是不安全的,K8S提供…

.NET Core 学习资料精选:进阶

2019.09月就要正式发布.NET 3.0了,对于前一篇博文《.NET Core 学习资料精选:入门》大家学的可还开心?这是本系列的第二篇文章:进阶篇,喜欢的园友速度学起来啊。对于还在使用传统.NET Framework 框架的园友,…

VS Code 1.38 发布!

今天(北京时间 2019 年 9 月 5 日),微软发布了 Visual Studio Code 1.38 版本。此版本主要更新的内容包括:Preserve case for global search and replace - 进行全局替换字符串时保留大小写。Settings editor string array valida…

.NET Core 收徒,有缘者,可破瓶颈

最近感悟天命,偶有所得,故而打算收徒若干,以继吾之传承。有缘者,可破瓶颈,职场巅峰指日可待。入门基本要求:1、工作经验:1年或以上。2、拜师费用:3999元(RMB)…

【全】Docker(二)-在Docker中部署Nginx实现负载均衡视频教程

一、前言在前面的文章中我们已经介绍了如何在Centos7系统中安装Docker以及利用Docker进行Asp.Net Core应用的部署。在本文中,我们将继续介绍利用Docker部署Nginx服务实现负载均衡。文章最后附有Nginx部署的视频全过程。注:查看公众号历史文章&#xff0c…

开源导入导出通用库Magicodes.ExporterAndImporter发布

导入导出通用库 Magicodes.ExporterAndImporter为心莱团队封装的导入导出通用库,并且仍在跟随项目不断地打磨。GitHub地址:https://github.com/xin-lai/Magicodes.ExporterAndImporter目录特点相关官方Nuget包导出 Demo普通导出特性导出列头处理或者多语…

netcore 中的动态代理与RPC实现(微服务专题)

一、关于RPC的调用1. 调用者(客户端Client)以本地调用的方式发起调用;  2. Client stub(客户端存根)收到调用后,负责将被调用的方法名、参数等打包编码成特定格式的能进行网络传输的消息体; …

[翻译] .NET Core 3.0 Preview 9 发布

原文: Announcing .NET Core 3.0 Preview 9今天,我们宣布推出 .NET Core 3.0 Preview 9。就像 Preview 8 一样,我们专注于打磨 .NET Core 3.0 的最终版本,而不是添加新功能。如果这些最终版本看起来不像早期预览版那么令人兴奋,我…

谈谈“学习”这件事儿

曾经有童鞋在我博客留言:楼主你是如何学习的,肿么那么牛逼(注:真不牛逼,只不过我讲的你刚好不知道,在你心中就形成了好牛逼的样子)曾经也有童鞋加我好友,开头第一句则是:…

持续集成之应用k8s自动部署

持续集成之应用k8s自动部署Intro上次我们提到了docker容器化及自动化部署[1],这仅仅适合个人项目或者开发环境部署,如果要部署到生产环境,必然就需要考虑很多因素,比如访问量大了如何调整部署,如何更好的应对大并发的情…

持续集成之应用容器化及自动化部署

通过 Azure Pipelines 实现持续集成之docker容器化及自动化部署IntroAzure DevOps Pipeline 现在对于公开的项目完全免费,这对于开源项目来讲无疑是个巨大的好消息,在 Github 的 Marketplace 里有个 Azure Pipeline,就是微软的 Azure DevOps …

持续集成之 Nuget 进阶

持续集成之 Nuget 进阶Intro之前介绍了一篇基于 Azure pipeline 的 nuget 包的持续集成配置,但是比较粗糙,这里介绍一下结合 Cake 实现更优雅的 nuget 包发布流程。实现目标:分支(除master/preview)有代码 push 或者 pr 时 自动 buildpreview…

做“是非题”的正确姿势

这里是Z哥的个人公众号每周五11:45 按时送达有时也会有感而发,来加个餐~我的第「107」篇原创敬上大家好,我是Z哥。这两天中国男篮的事,让我有感而发。不知道你有没有留意到,我们身边总有类似下面这样的事情…

依赖倒置原则(DIP)、控制反转(IoC)、依赖注入(DI)(C#)

象的控制权交由配置文件控制,然后根据配置文件中的信息(程序集类型),通过反射来获取对象,而不是直接new对象,这也是控制反转的一种体现。IoC容器会连接程序中的所有模块,模块将所需对象的控制权…

四种为HttpClient添加默认请求报头的解决方案

HttpClient在Web调用中具有广泛的应用,而为它添加默认请求头是我们经常遇到的需求,本文介绍4种为HttpClient添加默认请求头的方式。直接在创建的HttpClient对象的DefaultRequestHeaders集合中添加报头。class Program{static Task Main()> SendAsync…

【盛派内部分享资料】本期主题:使用JavaScript HTML CSS构建跨平台桌面应用

先上录制视频友情提示:如果公众号内视频无法显示高清视频,您也可以在小程序内观看高清视频,点击下方按钮观看:【盛派内部分享资料】本期主题:使用JavaScript HTML CSS构建跨平台桌面应用本次活动由盛派技术人员伏允坤主…

负载均衡及负载均衡器

负载均衡在分布式系统中,负载均衡(load balancing)是一种有效的将网络请求分配到多个服务器的过程。通过将负载进行负载均衡,可以有效地改进系统响应时间,提高系统的可用性。随着系统变的愈发复杂,用户增多…

VS Code 摸鱼插件开发小记

插件地址:https://marketplace.visualstudio.com/items?itemNamebugbreeder.vscode-readhub原文链接:https://github.com/alex-yh99/vscode-readhub/blob/master/docs/develop-note.md一、关于插件在 VSCode 中快捷查阅科技动态、开发者资讯等 Readhub …

9月数据库排行:Microsoft SQL Server分数罕见下滑

DB-Engines 数据库流行度排行榜 9 月更新已发布,排名前二十如下:明显能看出来,整体排名和上个月的保持一致。而上个月出现分数下跌的 PostgreSQL 和 MongoDB 终于“回归正道”,分数有了稍微的上升。与上个月相比,Postg…