作者设置:由于当前各个常用镜像站无法正常代理下载镜像,这篇实验中所用到的镜像建议先从网络下载获取再导入到私仓使用,
或私信后台回复:9521 获取~ ~
目录描述
- Kubernetes 常见的配置资源介绍
- ConfigMap 介绍说明
- ConfigMap 创建方式
- ConfigMap 使用方式
- ConfigMap实践案例
一. Kubernetes 常见的配置资源介绍
1.1 配置介绍
生产中所有的应用程序中,都涉及到配置文件,而配置文件经常会有变更,比如: 数据库连接,代码版本号,证书更新等
典型场景:项目经历开发环境、测试环境、预发布环境、线上环境才能完成发布,而每个环境都有定义其独立的各种配置,这些配置手工操作很繁杂,有一些流行的开源项目,比如: Apollo,Nacos,Consul等可以实现配置管理, 还有大公司专门开发了专用配置管理中心,如百度的disconf等。
为容器化应用提供配置信息方法
- 制作镜像时,提前将定义好的配置文件拷贝进镜像之中
- 制作镜像时,内置环境变量,在启动容器时通过环境变量向容器传递配置数据
- 启动容器时,基于存储卷向容器传递配置文件,但需要提前准备外部的存储
注意:对于运行容器中的配置改变,还需要通过应用程序重载相关配置才能生效
kubernetes
作为分布式容器调度平台,同样会遇到同样配置变更的问题,这时不可能把资源删除后,重新修改然后再启动生成,这种方法就太繁琐。
kubernetes提供了对pod
中容器应用的集中配置管理组件:ConfigMap
、Secret
、downwardAPI
。通过这些组件来实现向pod中的容器
注入配置信息
的机制。
1.2 配置组件简介
官方的配置组件简介说明https://kubernetes.io/zh-cn/docs/concepts/configuration/
https://kubernetes.io/zh-cn/docs/concepts/configuration/
1.2.1 Configmap
Configmap
是Kubernetes
集群中非常重要的一种配置管理资源对象。借助于ConfigMap API
向pod中的容器
注入配置信息的机制。
ConfigMap
不仅仅可以保存环境变量或命令行参数等属性,也可以用来保存整个配置文件或者JSON格式的文件。
各种配置属性和数据以 k/v
或嵌套k/v
样式 存在到Configmap
中
注意:所有的配置信息都是以明文的方式来进行传递,实现资源配置的快速获取或者更新。
1.2.2 Secret
在Kubernetes
集群中,有一些配置属性信息非常敏感,这些信息在传递的过程中,不希望外界能够接触的。所以,Kubernetes
提供了一种加密场景
中的配置管理资源对象Secret
。
它在进行数据传输之前,会对数据进行编码,在数据获取时,会对数据进行解码,从而保证整个数据传输过程的安全。
注意:这些数据是根据不同的应用场景,采用不同的加密机制。
1.2.3 downwardAPI
downwardAPI
为运行在pod中的应用容器提供了一种反向引用。让容器中的应用程序了解所处pod
或node
的一些基础属性信息。
从严格意义上来说,downwardAPI不是存储卷
,它自身就存在。相较于configmap
、secret
等资源对象需要创建后才能使用,而downwardAPI引用的是Pod自身的运行环境
,这些信息在Pod启动的时候就存在了
二、ConfigMap 介绍说明
Kubernetes
提供了对pod中容器应用的集中配置管理组件:ConfigMap
。通过ConfigMap
来实现、借助于ConfigMap API
向pod中容器中注入配置信息
的机制。
可以把configmap
理解为Linux系统中的/etc目录
,专门用来存储配置文件的目录。
Kubernetes借助于ConfigMap对象实现了将配置信息从容器镜像中解耦
,从而增强了工作负载的可移樟性、使其配置更易于更改和管理并避免了将配置数据硬编码到Pod配置清单中
注:ConfigMap不仅仅可以保存单个属性,也可以用来保存整个配置文件。
虽然configmap可以对各种应用程序提供定制配置服务,但是一般不用它来替代专门的配置文件,从Kubernetes v1.19
版本开始,ConfigMap
和Secret
支持使用immutable字段创建不可变实例。
Configmap 属于名称空间级别
基本属性:
root@master1ha1:~# kubectl explain cm binaryData #二进制数据 data #文本数据,支持变量和文件 immutable <boolean> #设为true,不能被修改只能删除,默认为nil可以随时被修改 #注意:基于data的方式传递信息的话,会在pod的容器内部生成一个单独的数据文件
数据的表现样式:
#简单数据: 属性名称key: 属性值value #单行配置内容,一般保存变量,参数等 文件名:单行内容 #配置文件如果有一行,也使用此方式,key为文件名,value为文件内容 #多行文件数据格式1: 文件名称1: | #注意:| 是"多行键值"的标识符 文件内容行1 #内容大小不能超过1M 文件内容行2 ...... 文件名称2: | #注意:| 是"多行键值"的标识符 文件内容行1 #内容大小不能超过1M 文件内容行2 ......
对于configmap
这种资源类型的创建,与Kubernetes
的其他资源对象的创建方式一样,主要涉及到两种方式:
- 命令行工具:配置中有大量简单的键值对时建议使用
- 资源定义文件:配置为大量文本内容时建议使用,此方式需要事先准备在资源清单元文件中加入配置文件内容
注意:
- 如果Pod是以
subPath
的形式挂载ConfigMap
和Secret
,那么Pod是不会感知到ConfigMap
和Secret
的更新。 - 如果
Pod 的变量
来自于ConfigMap
和Secret
中定义的内容,那么ConfigMap
和Secret
更新后,也不会更新Pod
中的变量。
三、ConfigMap 创建和更新
3.1 命令行创建方式
3.1.1 命令行创建方式说明
命令参数
#查看创建命令帮助 root@master1ha1:~# kubectl create configmap -h #参数详解: --from-literal=key1=value1 #以命令行设置键值对的方式配置数据 --from-env-file=/PATH/TO/FILE #以环境变量专用文件的方式配置数据 --from-file=[key=]/PATH/TO/FILE #以配置文件的方式创建配置数据,如不指定key,FILE名称 为key名 --from-file=/PATH/TO/DIR #以配置文件所在目录的方式创建配置数据 --dry-run=client -o yaml #测试运行并显示cm内容 #查看configmap kubectl create configmap <cm_name> -n <namespace> [-o yaml] --dry-run=client kubectl get configmap <cm_name> -n <namespace> kubectl describe configmap <cm_name> -n <namespace> #删除configmap kubectl delete configmap <cm_name> [-n <namespace>]
3.1.2 命令行创建方式案例
范例:命令行创建基于key:value
形式的CM
#在使用kubectl创建的时候,通过在命令行直接传递键值对创建 root@master1ha1:~# kubectl create configmap cm-test1 --from-literal=key1='value1' --from-literal=key2='value2' configmap/cm-test1 created root@master1ha1:~# kubectl get cm NAME DATA AGE cm-test1 2 11s kube-root-ca.crt 1 25d root@master1ha1:~# kubectl get cm cm-test1 -o yaml apiVersion: v1 data: key1: value1 key2: value2 kind: ConfigMap metadata: creationTimestamp: "2024-07-22T11:48:27Z" name: cm-test1 namespace: default resourceVersion: "139551" uid: fce0ffc0-2ad5-4b99-bdf5-a0f95882f19d root@master1ha1:~# kubectl describe cm cm-test1 Name: cm-test1 Namespace: default Labels: <none> Annotations: <none> Data ==== key1: ---- value1 key2: ---- value2 BinaryData ==== Events: <none> #删除CM root@master1ha1:~# kubectl delete cm cm-test1 configmap "cm-test1" deleted
范例: 命令行创建基于key/value
形式的CM
#创建CM root@master1ha1:~# kubectl create configmap pod-test-config --from-literal=host="127.0.0.1" --from-literal=port="8888" configmap/pod-test-config created #验证创建成功 root@master1ha1:~# kubectl get cm NAME DATA AGE kube-root-ca.crt 1 34d pod-test-config 2 18s #显示CM内容 root@master1ha1:~# kubectl get cm pod-test-config -o yaml apiVersion: v1 data: host: 127.0.0.1 port: "8888" kind: ConfigMap metadata: creationTimestamp: "2024-07-31T09:56:35Z" name: pod-test-config namespace: default resourceVersion: "161838" uid: 7b49ae67-4d64-4f2d-8c47-882c314f5ec7 #删除CM root@master1ha1:~# kubectl delete cm pod-test-config configmap "pod-test-config" deleted
范例: 命令行创建基于环境变量
文件的CM
#如果变量较多,使用上面方式一个个的设定环境变量太繁琐,可以全部添加到环境变量文件中然后基于它来创建CM。 #定制环境变量文件 root@master1ha1:~# cat > env key1=value1 key2=value2 ^C root@master1ha1:~# cat env key1=value1 key2=value2 #注意:env文件中所有的配置项以 "属性名=属性值" 格式定制 #将所有环境变量添加到到configmap中 root@master1ha1:~# kubectl create configmap cm-test2 --from-env-file=env configmap/cm-test2 created root@master1ha1:~# kubectl get cm cm-test2 -o yaml apiVersion: v1 data: key1: value1 key2: value2 kind: ConfigMap metadata: creationTimestamp: "2024-07-31T10:06:01Z" name: cm-test2 namespace: default resourceVersion: "162597" uid: 6ae54301-d753-4949-9e06-bdfba7c87cf9 root@master1ha1:~# kubectl describe cm cm-test2 Name: cm-test2 Namespace: default Labels: <none> Annotations: <none> Data ==== key1: ---- value1 key2: ---- value2 BinaryData ==== Events: <none> #删除CM root@master1ha1:~# kubectl delete cm cm-test2 configmap "cm-test2" deleted
范例:命令行创建基于配置文件
的CM
#直接将多个配置文件创建为一个ConfigMap root@master1ha1:~# cat conf.d/* [app1] config1 [app2] config2 [app3] config3 root@master1ha1:~# ls conf.d/ app1.conf app2.conf app3.conf root@master1ha1:~# kubectl create configmap cm-test3 --from-file=./conf.d/app1.conf --from-file=./conf.d/app2.conf configmap/cm-test3 created root@master1ha1:~# kubectl get cm cm-test3 -o yaml apiVersion: v1 data: app1.conf: | [app1] config1 app2.conf: | [app2] config2 kind: ConfigMap metadata: creationTimestamp: "2024-07-31T10:16:21Z" name: cm-test3 namespace: default resourceVersion: "163407" uid: bf4dc865-70ef-443a-883b-c1df3af54022 root@master1ha1:~# kubectl describe cm cm-test3 Name: cm-test3 Namespace: default Labels: <none> Annotations: <none> Data ==== app1.conf: ---- [app1] config1 app2.conf: ---- [app2] config2 BinaryData ==== Events: <none> #删除CM root@master1ha1:~# kubectl delete cm cm-test3 configmap "cm-test3" deleted
范例: 命令行创建基于目录
的CM
root@master1ha1:~# cat conf.d/* [app1] config1 [app2] config2 [app3] config3 root@master1ha1:~# ls conf.d/ app1.conf app2.conf app3.conf #直接将一个目录下的所有配置文件创建为一个ConfigMap root@master1ha1:~# kubectl create configmap cm-test4 --from-file=./conf.d/ configmap/cm-test4 created #结果显示:多个文件之间,属性名是文件名,属性值是文件内容 root@master1ha1:~# kubectl get cm cm-test4 -o yaml apiVersion: v1 data: app1.conf: | [app1] config1 app2.conf: | [app2] config2 app3.conf: | [app3] config3 kind: ConfigMap metadata: creationTimestamp: "2024-07-31T10:19:42Z" name: cm-test4 namespace: default resourceVersion: "163668" uid: a32a06f3-2b62-453b-9580-c62831bd97a3 #结果显示:多个文件之间,属性名是文件名,属性值是文件内容 root@master1ha1:~# kubectl describe cm cm-test4 Name: cm-test4 Namespace: default Labels: <none> Annotations: <none> Data ==== app1.conf: ---- [app1] config1 app2.conf: ---- [app2] config2 app3.conf: ---- [app3] config3 BinaryData ==== Events: <none> #删除CM root@master1ha1:~# kubectl delete cm cm-test4 configmap "cm-test4" deleted
3.2 资源清单文件创建方式
3.2.1 资源清单文件格式说明
资源清单文件命令格式
#清单文件格式 apiVersion: v1 kind: ConfigMap metadata: name: cm_name namespace: default data: key: value #配置信息如果只有一行,也使用此方式,使用卷挂载时,key即为文件名,value为文件 内容 文件名: | #配置文件有多行使用此方式 文件内容行1 文件内容行2 ..... #注意:CM的清单文件没有spec信息,而是data #命令式: kubectl create -f /path/file #声明式 kubectl apply -f /path/file
注意:此方式将配置文件内容写入清单文件,很不方便,推荐如下方式解决
- 先在命令行执行时
指定配置文件
的方式创建 CM - 通过
kubectl get cm <CM_NAME> -o yaml
方式导出资源清单文件, - 调整yaml资源清单文件,后续可重复使用
3.2.2 资源清单文件创建方式案例
操作示范
#资源定义文件 root@master1ha1:~# vim storage-configmap-test.yaml apiVersion: v1 kind: ConfigMap metadata: name: config-test data: author: ddddhh file.conf: | [class] linux go java #注释:data:部分内容是真正的配置项,有两种格式: #author: 是Key/value格式 #file.conf: | 是文件格式 #创建资源对象 root@master1ha1:~# kubectl apply -f storage-configmap-test.yaml configmap/config-test created #查看 root@master1ha1:~# kubectl get cm NAME DATA AGE config-test 2 32s kube-root-ca.crt 1 35d root@master1ha1:~# kubectl describe cm config-test Name: config-test Namespace: default Labels: <none> Annotations: <none> Data ==== author: ---- ddddhh file.conf: ---- [class] linux go java BinaryData ==== Events: <none> #结果显示:里面定义了两种类型的配置属性:文件样式和数据样式,都是以kv样式展示,属性名key和属性值 value中间使用 "----" 来隔开 #可以在线修改 root@master1ha1:~# kubectl edit cm config-test # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 data: author: ddddhh file.conf: | [class] linux go java kind: ConfigMap metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"author":"ddddhh","file.conf":"[class]\nlinux\ngo\njava\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"config-test","namespace":"default"}} creationTimestamp: "2024-08-01T07:46:13Z" name: config-test namespace: default resourceVersion: "165890" uid: 7142f41e-6efc-47e0-ae65-d73907e5df4f #删除 root@master1ha1:~# kubectl delete cm config-test configmap "config-test" deleted
操作示范:只读的configmap
root@master1ha1:~# vim storage-configmap-immutable-test.yaml apiVersion: v1 kind: ConfigMap metadata: name: cm-immutable-test data: author: ddddhh file.conf: | [class] linux go java immutable: true root@master1ha1:~# kubectl apply -f storage-configmap-immutable-test.yaml configmap/cm-immutable-test created root@master1ha1:~# kubectl get cm NAME DATA AGE cm-immutable-test 2 62s kube-root-ca.crt 1 35d #在线修改configmap提示出错 root@master1ha1:~# kubectl edit cm cm-immutable-test error: configmaps "cm-immutable-test" is invalid A copy of your changes has been stored to "/tmp/kubectl-edit-3644066815.yaml" error: Edit cancelled, no valid changes were saved. #可以删除 root@master1ha1:~# kubectl delete cm cm-immutable-test configmap "cm-immutable-test" deleted root@master1ha1:~# kubectl get cm NAME DATA AGE kube-root-ca.crt 1 35d
3.2.3 在线更新 configmap
操作示范
#创建 configmap root@master1ha1:~# kubectl create cm cm-nginx-conf --from-file=nginx.conf #修改configmap方法1 (主用方式推荐) #早期版本中nginx.conf内容如果不大,多行内容显示在一行,不方便修改,但如果过大,此方式只能显示大小,而非内容,所以不能修改,新版无此问题 root@master1ha1:~# kubectl edit cm cm-nginx-conf #修改configmap方法2 #通过将在线配置导出到一个yaml格式中修改后再apply root@master1ha1:~# kubectl get cm cm-nginx-conf -o yaml > cm-config-conf.yaml root@master1ha1:~# vim cm-config-conf.yaml root@master1ha1:~# kubectl apply -f cm-config-conf.yaml #修改configmap方法3 #修改配置 root@master1ha1:~# vim nginx.conf root@master1ha1:~# kubectl create cm cm-nginx-conf --from-file=nginx.conf --dry-run=client -o yaml |kubectl apply -f -
四、 ConfigMap 使用
使用ConfigMap
主要有两种方式:
- 通过环境变量的方式直接传递pod
- 使用volume的方式挂载入到pod内的文件中
注意:
ConfigMap
必须在Pod之前
创建- 与
ConfigMap
在同一个namespace
内的pod才能使用ConfigMap
,即ConfigMap
不能跨命名空间
调用。
- ConfigMap通常存放的数据
不要超过1M
CM 支持实时更新
,在原来的pod里面直接看到效果
4.1 通过环境变量的方式直接传递 Pod
引用ConfigMap对象
上特定的key,以valueFrom赋值
给Pod上指定的环境变量。
也可在Pod上使用envFrom
一次性导入ConfigMap对象
上的所有的key-value,key
(可以统一附加特定前缀)即为环境变量,value自动成为相应的变量值。
环境变量是容器启动时注入
的,不会随CM更改而发生变化,即一次性加载configmap
。
通过环境变量脚本的方式,预处理这些配置信息。
注意:环境变量的名称如果要用横线的话,最好使用下划线 _环境变量格式
- 方式1:
env
对指定的变量一个一个赋值
kubectl explain pod.spec.containers.env name #手工定制环境变量时,设置环境变量的名称,必选字段 value #手工定制环境变量时,直接设置环境变量的属性值,不通过CM获取配置,可选字段 valueFrom #手工定制环境变量时,设置环境变量的属性来源位置,可以支持从CM,Secret,downwordAPI获取 kubectl explain pod.spec.containers.env.valueFrom.configMapKeyRef name #引用哪个configmap key #引用哪个configmap中的key optional #如果设置为false,标识该项是必选项,如果设置为true标识这个key是可选的。 #此方式实现过程 1)容器中自定义环境变量名 2)根据CM的名称和Key名,找到对应的value 3) 再将value赋值给容器的环境变量
- 方式2:
envFrom
使用CM的所有变量实现对变量的批量赋值
,此方式生产
更为推荐
kubectl explain pod.spec.containers.envFrom configMapRef #ConfigMap对象中的特定Key secretKeyRef #Secret对象中的特定Key prefix #为ConfigMap中的每个属性都添加前缀标识 #此方实现过程 1)容器中自定义环境变量名,并且和CM的key同名 2)找到指定的CM中所有Key名,将值批量直接赋值给容器中相同名称的变量
4.2 使用volume的方式挂载入到pod内的文件中
在Pod上将 configMap
对象引用为存储卷,而后整体由容器mount
至某个目录下, key转为文件名,value即为相应的文件内容
在Pod上定义configMap
卷时,仅引用其中的部分key
,而后由容器mount
至目录下
在容器上仅mount configMap
卷上指定的key
容器中挂载的Volume
数据可以根据时间戳机制,和ConfigMap
同步更新,即configmap
变更后会自动加载
推荐滚动升级pod的方式来让ConfigMap内容变化生效
volume 格式
#指定卷信息,引用CM kubectl explain pod.spec.volumes name: volume_name #指定volume名 configMap: name: CM_name #指定CM的名称 #挂载卷到容器内的目录 kubectl explain pod.spec.containers.volumeMounts volumeMounts: - name: CM_name #指定CM的名称 mountPath; /path #容器内的挂载点
最后:
下章ConfigMap实践案例部分
最后~欢迎关注我! @Linux学习的那些事儿
我的个人资源整理,满满都是干货: → 可按需访问领取
如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!