configMap挂载配置文件
在 Kubernetes 中,可以使用 ConfigMap 来存储应用程序的配置信息,例如环境变量、配置文件等。
ConfigMap 可以被挂载到容器内部的指定路径下,从而方便应用程序读取和使用配置信息。
假如业务应用有一个配置文件,名为 application.yml,如果想将此配置挂载到pod的/etc/application/目录中。
--from-file
application.yml的内容为:
spring:
application:
name: svca-service
cloud:
config:
uri: http://config:8888
fail-fast: true
username: user
password: ${CONFIG_SERVER_PASSWORD:password}
retry:
initial-interval: 2000
max-interval: 10000
multiplier: 2
max-attempts: 10
该配置文件在k8s中可以通过configmap来管理,通常我们有如下两种方式来管理配置文件:
通过kubectl命令行来生成configmap
# 通过文件直接创建
$ kubectl -n default create configmap application-config --from-file=application.yml
# 会生成配置文件,查看内容
$ kubectl -n default get cm application-config -oyaml
yml创建cm
技巧是你可以直接基于上述的configmap,获取到yaml
apiVersion: v1
data:
# 这里key,作为挂载后的文件名字
application.yaml: |
spring:
application:
name: svca-service
cloud:
config:
uri: http://config:8888
fail-fast: true
username: user
password: ${CONFIG_SERVER_PASSWORD:password}
retry:
initial-interval: 2000
max-interval: 10000
multiplier: 2
max-attempts: 10
kind: ConfigMap
metadata:
name: application-config
namespace: yuchao
# [root@k8s-master ~/efk-all]#kubectl -n yuchao get cm -oyaml
创建pod挂载cm
Demo-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: yuchao
spec:
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
volumes:
- configMap: # pod使用configmap
name: application-config
name: config
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
volumeMounts: # 容器挂载configmap
- mountPath: "/etc/application"
name: config
创看容器内是否挂载了配置文件
注意,容器内配置文件的名字,以cm的key作为文件名
[root@k8s-master ~/efk-all]#
[root@k8s-master ~/efk-all]#kubectl apply -f demo-deployment.yml
deployment.apps/demo created
[root@k8s-master ~/efk-all]#kubectl -n yuchao exec -it demo-6f8f6967d7-pwl8g -- sh
/ # ls /etc/application/
application.yaml
/ # cat /etc/application/application.yaml
spring:
application:
name: svca-service
cloud:
config:
uri: http://config:8888
fail-fast: true
username: user
password: ${CONFIG_SERVER_PASSWORD:password}
retry:
initial-interval: 2000
max-interval: 10000
multiplier: 2
max-attempts: 10
动态修改配置文件
外部修改配置文件,查看pod内挂载cm的配置文件情况
[root@k8s-master ~/efk-all]#grep chaoge application.yaml
username: chaoge
[root@k8s-master ~/efk-all]#kubectl apply -f application.yaml
configmap/application-config configured
动态pod内的配置更新
[root@k8s-master ~/efk-all]#kubectl -n yuchao exec -it demo-6f8f6967d7-pwl8g -- sh
/ # cat /etc/application/application.yaml
spring:
application:
name: svca-service
cloud:
config:
uri: http://config:8888
fail-fast: true
username: chaoge
password: ${CONFIG_SERVER_PASSWORD:password}
retry:
initial-interval: 2000
max-interval: 10000
multiplier: 2
max-attempts: 10
/ #
生产用法
当 ConfigMap 的内容发生变化时,Kubernetes 会自动更新 Pod 内部挂载的 ConfigMap 文件,并且通知到 Pod 中的容器。
但是容器内的进程不会自动重启,因此需要通过特定的方式来让应用程序重新加载最新的配置信息。
一种常见的做法是,为应用程序提供一个内部的 Reload 接口,可以通过该接口来触发应用程序重新加载最新的配置信息。当 ConfigMap 发生变化时,Kubernetes 可以使用 livenessProbe 或 readinessProbe 检查容器的健康状态,并在容器状态发生变化时执行特定的操作。
例如,可以在 livenessProbe 或 readinessProbe 中定义一个 HTTP 接口,用于检查应用程序是否处于正常运行状态。当 ConfigMap 发生变化时,Kubernetes 会重新调用该接口,如果应用程序返回了特定的响应码(例如 503),则 Kubernetes 认为应用程序需要重新加载最新的配置信息,并且会发送 SIGTERM 信号给容器内的进程,让它们自动重启。当进程重新启动后,应用程序会重新加载最新的配置信息,并且继续运行。
需要注意的是,为了避免应用程序重启带来的不必要的延迟和资源消耗,可以使用一些优化手段来降低重启的频率,例如增加缓存、使用热更新等方式。同时,在应用程序中也应该处理好配置变化的异常情况,例如配置文件格式错误、配置文件缺失等情况,以确保应用程序可以在不间断服务的情况下加载最新的配置信息。
多配置文件挂载
在 Kubernetes 中,ConfigMap 是一种存储非机密数据的对象,例如配置文件、环境变量等。ConfigMap 可以通过多种方式来创建,其中一种方式是使用 kubectl create configmap 命令,并通过 --from-file 标志来指定配置文件路径。
当使用 --from-file 标志创建 ConfigMap 时,kubectl 会读取指定的文件并将其内容存储为键值对。
对于 conf 文件或 YAML 文件,kubectl 会将整个文件内容作为一个字符串存储为 ConfigMap 的值,并以文件名作为键。
假如有多个配置文件,都需要挂载到pod内部,且都在一个目录中。多次--from-file即可
$ cat application.yml
spring:
application:
name: svca-service
cloud:
config:
uri: http://config:8888
fail-fast: true
username: user
password: ${CONFIG_SERVER_PASSWORD:password}
retry:
initial-interval: 2000
max-interval: 10000
multiplier: 2
max-attempts: 10
$ cat supervisord.conf
[unix_http_server]
file=/var/run/supervisor.sock
chmod=0700
[supervisord]
logfile=/var/logs/supervisor/supervisord.log
logfile_maxbytes=200MB
logfile_backups=10
loglevel=info
pidfile=/var/run/supervisord.pid
childlogdir=/var/cluster_conf_agent/logs/supervisor
nodaemon=false
创建多个文件的configmap
kubectl -n yuchao create cm application-config --from-file=application.yaml --from-file=supervisord.conf
# check
[root@k8s-master ~/efk-all]#kubectl -n yuchao get cm application-config -oyaml
# 查看pod是否自动更新配置
[root@k8s-master ~/efk-all]#kubectl -n yuchao exec -it demo-6f8f6967d7-pwl8g -- sh
/ # ls /etc/application/
application.yaml supervisord.conf
负载挂载已存在的目录
上述configmap挂载的/etc/application/是新目录,会自动创建。
例如我们挂载给系统自带的,如/etc/nginx/conf.d此类目录,就会隐藏源目录文件。
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: yuchao
spec:
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
volumes:
- configMap: # pod使用configmap
name: application-config
name: config
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
volumeMounts: # 容器挂载configmap
- mountPath: "/etc/profile.d/"
name: config
重建pod
[root@k8s-master ~/efk-all]#kubectl apply -f demo-deployment.yml
deployment.apps/demo configured
[root@k8s-master ~/efk-all]#kubectl -n yuchao exec demo-56fb5f4c9-lrmtx ls /etc/profile.d
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
application.yaml
supervisord.conf
很明显,这个挂载方式不合理,因此还有subPath用法。
subPath挂载子路径
在 Kubernetes 中,ConfigMap 是一种用于存储非机密数据的 Kubernetes 对象。ConfigMap 通常用于存储应用程序的配置信息,比如环境变量、命令行参数等。
ConfigMap 可以通过挂载 Volume 或设置环境变量的方式将配置信息传递给容器。其中,subPath 是用于指定 ConfigMap 某个特定键值对的值的路径。
subPath 的作用是将 ConfigMap 中的某个特定键值对的值作为文件挂载到容器中的指定路径上。这使得容器可以直接访问该文件,而不需要将整个 ConfigMap 挂载为一个 Volume。
例如,假设 ConfigMap 中有一个名为 my-config 的键值对,值为 "hello world",使用 subPath 可以将该键值对的值作为文件挂载到容器的 /etc/my-app/config.txt 路径上,而不是将整个 ConfigMap 挂载为 Volume。
案例
实现多个配置文件,可以挂载到pod内的不同的目录中。比如:
application.yml挂载到/etc/application/
supervisord.conf挂载到/etc/profile.d
configmap保持不变,修改deployment文件:
修改deployment.yaml挂载参数
$ cat demo-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: yuchao
spec:
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
volumes:
- name: config
configMap:
name: application-config
items:
- key: application.yaml
path: application
- key: supervisord.conf
path: supervisord
containers:
- name: nginx
image: nginx:alpine
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: "/etc/application/application.yaml"
name: config
subPath: application
- mountPath: "/etc/profile.d/supervisord.conf"
name: config
subPath: supervisord
在这个Deployment中,items和subPath是用来指定如何将ConfigMap中的数据挂载到容器中的特定文件路径的。
items字段指定了要挂载到容器中的ConfigMap中的数据项的列表。每个项都有一个key字段和一个path字段。key指定了ConfigMap中的数据项的名称,path指定了该数据项将被挂载到容器的哪个路径。
在这个示例中,items字段包含了两个项:application.yml和supervisord.conf。它们分别被挂载到了容器中的/etc/application/application.yml和/etc/profile.d/supervisord.conf路径。
subPath字段用于指定要将ConfigMap中的哪个数据项挂载到容器中的特定文件。在这个示例中,容器中有两个文件要被挂载:application.yml和supervisord.conf,它们分别使用了subPath字段来指定对应的数据项。具体来说,/etc/application/application.yml文件的数据来自application.yml数据项,/etc/profile.d/supervisord.conf文件的数据来自supervisord.conf数据项。
测试挂载
[root@k8s-master ~/efk-all]#kubectl -n yuchao delete deployments.apps demo
deployment.apps "demo" deleted
[root@k8s-master ~/efk-all]#
[root@k8s-master ~/efk-all]#
[root@k8s-master ~/efk-all]#kubectl apply -f demo-deployment.yml
deployment.apps/demo created
[root@k8s-master ~/efk-all]#kubectl -n yuchao exec demo-85cdd494c-8tcfn -- ls /etc/application
application.yaml
[root@k8s-master ~/efk-all]#kubectl -n yuchao exec demo-85cdd494c-8tcfn -- ls /etc/profile.d/
README
color_prompt.sh.disabled
locale.sh
supervisord.conf
这样就不会覆盖原有的文件系统,单独挂载配置文件了。
但是注意,使用subPath挂载到Pod内部的文件,不会自动感知原有ConfigMap的变更。