1. kubernets对ConfigMap的定义
ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。
概括:
- API对象:一种资源,跟service,deployment/statefulset一个级别。
- 非机密性的数据:对数据以键值对的方式明文传输。
- 实现的功能:可以传递pod启动用到的环境变量;挂载配置文件到pod中
补充:
运行在名称空间的级别,因此创建ConfigMap的时候需要加上namespace
2. 创建方式
创建ConfigMap的方式有4种:分别是从key-value字符串创建,从env文件创建,从文件/目录创建,从文件创建。语法为:
kubectl create cm <cm名称> --from-literal=<键1>=<值1> --from-literal=<键2>=<值2> -n <namespace>
kubectl create cm <cm名称> --from-env-file=<config.env> -n <namespace>
kubectl create cm <cm名称> --from-file=<文件路径> --from-file=<文件名称> -n <namespace>
kubectl apply -f <yaml文件> -n <namespace>
最常用的是第4种语法格式
3. ConfigMap的使用场景
在使用ConfigMap的过程中,主要有两种业务场景,也是我们日常使用最多的两种方式:
- 向Pod中注入环境变量。
- 以存储卷的方式,向pod中挂载文件,通常是一些配置文件。
4. 向Pod中注入环境变量
创建 Pod 时,可以为其下的容器设置环境变量。通过配置文件的 env 或者 envFrom 字段来设置环境变量。
env 和 envFrom 字段具有不同的效果。
env :可以为容器设置环境变量,直接为你所给的每个变量指定一个值。
envFrom :你可以通过引用 ConfigMap 或 Secret 来设置容器的环境变量。 使用 envFrom 时,引用的 ConfigMap 或 Secret 中的所有键值对都被设置为容器的环境变量。 你也可以指定一个通用的前缀字符串
4.1 采用env向pod中注入环境变量
- 准备一个测试的pod,首先定义它的yaml文件,在yaml中直接采用env注入环境变量。
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: test
spec:
containers:
- name: test-pod
image: registry:5000/busybox:latest
command: ["/bin/sh","-c","while true;do echo $(date +%T) >> /tmp/time.txt; sleep 300; done"]
#注入2个env变量
env:
- name: USER
value: "alice"
- name: AGE
value: "66"
- 去创建这个pod
kubectl apply -f pod-test.yaml
- 进入容器内,检查注入的env已经生效
4.2 引用configmap设置pod环境变量
- 首先创建一个configmap配置文件,在data部分定义环境变量和取值
# test-env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test-env
namespace: test
data:
TZ: "Asia/Shanghai"
USERNAME: "mysql"
- 在test-pod引用configmap定义的环境变量,在引用的时候,又有2种方式:
a. 整个cm中的健值对全部注入pod的环境变量中,通过关键字envFrom
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: test
spec:
containers:
- name: test-pod
image: registry:5000/busybox:latest
command: ["/bin/sh","-c","while true;do echo $(date +%T) >> /tmp/time.txt; sleep 300; done"]
envFrom:
- configMapRef:
name: test-env
b. 指定cm中的key,注入pod。
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: test
spec:
containers:
- name: test-pod
image: registry:5000/busybox:latest
command: ["/bin/sh","-c","while true;do echo $(date +%T) >> /tmp/time.txt; sleep 300; done"]
env:
- name: userName
valueFrom:
configMapKeyRef:
name: test-env
key: USERNAME
- 分别测试两种方法,不难看出:采用configmap向pod注入环境变量,可以将整个cm中的键值注入,也可以指定cm中的key注入
5. ConfigMap以volume方式挂载文件给pod
- 首先准备一个cm,在里面定义time.txt、b.txt两个文件
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
namesapce: test
data:
time.txt: |
2023/07/11
b.txt: |
my name is liu.
- 创建tets-pod,pod启动后,会在/tmp中创建一个note目录,并在/tmp目录下生成一个a.txt的文本,每隔1小时a.txt中写入当前时间
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: test
spec:
containers:
- name: test-pod
image: registry:5000/busybox:latest
command: ["/bin/sh","-c","mkdir /tmp/note;while true;do echo $(date +%T) >> /tmp/time.txt; sleep 3600; done"]
3. 将cm挂载进容器
3.1 将time.txt和b.txt都挂载进去
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: test
spec:
containers:
- name: test-pod
image: registry:5000/busybox:latest
command: ["/bin/sh","-c","mkdir /tmp/note;while true;do echo $(date +%T) >> /tmp/time.txt; sleep 3600; done"]
volumeMounts:
- name: cm-test
mountPath: /tmp
volumes:
- name: cm-test
configMap:
name: test-cm
测试结果发现:
a. time.txt和b.txt都被挂载进了容器的/tmp目录下
b. 原来time.txt的内容被覆盖掉
c.note目录被覆盖掉
3.2 只将b.txt挂载进/tmp
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: test
spec:
containers:
- name: test-pod
image: registry:5000/busybox:latest
command: ["/bin/sh","-c","mkdir /tmp/note;while true;do echo $(date +%T) >> /tmp/time.txt; sleep 3600; done"]
volumeMounts:
- name: cm-test
mountPath: /tmp
volumes:
- name: cm-test
configMap:
name: test-cm
items:
- key: b.txt
path: path1/path2/b.txt
测试结果发现:
a./tmp下time.txt和a.txt被覆盖
b.b.txt被挂载到/tmp/path1/path2目录下
小结:
configMap挂载文件时,会先覆盖挂载目录,然后再将configmap中的内容做为文件挂载进行。
通常我们不希望挂载目录下的文件造成覆盖,只是将configmap中的key作为文件挂载到目录下,可以是用subpath参数。
6. 使用subPath将ConfigMap挂载进目录
示例:将b.txt挂载到/tmp/path1/path2下,time.txt挂载/tmp下,替换来的内容,不覆盖掉note目录
# pod-test.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: test
spec:
containers:
- name: test-pod
image: registry:5000/busybox:latest
command: ["/bin/sh","-c","mkdir /tmp/note;while true;do echo $(date +%T) >> /tmp/time.txt; sleep 3600; done"]
volumeMounts:
- name: cm-test1
mountPath: /tmp/path1/path2/b.txt
subPath: b.txt
- name: cm-test2
mountPath: /tmp/time.txt
subPath: time.txt
volumes:
- name: cm-test1
configMap:
name: test-cm
items:
- key: b.txt
path: b.txt
- name: cm-test2
configMap:
name: test-cm
items:
- key: time.txt
path: time.txt
测试结果如下: