kubernetes之十: ConfigMap
什么是ConfigMap
1 | ConfigMap是用来存储配置文件的Kubernetes的资源对象,配置对象存储在Etcd中,配置的形式可以是完整的配置文件或者key /value 的形式 |
ConfigMap可以带来什么好处
1 | 传统的应用服务,每个服务都有自己的配置文件,各自配置文件存储在服务所在节点,对于单体应用,这种存储没有任何问题,但是随着用户数量的激增,一个节点不能满足线上用户使用,故服务可能从一个节点扩展到十个节点,这就导致,如果有一个配置出现变更,就需要对应修改十次配置文件。这种人肉处理,显然不能满足线上部署要求,故引入了各种类似于 ZooKeeper 中间件实现的配置中心,但配置中心属于 “侵入式” 设计,需要修改引入第三方类库,它要求每个业务都调用特定的配置接口,破坏了系统本身的完整性,而Kubernetes 利用了 Volume 功能,完整设计了一套配置中心,其核心对象就是ConfigMap,使用过程不用修改任何原有设计,即可无缝对 ConfigMap;为什么呢? |
使用configmap的限制条件
1 2 3 4 5 6 7 8 9 10 11 12 13 | ConfigMap必须在Pod之前创建 ConfigMap受Namespace限制,只有处于相同Namespace中的Pod才可以引用它。 ConfigMap中的配额管理还未能实现。 kubelet只支持可以被API Server管理的Pod使用ConfigMap kubelet在本Node上通过 --manifest-url或–config自动创建的静态Pod将无法引用ConfigMap。 在Pod对ConfigMap进行挂载(volumeMount)操作时,在容器内部只能挂载为“目录”,无法挂载为“文件”,在挂载到容器内部后,在目录下将包含ConfigMap定义的每个item,如果在该目录下原来还有其他文件,则容器内的该目录将被挂载的ConfigMap覆盖 如果应用程序需要保留原来的其他文件,则需要进行额外的处理。可以将ConfigMap挂载到容器内部的临时目录,再通过启动脚本将配置文件复制或者链接到( cp 或link命令)应用所用的实际配置目录下 |
ConfigMap 三种创建方式
第一种方式: 指定字面量进行创建,创建命令如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 | kubectl create configmap configmaptest --from-literal=foo=bar --from-literal=one=two [root@master01 ~] # kubectl get configmap configmaptest -o yaml apiVersion: v1 data: foo: bar one: two kind: ConfigMap metadata: name: configmaptest namespace: default |
第二种方式: 指定特定文件进行创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | [root@master01 template] # cat db.properties driverClassName=com.mysql.jdbc.Driver kubectl create configmap config-files --from- file = /data/k8s/template/db .properties [root@master01 template] # kubectl get configmap config-files -o yaml apiVersion: v1 data: db.properties: | driverClassName=com.mysql.jdbc.Driver kind: ConfigMap metadata: creationTimestamp: "2020-08-12T13:52:35Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:db.properties: {} manager: kubectl operation: Update time : "2020-08-12T13:52:35Z" name: config-files namespace: default resourceVersion: "491983" selfLink: /api/v1/namespaces/default/configmaps/config-files uid: bfeacb89-fdd7-41d7-8089-ce1a1629b102 You have new mail in /var/spool/mail/root |
第三种: 指定特定文件夹进行创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | kubectl create configmap config- dir --from- file = /data/k8s/template/config/ [root@master01 ~] # kubectl get configmap config-dir -o yaml apiVersion: v1 data: db.properties: | driverClassName=com.mysql.jdbc.Driver svc.properties: | #server protocol=tcp system.properties: | time =100 kind: ConfigMap metadata: name: config- dir namespace: default |
ConfigMap 作为环境变量三种使用方式
1、单个引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 先创建configmap kubectl create configmap configmaptest --from-literal=code=25 --from-literal=foo=bar --from-literal=one=two spec: containers: - name: demo-nginx image: nginx imagePullPolicy: IfNotPresent env : - name: CODE-TIME ( env 变量名) valueFrom: configMapKeyRef: name: configmaptest (configmap的名称) key: code (定义的key)验证 |
[root@master01 template]# kubectl exec -it demo-nginx-55485d6b97-7wzhq -- /bin/bash
root@demo-nginx-55485d6b97-7wzhq:/# env|grep CO
CODE-TIME=25
2)多个引用
一次性传递所有ConfigMap条目作为环境变量
1 2 3 4 5 6 7 8 9 10 11 12 13 | spec: containers: - name: demo-nginx image: nginx imagePullPolicy: IfNotPresent envFrom: - prefix: CODE_ #以CODE前缀 configMapRef: name: configmaptest #configmap名称 ports: - name: http containerPort: 80验证 |
[root@master01 template]# kubectl exec -it demo-nginx-6b8dcf7d4f-xzhgk -- /bin/bash
root@demo-nginx-6b8dcf7d4f-xzhgk:/# env|grep CO
CODE_code=25
CODE_one=two
CODE_foo=bar
3) args 方式传递环境变量
容器启动时,传递该变量到服务,运行 shell 脚本,可能会用到,具体设置方式如图(5)所示
1 2 3 4 5 6 7 8 9 10 11 12 | spec: containers: - name: demo-nginx image: nginx imagePullPolicy: IfNotPresent env : - name: CONFIG valueFrom: configMapKeyRef: name: configmaptest key: code args: [ "$(CONFIG)" ] |
4)volume挂载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ...... - containerPort: 80 volumeMounts: - mountPath: /usr/local/nginx/conf/vhost/ name: http - mountPath: /usr/local/nginx/html/foo subPath: foo name: nginx-html volumes: - name: http configMap: name: nginx-conf - name: nginx-html configMap: name: configmaptest items: - key: foo path: foo ......<br><br>如果有特定需求,需要挂载某个特定文件,而不允许覆盖原有文件,可以挂载到指定文件,通过 subPath 配合指定文件。<br>但是单个文件挂载这种方式不能实现热更新,即宿主机 ConfigMap 文件发生变化,容器内部不会自动重载<br><br>至于 items 使用就比较简单了,如果一个 ConfigMap 中包含多个配置文件,但是只想暴露出来其中一部分<br>那么可以通过 items 方式进行指定。当然你也可以对文件设置读写权限 |
像下面的LAMP,可以将同一个volume下的 mysql 和 html目录,挂载到不同的挂载点上,这样就不需要为 mysql 和 html 单独创建volume了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | apiVersion: v1 kind: Pod metadata: name: my-lamp-site spec: containers: - name: mysql image: mysql env : - name: MYSQL_ROOT_PASSWORD value: "rootpasswd" volumeMounts: - mountPath: /var/lib/mysql name: site-data subPath: mysql - name: php image: php:7.0-apache volumeMounts: - mountPath: /var/www/html name: site-data subPath: html volumes: - name: site-data persistentVolumeClaim: claimName: my-lamp-site-data |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | apiVersion: v1kind: Pmetadata: name: pod-volume- test spec: containers: - name: apache image: httpd ports: - containerPort: 80 volumeMounts: - name: volume- test mountPath: /var/www/html volumes: - name: volume- test configMap: name: cm-apache items: - key: html path: main.html #文件名 - key: path path: path.txt #文件名 验证: root@pod-volume- test :/ # cd /var/www/html/ root@pod-volume- test : /var/www/html # ls main.html path.txt root@pod-volume- test : /var/www/html #cat main.html hello world root@pod-volume- test : /var/www/html # cat path.txt /var/www/html |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: busybox args: [ "/bin/sh" , "-c" , "sleep 3000" ] volumeMounts: - name: mysql mountPath: "/tmp" volumes: - name: mysql configMap: name: mysql-cm items: - key: my.cnf path: mysql /my .cnf 验证 [root@master ~] # kubectl exec -it mypod sh / # cat /tmp/mysql/my.cnf [mysqld] datadir= /var/lib/mysql socket= /var/lib/mysql/mysql .sock symbolic-links=0 [mysqld_safe] log-error= /var/log/mariadb/mariadb .log pid- file = /var/run/mariadb/mariadb .pid !includedir /etc/my .cnf.d / # exit |
热更新机制
当 ConfigMap 作为 Volume 进行挂载时,它的内容是会更新的。分析 ConfigMap volume 的更新机制:
1 2 3 4 5 6 | 更新操作由 kubelet 的 Pod 同步循环触发,每次进行 Pod 同步时(默认每 10 秒一次),kubelet 都会将 Pod 的所有 ConfigMap Volume 标记为“需要重新挂载<br>(RequireRemount)”,而 kubelet 中的 Volume 控制循环会发现这些需要重新挂载的 Volume,去执行一次挂载操作,在 ConfigMap 的重新挂载过程中,kubelet <br>会先比较远端的 ConfigMap 与 Volume 中的 ConfigMap 是否一致,再做更新。要注意,“拿远端的 ConfigMap” 这个操作可能是有缓存的,因此拿到的并不一定是最新版本。 <br>延迟时间:Pod 同步间隔(默认10秒)+ ConfigMap 本地缓存的 TTL。 |
部分文件挂载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | apiVersion: v1 kind: Pod metadata: labels: name: busybox role: master name: busybox spec: containers: - name: busybox image: myhub.fdccloud.com /library/busybox command : - sleep - "3600" volumeMounts: - name: configmap-volume mountPath: /etc/passwd subPath: path /to/passwd - name: configmap-volume-1 mountPath: /etc/group subPath: path /to/group nodeSelector: app: busybox volumes: - name: configmap-volume configMap: name: cmtest items: - key: passwd path: path /to/passwd - name: configmap-volume-1 configMap: name: cmtest items: - key: group path: path /to/group |
分类:
Kubernetes
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 20250116 支付宝出现重大事故 有感
· 一个基于 Roslyn 和 AvalonEdit 的跨平台 C# 编辑器
· 推荐一款非常好用的在线 SSH 管理工具
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· .NET周刊【1月第1期 2025-01-05】