前提条件
- 拥有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里的相关信息。