ConfigMap
前面的资源对象并不能满足日常工作中的所有需求,一个最重要的需求就是应用的配置管理,特别是可变配置。
比如,在开发过程中程序需要配置 MySQL 或者 Redis 的连接地址。如果是以前的部署方式,此时想要修改这些信息,就需要修改代码的配置,然后重新打包部署。如果使用 ConfigMap,它能够向容器中注入配置信息,不仅可以是单个配置,也可以是整个配置文件。后面只需要修改 ConfigMap 的配置就能实现应用的配置更新。
ConfigMap 资源清单
ConfigMap 资源清单示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-demo
data:
serviceName: "demo-service"
listenPort: "8080"
config: |
mysql.ip="192.168.2.1"
mysql.port="3306"
redis.ip="192.168.2.2"
redis.port="6379"
在这个配置清单中,前两项是单个属性配置,config 字段中的可以看成是一个配置文件,其中的 |
的作用在于,保留下面属性的换行符和每行相对于第一行的缩进,多余的缩进和行尾的空白都会被删除。
使用示例:
config: |
第一行
第二行
第三行
第四行
转换成 JSON 格式就是:
{"config": "第一行\n 第二行\n 第三行\n第四行"}
如果将 |
换成 >
,表示折叠的意思,只有空白和才会被识别成换行,原来的换行符则会被识别成空格:
config: >
第一行
第二行
第三行
第五行
转换成 JSON 格式就是:
{"config": "第一行 第二行 第三行\n第五行"}
还可以使用竖线和加号或者减号进行配合使用,+
表示保留文字块末尾的换行,-
表示删除字符串末尾的换行。
config: |
"hello"
# Json 格式:{"config": "hello\n"}
config: |-
"hello"
# Json 格式:{"config": "hello"}
config: |+
"hello"
# Json 格式:{"config": "hello\n\n"}
# 有几个换行则加几个
创建 ConfigMap
创建 ConfigMap 的命令:
# 通过指定目录创建 ConfigMap
kubectl create configmap cm-demo --from-file=/path/dir
# 通过指定文件创建 ConfigMap,可以是多个文件
kubectl create configmap cm-demo --from-file=key1=/path/dir/file1.txt --from-file=key2=/path/dir/file2.txt
# 直接指定键值创建 ConfigMap
kubectl create configmap cm-demo --from-literal=key1=value1 --from-literal=key2=value2
准备一个目录 /cm/config/
,下面准备两个文件 mysql.conf
和 redis.conf
:
# mysql.conf 内容
host="192.168.2.1"
port="3306"
# redis.conf 内容
host="192.168.2.2"
port="6379"
测试创建:
# 直接通过整个目录创建,默认的 Key 就是文件名
kubectl create configmap cm-demo1 --from-file=/cm/config
# 指定文件创建,可以指定对于的 Key
kubectl create configmap cm-demo2 --from-file=mysqlConfig=/cm/config/mysql.conf --from-file=redisConfig=/cm/config/redis.conf
# 指定 K/V 直接创建
kubectl create configmap cm-demo3 --from-literal=k1=v1 --from-literal=k2=v2
使用 ConfigMap(环境变量)
在 ConfigMap 创建成功之后,有以下方法在 Pod 中使用它:
- 设置环境变量的值
- 在容器中设置命令行参数
- 在数据卷中挂载配置文件
使用环境变量示例:
apiVersion: v1
kind: Pod
metadata:
name: pod-cm-demo1
spec:
containers:
- name: c-cm-demo1
image: busybox:latest
command: [/bin/sh, -c, "env"]
# 将每个配置文件单独给一个环境变量
env:
- name: MYSQL_CONFIG
valueFrom:
configMapKeyRef:
name: cm-demo1
key: mysql.conf
- name: REDIS_CONFIG
valueFrom:
configMapKeyRef:
name: cm-demo1
key: redis.conf
# 直接导入整个 ConfigMap 到环境变量中
envFrom:
- configMapRef:
name: cm-demo
通过查看创建 Pod 之后输出的日志,可以看到设置的环境变量为:
# cm-demo 的 mysql.conf Key
MYSQL_CONFIG=host="192.168.2.1"
port="3306"
# cm-demo 的 redis.conf Key
REDIS_CONFIG=host="192.168.2.2"
port="6379"
# cm-demo 的配置生成了三个环境变量
config=mysql.ip="192.168.2.1"
mysql.port="3306"
redis.ip="192.168.2.2"
redis.port="6379"
serviceName=demo-service
listenPort=8080
使用 ConfigMap(容器运行参数)
作为容器的运行参数示例:
apiVersion: v1
kind: Pod
metadata:
name: pod-cm-demo2
spec:
containers:
- name: c-cm-demo2
image: busybox:latest
command: [/bin/sh, -c, "echo ${ENV_V1}-${ENV_V2}"]
env:
- name: ENV_V1
valueFrom:
configMapKeyRef:
name: cm-demo3
key: k1
- name: ENV_V2
valueFrom:
configMapKeyRef:
name: cm-demo3
key: k2
使用 ConfigMap(数据卷挂载)
以数据卷的方式挂载到 Pod 中使用:
apiVersion: v1
kind: Pod
metadata:
name: pod-cm-demo3
spec:
volumes:
- name: v-cm-demo
configMap:
name: cm-demo1
containers:
- name: c-cm-demo3
image: busybox:latest
command: [/bin/sh, -c, "ls -lh /opt/config/ && cat /opt/config/mysql.conf"]
volumeMounts:
- name: v-cm-demo
mountPath: /opt/config/
此时 ConfigMap 中的 Key 就能够变成文件名,然后挂载到指定的目录下。而且当使用数据卷的方式挂载到 Pod 中,此时更新 ConfigMap,挂载的数据也是会跟着热更新的。
这意味着以配置文件名称作为 Key 名称,然后使用 volume 挂载的方式是最适合开发场景的。
只有通过 Kubernetes API 创建的 Pod 才能使用 ConfigMap,其他方式创建的(比如静态 Pod)不能使用,同时 ConfigMap 文件大小限制为
1MB
(ETCD 的要求)。