一、configmap概述
configmap是k8s中的资源对象,用于保存非机密性的配置
,数据可以用key/value键值对的形式保存
,也可通过文件
的形式保存。
主要作用:让镜像和配置文件进行解耦,以便实现镜像的可移植性和可复用性。
适用于同时部署多个相同的服务
解释:
我们在部署服务的时候,每个服务都有自己的配置文件,如果一台服务器上部署多个服务:nginx、tomcat、apache 等,那么这些配置都存在这个节点上,假如一台服务器不能满足线上高并发的要求,需要对服务器扩容,扩容之后的服务器还是需要部署 多个服务:nginx、tomcat、apache,新增加的服务器上还是要管理这些服务的配置, 如果有一个服务出现问题,需要修改配置文件,每台物理节点上的配置都需要修改, 这种方式肯定满足不了线上大批量的配置变更要求。 所以,k8s 中引入了 Configmap 资源对象,可以当成volume挂载到pod中,实现统一的配置管理。
流程:
1、
Configmap 是 k8s 中的资源, 相当于配置文件
,可以有一个或者多个 Configmap;2、Configmap 可以做成 Volume,k8s pod 启动之后,
通过 volume 形式映射到容器内部指定目录上
;3、
容器中应用程序按照原有方式读取容器特定目录上的配置文件。
4、在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入。
Configmap 应用场景
1、使用k8s部署应用,当你将应用配置写进代码中,更新配置时也需要打包镜像,configmap可以将配置信息和docker镜像解耦,以便实现镜像的可移植性和可复用性,因为一个configmap是一系列配置信息的集合,可直接注入到pod中给容器使用。
configmap注入方式有两种:
1、将configmap作为存储卷
2、将configmap通过env中configmapkeyref注入到容器中
2、使用微服务架构
的话,存在多个服务共用配置的情况,如果每个服务单独一份配置,那更新配置会比较麻烦,使用configmap可以友好的共享配置。
使用configmap的限制条件
1、configmap需要在pod创建之前创建
2、只有当configmap和pod处于同一个命名空间,才可以被pod引用;
3、当pod挂载configmap绑定目录时,
目录下的目录不会被挂载在pod内,只有目录下的文件会挂载
4、configmap在设计上不是用来保存大量的数据。
在configmap中保存的数据不可超过1MiB
,若果需要保存超出尺寸限制的数据,可以考虑挂载存储卷或使用独立的数据库或文件服务。
二、configmap创建方法
按大类可分为两种方式,细分共有五种方式:
(一)
kubectl create configmap
创建
(1)通过命令行参数字面直接创建
(2)通过指定文件创建
(3)通过指定目录创建
(二)
yaml
文件创建
1、命令行参数字面直接创建
kubectl create configmap NAME [--from-literal=key1=value1] [--dry-run=server|client|none] [options]
#NAME: ConfigMap 的名称。
#--from-literal=key1=value1: 直接从命令行指定键值对。
#--dry-run=server|client|none: 模拟创建 ConfigMap 的操作,server 表示在服务器端模拟,client 表示在客户端模拟,none 表示不模拟。
#[options]: 其他可选参数,例如 --namespace 指定命名空间等。
创建可以同时输入多个参数即可以多个--from-literal=key1=value1
这种方式比较"适用于临时测试使用",而且不适合配置很多的情况。
2、指定文件创建
kubectl create configmap NAME [--from-file=[key=]source] [--dry-run=server|client|none] [options]
#--from-file=[key=]source: 从文件创建 ConfigMap。可以指定文件的键名(key),如果不指定,则文件名将作为键名。
创建可以同时输入多个文件
3、指定目录创建
kubectl create configmap NAME --from-file=目录路径 [--dry-run=server|client|none] [options]
指定目录创建和指定文件创建差不多,只是--from-file后面的参数"是目录不是文件",注意指定目录时,--from-file不需要指定key值,目录名会自动为key值
4、yaml文件创建
kubectl apply -f yaml文件
书写略...
三、Pod使用 Configmap
在pod中使用configmap有以下四种方式:
(一)通过环境变量引入
(1)在容器命令和参数里(
valueFrom
一一映射)(2)容器的环境变量(
envFrom
全部映射)(二)加载文件
(1)把 configmap 做成 volume,挂载到 pod (
通过volume加载
)(2)编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap(
通过subPath加载
)
通过环境变量引入,只是启动命令添加环境变量,是要把ConfigMap
映射为容器的环境变量。
编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap,要访问API
,可以使用相关的库
1、valueFrom-单个映射
通过valuefrom来配置环境变量,确保在 Pod 的 YAML 文件中,您引用的 ConfigMap 名称和键与您在 ConfigMap 中定义的完全一致。。valueFrom:表示引用cm的一个key
1、创建一个存储mysql配置的文件
#vim mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql #环境变量的名称
labels:
app: mysql
data:
logs: "1"
lower: "1"
2、将文件导入到configmap中,即环境变量
kubectl apply -f mysql-configmap.yaml
3、创建 pod,引用 Configmap 中的内容
#vim mysql-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
spec:
containers:
- name: mysql
image: busybox #拉取镜像
imagePullPolicy: ifNotPresent #拉取策略
command: [ "bin/sh", "-c", "sleep 3000" ]
env: #这里开始引入环境变量
- name: logs #自定义名称,用来作为引用的环境变量的name
valuefrom: #valueFrom:表示引用cm的一个key
configMapKeyRef:
name: mysql #指定 configmap 的名字
key: logs #指定 configmap 中的 key
- name: lower
valuefrom: #valueFrom:表示引用cm的一个key
configMapKeyRef:
name: mysql
key: lower
restartPolicy: Never
3、导入pod,并开始引用环境变量
kubectl apply -f mysql-pod.yaml
4、查看资源清单,要进入容器中。
# kubectl exec -it mysql-pod -- /bin/sh
env 查看资源清单
2、envfrom-全部映射
通过环境变量引入
envfrom:引入cm当中的所有的key为环境变量
1、导入一个存储mysql配置的文件 即设置环境变量
2、创建 pod,引用 Configmap 中的内容
#vim mysql-pod-envfrom
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod-envfrom
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent #拉取策略
command: [ "bin/sh", "-c", "sleep 3000" ]
envFrom: #这里为全部映射
- configMapRef:
name: mysql #这里为引用的环境变量的名称
restartPolicy: Never #重启策略
3、导入pod,并开始引用环境变量
kubectl apply -f mysql-pod-envfrom.yaml
4、查看资源清单,要进入容器中。
# kubectl exec -it mysql-pod-envfrom sh
3、把 configmap 做成 volume,挂载到 pod
通过volume
的方式把ConfigMap
加载进Pod
#通过volume加载文件
apiVersion: v1
kind: Pod
metadata:
name: busy-mount-volume
spec:
volumes: #Pod定义中的一个部分,用于声明要挂载的卷。
- name: passwd #挂载到容器中的卷,自定义名称
configMap: #指定该卷是从一个ConfigMap中创建的
name: busy-mount-passwd #指定挂载卷中数据源自configmap中的哪个环境变量
containers:
- name: busybox1
image: busybox
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "sleep 3000" ]
volumeMounts: #指定了要在容器中挂载的卷
- name: passwd #指定了要挂载的卷的名称为 passwd
mountPath: /root/k8s #指定挂载的路径
restartPolicy: Never
#注意:volumes和volumeMounts中的name定义的卷名称一致
如果只想要ConfigMap某个定义的环境变量中的部分内容,并自定义文件名,可通过"items"来配置
...
volumes:
- name: config-volume
configMap:
name: pkslow-yaml
items:
- key: application.yaml #注意这个名称对应pkslow-yaml这个环境变量中的某个值
path: app.yaml
- key: application-uat.yaml
path: uat.yaml
...
#items:
选择特定键: 这个部分允许您选择 ConfigMap 中的特定键,并将它们映射到容器内的文件名。
这里有两个条目:
第一个条目:
#application.yaml 被映射为 app.yaml。
key: application.yaml: 指定 ConfigMap 中的键名。
path: app.yaml: 指定在容器中挂载的文件名。
第二个条目:
#application-uat.yaml 被映射为 uat.yaml。
key: application-uat.yaml: 另一个键名。
path: uat.yaml: 在容器中挂载的文件名。
4、通过subPath加载
通过配置subPath
字段,把文件一个一个加载到Pod
中去。
将卷中的特定文件或目录挂载到容器中的指定路径,而不是将整个卷挂载到容器中
。这种方式在处理多个文件时非常有用。
示例:
假设您有一个 ConfigMap(指在configmap中某一个文件中有定义多个键值对
),其中包含多个配置文件,您可以使用 subPath
将每个文件单独挂载到容器中。
apiVersion: v1 #指定使用的 Kubernetes API 版本
kind: Pod #kind: 表示资源类型
metadata: #metadata: 包含关于 Pod 的元数据,比如名称之类的
name: busy-pod-subpath
spec: #定义 Pod 的具体配置。
volumes: #定义 Pod 中使用的卷
- name: passwd #自定义卷的名称,卷的名称
configMap: #指定该卷的类型为 ConfigMap。
name: busy-mount-passwd #指定使用的 ConfigMap 名称
containers: #定义 Pod 中的容器列表
- name: busybox #容器的名称
image: busybox #使用的容器镜像
imagePullPolicy: IfNotPresent #指定镜像拉取策略
command: [ "/bin/sh", "-c", "sleep 3000" ] #容器启动时执行的命令
volumeMounts: #定义容器中的卷挂载
- name: passwd #指定挂载的卷名称
mountPath: /data/passwd.yaml #指定在容器中的挂载路径
subPath: passwd #指定要挂载的 ConfigMap 中的具体键
- name: passwd
mountPath: /data/mysql
subPath: mysql #指定要挂载的 ConfigMap 中的具体键
restartPolicy: Never #指定Pod的重启策略,Never,表示如果容器停止运行,将不会被重启。
这个 Pod 配置的目的是创建一个包含两个文件挂载的容器。文件内容来自于 busy-mount-passwd ConfigMap 中的 passwd 和 mysql 键。容器将会运行 busybox 镜像,保持 3000 秒的休眠状态。Pod 的重启策略设置为不重启容器。
注意事项
-
文件覆盖: 挂载卷会覆盖容器内挂载路径下的任何现有文件或目录。
-
ConfigMap 更新: 如果更新了 ConfigMap,挂载该 ConfigMap 的 Pod 将会自动获取这些更新,但通常需要重启 Pod 才能使更改生效。
解决覆盖的问题
修改configmap后容器中对应的file会自动更新,如果以subpath方式挂载文件,文件内容不会自动更新
。
即挂载卷的时候尽量使用subpath,减少文件被覆盖的几率。
...
volumeMounts:
- mountPath: /etc/nginx/nginx.conf
name: volume-7zdx7
subPath: nginx.conf
dnsPolicy: ClusterFirst #dnsPolicy: 指定 Pod 的 DNS 策略,这里是 ClusterFirst,表示 Pod 将优先使用集群 DNS 服务。
restartPolicy: Always #restartPolicy: 指定 Pod 的重启策略,这里是 Always,表示无论容器是如何退出的,Kubernetes 都会尝试重新启动它。
schedulerName: default-scheduler #schedulerName: 指定调度器的名称,这里是 default-scheduler,表示使用 Kubernetes 的默认调度器来调度该 Pod。
securityContext: {} #securityContext: 定义 Pod 的安全上下文,这里是一个空对象 {},表示没有特别的安全设置。
terminationGracePeriodSeconds: 30 #terminationGracePeriodSeconds: 指定 Pod 终止时的宽限期(以秒为单位),这里是 30 秒,表示在发送终止信号后,容器有 30 秒的时间来清理和关闭。
volumes:
- name: volume-7zdx7
configMap:
defaultMode: 420 #defaultMode: 指定挂载文件的默认权限,这里是 420(八进制),表示文件权限为 644(用户可读写,组和其他用户可读)。
name: nginx1
...
Configmap 热更新
仅限于卷的形式,如果是环境变量的形式则不更新!!!
即修改configmap中文件的内容,然后重新执行一下。即可
[root@k8s-master01 ~]# kubectl edit configmap mysql
#将log:1 变成 log:2
apiVersion:v1
data:
log:"2"
lower:"1"
重新执行一次资源清单文件
[root@k8s-master01 test1]# kubectl apply -f mysql-pod-volume.yaml
pod/mysql-pod-volume configured
[root@k8s-master01 ~]# kubectl exec -it mysql-pod-volume -- /bin/sh
/ # cat /tmp/config/log
2/ #
#一次构建镜像,通过配置管理中心configmap 实现了 多场景运行
四、不可变的ConfigMap
可以禁止修改ConfigMap
-
保护应用,使之免受意外(不想要的)更新所带来的负面影响。
-
通过大幅降低对 kube-apiserver 的压力提升集群性能,这是因为系统会关闭 对已标记为不可变更的 ConfigMap 的监视操作。
此功能特性由 ImmutableEphemeralVolumes
特性门控 来控制。你可以通过将 immutable
字段设置为 true
创建不可变更的 ConfigMap。
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
一旦某 ConfigMap 被标记为不可变更,则 无法逆转这一变化,也无法更改 data
或 binaryData
字段的内容。你只能删除并重建 ConfigMap。 因为现有的 Pod 会维护一个对已删除的 ConfigMap 的挂载点,建议重新创建 这些 Pods。