ConfigMap
configmap 是 k8s 中的资源对象,用于保存非机密性的配置的,数据可以用 kv 键值对的形式保存,也可通过文件的形式保存。
什么是 configmap
在 k8s 中,ConfigMap 是一种用于存储应用程序配置数据的对象。它允许将配置信息与应用程序分离,从而实现配置的解耦和管理的集中化。
ConfigMap 是以键值对的形式存储配置数据的,可以包含一个或多个键值对。这些配置数据可以包含环境变量、命令行参数、配置文件等。ConfigMap 的数据可以通过环境变量、命令行参数或挂载文件的方式注入到 Pod 中的容器中。
ConfigMap 可以通过 kubectl 命令行工具、YAML 文件或 API 进行创建和管理。可以在命名空间级别或集群级别创建 ConfigMap,并将其应用于特定的 Pod、Deployment、StatefulSet 等对象。
通过使用 ConfigMap,可以实现以下的优势:
- 解耦配置和应用程序:将配置信息从应用程序中分离,使得应用程序更加灵活和可配置。
- 集中化管理配置:通过创建和管理 ConfigMap 对象,可以集中管理应用程序的配置,而不需要修改容器镜像或重新部署应用程序。
- 容器化配置:ConfigMap 中的配置数据可以以环境变量、命令行参数或挂载文件的方式注入到容器中,方便应用程序的使用。
- 动态更新配置:通过更新 ConfigMap 对象,可以实现对应用程序配置的动态更新,而不需要重新启动或重新部署应用程序。
总之,ConfigMap 是 k8s 中用于存储和管理应用程序配置数据的一种机制,通过将配置与应用程序分离,实现了配置的解耦和集中化管理,提高了应用程序的灵活性和可维护性。
configmap 作用
我们在部署服务的时候,每个服务都有自己的配置文件,
如果一台服务器上部署多个服务:nginx、tomcat、apache 等,那么这些配置都存在这个节点上
假如一台服务器不能满足线上高并发的要求,需要对服务器扩容,扩容之后的服务器还是需要部署多个服务:nginx、tomcat、apache,新增加的服务器上还是要管理这些服务的配置
如果有一个服务出现问题,需要修改配置文件,每台物理节点上的配置都需要修改,这种方式肯定满足不了线上大批量的配置变更要求
所以,k8s 中引入了 Configmap 资源对象,可以当成 volume 挂载到 pod 中,实现统一的配置管理。
configmap 特点
- Configmap 是 k8s 中的资源, 相当于配置文件,可以有一个或者多个 Configmap
- Configmap 可以做成 Volume,k8s pod 启动之后,通过 volume 形式映射到容器内部指定目录上;
- 容器中应用程序按照原有方式读取容器特定目录上的配置文件;
- 在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入。
configmap 使用
一个项目的所有配置文件都是用一个 configmap 来统一管理!这里我们使用 redis 进行测试
- 编辑一个简单的 redis 配置文件,
my-redis.conf
,内容如下
appendonly yes
- 根据 redis 配置文件创建一个 configmap
kubectl create cm redis-cm --from-file=my-redis.conf
[root@k8s-master k8s]# kubectl create cm redis-cm --from-file=my-redis.conf
configmap/redis-cm created
[root@k8s-master k8s]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 2d4h
redis-cm 1 11s
这个 configmap 就保存在 k8s 的 etcd 中,这个 redis 配置文件 my-redis.conf
就可有可无了
可以以 yaml 格式查看这个 configmap
kubectl get cm redis-cm -o yaml
[root@k8s-master k8s]# kubectl get cm redis-cm -o yaml
apiVersion: v1
data:
my-redis.conf: |
appendonly yes
kind: ConfigMap
metadata:
creationTimestamp: "2024-03-26T12:24:25Z"
name: redis-cm
namespace: default
resourceVersion: "298281"
uid: a472846b-e060-478a-8d37-f21300f975d8
- 创建一个 redis pod,编辑文件
redis-cm.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-cm
spec:
containers:
- name: redis01
image: redis
command:
- redis-server
- "/redis-master/redis.conf"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /data
name: redis-data
- mountPath: /redis-master
name: config
volumes:
- name: redis-data
emptyDir: {}
- name: config
configMap:
name: redis-cm
items:
- key: my-redis.conf
path: redis.conf
在 yaml 文件中,容器与 configmap 进行挂载的目录/redis-master
是任意取的,自行设置即可
容器下 command 的第二个属性"/redis-master/redis.conf"
是由容器与 configmap 挂载的目录加上最后一行的 path 构成,path 也是任意取名,是容器内生成的 redis 文件,内容是由上面的 key 映射到 configmap 里面对应的内容
- 根据 yaml 文件创建 pod
[root@k8s-master k8s]# vim redis-cm.yaml
[root@k8s-master k8s]# kubectl apply -f redis-cm.yaml
pod/redis-cm created
[root@k8s-master k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-pod 1/1 Running 0 3h37m
nginx-pod-pvc-967fcb547-rj5ll 1/1 Running 0 6h14m
nginx-pod-pvc-967fcb547-wbbh7 1/1 Running 0 6h14m
redis-cm 1/1 Running 0 59s
- 进入 pod 容器内部,查看
/redis-master
下的redis.conf
文件
[root@k8s-master k8s]# kubectl exec -it redis-cm /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@redis-cm:/data# cd /redis-master/
root@redis-cm:/redis-master# ls
redis.conf
root@redis-cm:/redis-master# cat redis.conf
appendonly yes
可以看到/redis-master
下的 redis.conf
文件已经和 configmap 绑定好了
- 在外部修改 configmap,查看容器内部的
redis.conf
会不会发生变化
[root@k8s-master k8s]# kubectl edit cm redis-cm
configmap/redis-cm edited
在上面新增一行requirepass 123456
,这是 redis 修改登录密码的属性
- 更改完成后等1-2分钟,进入容器查看
redis.conf
变化
[root@k8s-master k8s]# kubectl exec -it redis-cm /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@redis-cm:/data# cd /redis-master/
root@redis-cm:/redis-master# cat redis.conf
appendonly yes
requirepass 123456
我们在容器中尝试获取这两个属性
root@redis-cm:/redis-master# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
发现我们新增加的 requirepass 属性是获取不到的,这是容器的问题,因为当前 pod 没有热更新的能力
kubectl create cm xxxx --from-file=文件名
volumeMounts:
- name: xxx和voulmes的name对应
mountPath: 容器内加载配置文件的路径。
voulmes:
- name: xxx和容器内要挂载目录的对应
configMap:
name:
items:
key:
path: