前提条件
- 拥有Kubernetes集群环境,可参考:Kubernetes集群搭建
- 理解Kubernetes部署知识,可参考:使用Kubernetes部署第一个应用 、Deloyment控制器
ConfigMap简介
ConfigMap 是 Kubernetes(通常简称为 K8s)中的一种 API 对象,用于将非机密性的数据保存到键值对中。它可以将配置信息与容器镜像解耦,使得应用程序在不同环境(如开发、测试、生产)中的配置变得更加灵活和易于管理。
例如,一个 Web 应用程序可能在开发环境中连接到本地的测试数据库,而在生产环境中需要连接到远程的高性能数据库。通过 ConfigMap,可以轻松地切换这些配置,而无需重新构建容器镜像。
创建ConfigMap
ConfigMap
资源对象使用 key-value
形式的键值对来配置数据,这些数据可以在 Pod
里面使用,如下使用yaml文件来创建ConfigMap
# 目录准备 [root@k8s-master01 test]# mkdir configtest [root@k8s-master01 test]# cd configtest/ # 创建yaml文件 [root@k8s-master01 configtest]# vi configdemo.yaml
yaml文件内容如下
kind: ConfigMap
apiVersion: v1
metadata:
name: cm-demo
namespace: default
data:
data.1: hello
data.2: world
config: |
property.1=value-1
property.2=value-2
property.3=value-3
其中配置数据在 data
属性下面进行配置,前两个被用来保存单个属性,后面一个被用来保存一个配置文件
# 创建configmap [root@k8s-master01 configtest]# kubectl apply -f configdemo.yaml configmap/cm-demo created # 查看configmap [root@k8s-master01 configtest]# kubectl get cm NAME DATA AGE cm-demo 3 94s kube-root-ca.crt 1 74d [root@k8s-master01 configtest]# kubectl get configmap NAME DATA AGE cm-demo 3 104s kube-root-ca.crt 1 74d
更多创建方法,可以使用 kubectl create configmap -h
来查看创建 ConfigMap
的帮助信息
Examples: # Create a new configmap named my-config based on folder bar kubectl create configmap my-config --from-file=path/to/bar # Create a new configmap named my-config with specified keys instead of file basenames on disk kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt # Create a new configmap named my-config with key1=config1 and key2=config2 kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
从一个给定的目录来创建一个 ConfigMap
对象,比如我们有一个 testcm
的目录,该目录下面包含一些配置文件,redis
和 mysql
的连接信息,如下:
$ ls testcm redis.conf mysql.conf $ cat testcm/redis.conf host=127.0.0.1 port=6379 $ cat testcm/mysql.conf host=127.0.0.1 port=3306
使用 from-file
关键字来创建包含这个目录下面所以配置文件的 ConfigMap
:
$ kubectl create configmap cm-demo1 --from-file=testcm configmap "cm-demo1" created
其中 from-file
参数指定在该目录下面的所有文件都会被用在 ConfigMap
里面创建一个键值对,键的名字就是文件名,值就是文件的内容。
创建完成后,查看 ConfigMap
列表:
$ kubectl get configmap NAME DATA AGE cm-demo1 2 17s
可以看到已经创建了一个 cm-demo1
的 ConfigMap
对象,然后可以使用 describe
命令查看详细信息:
kubectl describe configmap cm-demo1 Name: cm-demo1 Namespace: default Labels: <none> Annotations: <none> Data ==== mysql.conf: ---- host=127.0.0.1 port=3306 redis.conf: ---- host=127.0.0.1 port=6379 Events: <none>
操作过程
[root@k8s-master01 configtest]# mkdir testcm [root@k8s-master01 configtest]# vi testcm/redis.conf # 内容如下 host=127.0.0.1 port=6379 [root@k8s-master01 configtest]# vi testcm/mysyql.conf # 内容如下 host=127.0.0.1 port=3306 [root@k8s-master01 configtest]# kubectl create configmap cm-demo1 --from-file=testcm configmap/cm-demo1 created [root@k8s-master01 configtest]# kubectl get configmap NAME DATA AGE cm-demo 3 5m30s cm-demo1 2 12s kube-root-ca.crt 1 74d [root@k8s-master01 configtest]# kubectl describe configmap cm-demo1 Name: cm-demo1 Namespace: default Labels: <none> Annotations: <none> Data ==== mysyql.conf: ---- host=127.0.0.1 port=3306 redis.conf: ---- host=127.0.0.1 port=6379 BinaryData ==== Events: <none> [root@k8s-master01 configtest]#
可以看到两个 key
是 testcm
目录下面的文件名称,对应的 value
值的话就是文件内容,注意,如果文件里面的配置信息很大的话,describe
的时候可能不会显示对应的值,要查看键值的话,可以使用如下命令:
[root@k8s-master01 configtest]# kubectl get configmap cm-demo1 -o yaml apiVersion: v1 data: mysyql.conf: | host=127.0.0.1 port=3306 redis.conf: | host=127.0.0.1 port=6379 kind: ConfigMap metadata: creationTimestamp: "2024-11-28T08:38:23Z" name: cm-demo1 namespace: default resourceVersion: "540808" uid: fb0bf381-67f3-427b-a51d-466cda8d808f [root@k8s-master01 configtest]#
除了通过目录进行创建,我们也可以使用指定的文件进行创建 ConfigMap
,同样的,以上面的配置文件为例,创建一个 redis
配置的 ConfigMap
对象:
[root@k8s-master01 configtest]# kubectl create configmap cm-demo2 --from-file=testcm/redis.conf configmap/cm-demo2 created [root@k8s-master01 configtest]# kubectl get configmap cm-demo2 -o yaml apiVersion: v1 data: redis.conf: | host=127.0.0.1 port=6379 kind: ConfigMap metadata: creationTimestamp: "2024-11-28T08:42:53Z" name: cm-demo2 namespace: default resourceVersion: "541215" uid: bc51ade4-add0-4279-b7f3-939e64902222
redis.conf
文件配置信息的 ConfigMap
对象创建成功了,值得注意的是 --from-file
这个参数可以使用多次,比如我们这里使用两次分别指定 redis.conf
和 mysql.conf
文件,就和直接指定整个目录是一样的效果了。
另外,通过帮助文档看到,还可以直接使用字符串进行创建,通过 --from-literal
参数传递配置信息,同样的,这个参数可以使用多次,格式如下:
[root@k8s-master01 configtest]# kubectl create configmap cm-demo3 --from-literal=db.host=localhost --from-literal=db.port=3306 configmap/cm-demo3 created [root@k8s-master01 configtest]# kubectl get configmap cm-demo3 -o yaml apiVersion: v1 data: db.host: localhost db.port: "3306" kind: ConfigMap metadata: creationTimestamp: "2024-11-28T08:44:28Z" name: cm-demo3 namespace: default resourceVersion: "541362" uid: 42ab9175-74ef-4f55-83c0-536ac12be56d
使用ConfigMap
ConfigMap
创建成功了,怎么在 Pod
中来使用呢? ConfigMap
这些配置数据可以通过很多种方式在 Pod
里使用,主要有以下几种方式:
-
设置环境变量的值
-
在数据卷里面创建config文件
使用 ConfigMap
来填充环境变量
创建yaml文件
[root@k8s-master01 configtest]# vi testcm1-pod.yaml
内容如下
apiVersion: v1
kind: Pod
metadata:
name: testcm1-pod
spec:
containers:
- name: testcm1
image: busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.port
envFrom:
- configMapRef:
name: cm-demo1
创建pod
[root@k8s-master01 configtest]# kubectl apply -f testcm1-pod.yaml
查看pod状态
[root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 ContainerCreating 0 13s [root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 ContainerCreating 0 24s [root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 Completed 0 36s [root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 CrashLoopBackOff 1 (2s ago) 38s [root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 CrashLoopBackOff 1 (4s ago) 40s [root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 CrashLoopBackOff 1 (16s ago) 52s
这个Pod运行后会输出如下几行:
$ kubectl logs testcm1-pod ...... DB_HOST=localhost DB_PORT=3306 mysql.conf=host=127.0.0.1 port=3306 redis.conf=host=127.0.0.1 port=6379 ......
实际操作的完整输出如下
[root@k8s-master01 configtest]# kubectl logs testcm1-pod KUBERNETES_SERVICE_PORT=443 KUBERNETES_PORT=tcp://10.0.0.1:443 HOSTNAME=testcm1-pod DB_PORT=3306 SHLVL=1 HOME=/root mysyql.conf=host=127.0.0.1 port=3306 redis.conf=host=127.0.0.1 port=6379 KUBERNETES_PORT_443_TCP_ADDR=10.0.0.1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT_443_TCP=tcp://10.0.0.1:443 KUBERNETES_SERVICE_HOST=10.0.0.1 PWD=/ DB_HOST=localhost [root@k8s-master01 configtest]#
看到 DB_HOST
和 DB_PORT
都已经正常输出了,因为通过ConfigMap将配置赋值到环境变量中,把执行env命令后,能看到环境变量里包含了ConfigMap的值。
刚才是把整个环境变量输出来了,具体使用中,可以将环境变量ConfigMap配置的值用拼接在命令行中,如下:
vi testcm2-pod.yaml
内容如下
apiVersion: v1
kind: Pod
metadata:
name: testcm2-pod
spec:
containers:
- name: testcm2
image: busybox
command: [ "/bin/sh", "-c", "echo $(DB_HOST) $(DB_PORT)" ]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: cm-demo3
key: db.port
创建pod
[root@k8s-master01 configtest]# kubectl apply -f testcm2-pod.yaml pod/testcm2-pod created
查看pod
[root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 CrashLoopBackOff 5 (56s ago) 4m43s testcm2-pod 0/1 CrashLoopBackOff 1 (3s ago) 7s
运行这个 Pod
后会输出如下信息:
[root@k8s-master01 configtest]# kubectl logs testcm2-pod localhost 3306
在数据卷里面使用 ConfigMap
另外一种是非常常见的使用 ConfigMap
的方式:通过数据卷使用,在数据卷里面使用 ConfigMap
,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容:
创建yaml文件
vi testcm3-pod.yaml
内容如下
apiVersion: v1
kind: Pod
metadata:
name: testcm3-pod
spec:
containers:
- name: testcm3
image: registry.cn-hangzhou.aliyuncs.com/my-common-images/busybox:latest
command: [ "/bin/sh", "-c", "cat /etc/config/redis.conf" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: cm-demo2
应用yaml文件
[root@k8s-master01 configtest]# kubectl apply -f testcm3-pod.yaml pod/testcm3-pod created
查看pod
[root@k8s-master01 configtest]# kubectl get pod NAME READY STATUS RESTARTS AGE testcm1-pod 0/1 CrashLoopBackOff 6 (95s ago) 8m12s testcm2-pod 0/1 CrashLoopBackOff 5 (37s ago) 3m36s testcm3-pod 0/1 CrashLoopBackOff 1 (7s ago) 10s
运行这个 Pod
的,查看日志:
[root@k8s-master01 configtest]# kubectl logs testcm3-pod host=127.0.0.1 port=6379
看到输出的日志信息就是从ConfigMap里的相关信息。