文章将会解决以下问题,欢迎点击右上角关注我。
1.如何对k8s的容器进行程序升级?
2.如何对k8s的容器进行配置修改?
上一篇中,我们提到,如果程序的配置信息变更,例如数据库地址变更,能不能再不重新构建镜像的基础上,直接更改容器的配置信息呢?
对的,是可以的!今天我来聊一聊k8s的ConfigMap。
k8s的ConfigMap产生的原因是希望程序和配置信息能隔离开来。这样的话,就能让容器动态部署到不同的环境(生产,测试,开发)。
我们原来讲过通过.net core 的配置文件和ASPNETCORE_ENVIRONMENT结合也可以实现多环境的部署,但是为了安全起见,我们不能在代码里面增加生产环境的配置信息,这样能看到代码的人,就能知道生产环境的账号,密码等敏感信息,泄露的风险很大。通过ConfigMap,我们同样能达到多环境的部署,而且可以尽量让少的人知道生产环境的配置信息。
ConfigMap有两种使用方式,一个是将数据设置成容器的环境变量,一个是使用Volume作为文件或者目录挂载。两种方式的区别在于,环境变量的方式不支持热更新。所以,这里我们使用Volume的方式来修改配置。
那这种方式到底是怎么样来实现对Pod里面.net core 程序配置文件进行覆盖的呢?我画了一张图:
k8s在调度Pod到集群的节点上时,会在这个Pod的宿主机上创建Volume目录(/var/lib/kubelet/pods/<PodID>/volumes/kubernetes.io~<VolumeType>/<VolumeName>),然后再启动Pod的容器。容器启动时,会根据volumeMounts里面的定义将宿主机目录下的部分卷资源挂载进去,这样就达到了覆盖容器内配置文件的目的。
我们先来直观的看一下configMap.yaml和deployment.yaml的文件,了解它们是如何关联起来的。
我们在configMap.yaml要更改ConfigMapsValue的值为"new value"。
---
kind: ConfigMap
apiVersion: v1
metadata:
name: mozhi-demo-config
namespace: mozhi-smartinvent
data:
appsettings.Development.json: |
{"ConfigMapsValue": "New Value"}
deployment.yaml创建一个名为mozhi-demo-volume的volume,并且使用名称mozhi-demo-config的ConfigMap。
spec:
containers:
volumeMounts:
- mountPath: /app/appsettings.Development.json
name: mozhi-demo-volume
readOnly: true
subPath: appsettings.Development.json
volumes:
- name: mozhi-demo-volume
configMap:
name: mozhi-demo-config
通过这个配置,k8s每次调度Pod到结点时,就会自动去更改容器程序里的ConfigMapsValue值。而不需要我们去重新构建镜像。
下面,我们来实际操作一下。刚来的小伙伴,如果不太清楚部署过程,可以先阅读这篇文章.net core 部署到k8s,这里有详细的部署步骤。
我们先来解决第1个问题,如何更新容器的程序?
上一节中,我们只有一个默认的接口,现在增加了一个接口,用来读取配置文件里面的ConfigMapsValue,配置文件中的原始值是"old value"。
代码修改完以后,我们重新上传到有docker环境的服务器,构建一个新的镜像,并给它打上Tag:v1.0.1。然后推送到我们的docker 私有仓库。
cd /root/Documents/mozhi/demo #切换到自己代码的目录
docker build -t mozhi/demo:v1.0.1 -f Dockerfile . --network host
docker login 192.168.41.147:5000 #登录docker私有仓库
docker tag mozhi/demo:v1.0.1 192.168.41.147:5000/demo:v1.0.1 #给镜像重新打标签
docker push 192.168.41.147:5001/demo:v1.0.1
如果我们不需要更改配置信息,我们只需要更改原来的deployment-demo.yaml文件,然后就可以直接执行命令,k8s就会删除原来的Pod,然后再创建新的Pod,并且会拉取新的v1.0.1的镜像。这样,我们就完成了程序的升级。
spec:
containers:
- name: mozhi-demo
image: 192.168.41.147:5000/demo:v1.0.1 #修改这里,其他地方不用动
ports:
- containerPort: 80
kubectl apply -f deployment-demo.yaml -n mozhi-smartinvent
下面我们来解决第2个问题,如何对k8s的容器进行配置修改
先创建一个configmap-demo.yaml文件。设置ConfigMapsValue的值为"New Value"。
---
kind: ConfigMap
apiVersion: v1
metadata:
name: mozhi-demo-config
namespace: mozhi-smartinvent
data:
appsettings.Development.json: |
{"Logging":{"LogLevel":{"Default":"Information","Microsoft":"Warning","Microsoft.Hosting.Lifetime":"Information"}},"ConfigMapsValue":"New Value"}
执行命令,可以看到提示我们已经创建成功了,我们登录到dashboard,就可以看到configmap的项目信息。
cd /root/Documents/mozhi/deployments
kubectl create -f configmap-demo.yaml
然后我们再修改deployment-demo.yaml部署文件,将刚才的configmap通过volume的方式挂载上去。
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: mozhi-demo
namespace: mozhi-smartinvent
labels:
name: mozhi-demo
spec:
replicas: 1
selector:
matchLabels:
name: mozhi-demo
template:
metadata:
labels:
name: mozhi-demo
spec:
containers:
- name: mozhi-demo
image: 192.168.41.147:5000/demo:v1.0.1
ports:
- containerPort: 80
env:
- name: ASPNETCORE_ENVIRONMENT
value: Development
imagePullPolicy: Always
volumeMounts:
- mountPath: /app/appsettings.Development.json
name: mozhi-demo-volume
readOnly: true
subPath: appsettings.Development.json
volumes:
- name: mozhi-demo-volume
configMap:
defaultMode: 420
name: mozhi-demo-config
imagePullSecrets:
- name: dockersecret
执行命令,然后通过curl访问我们的接口,验证是不是返回的new value。
kubectl apply -f deployment-demo.yaml -n mozhi-smartinvent #部署pod
kubectl get pods --all-namespaces -o wide #查看pod状态
curl http://192.168.41.147:30246/WeatherForecast/GetConfigMapsValue
通过截图,可以看到,我们部署的程序成功的返回了"New Value",实现了不重新构建镜像,就更改了程序的配置信息。
下一章,我会和大家聊一聊k8s的热更新,可以实现更改ConfigMap的信息时,自动触发容器的配置更新。欢迎大家关注我的账号,以便在第一时间获取推送。
如果你觉得我的文章还不错,欢迎关注,转发和评论。大家也可以在微信公众号搜索"墨汁软件"关注我哟!