ConfigMap
许多应用经常会有从配置文件,命令行参数或者环境变量中读取一些配置信息,这些配置信息不应该直接写死在到应用程序中,比如你一个应用连接一个 redis
服务,下一次下一次想要更换一个的,还得重新修改代码,重新制作一个镜像, 这样是不可取的, ConfigMap
给我们提供了向容器中注入配置信息的能力,不仅可以用来保存单个属性,也可以用来保存整个配置文件
,比如我们可以用来配置一个redis
服务的访问地址,也可以用来保存整个redis
的配置文件
创建 通过Yaml文件创建
ConfigMap
资源对象使用 key-value
形式的键值对来配置数据,这些数据可以在 Pod
中使用, ConfigMap
和我们后面的 Secrets
比较类似,一个较大的区别是 ConfigMap
可以比较方便的处理一些非敏感的数据,比如密码之类的还是需要使用 Secrets
来进行管理,
1 2 3 4 5 6 7 8 9 10 11 apiVersion: v1 kind: ConfigMap metadata: name: cm-demo1 data: data.1: hello data.2: world config: property.1=value-1 property.2=value-2 property.3=value-3
其中配置数据在 data
属性下面进行配置,前两个被用来保存单个属性,后面一个被用来保存一个配置文件。
1 kubectl create -f xxx.yaml
通过指定文件创建
同时也可以用 kubectl create configmap -h
来查看关于创建 ConfigMap 的帮助信息
1 2 3 4 5 6 7 8 9 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
的连接信息
1 2 3 4 5 6 7 8 9 10 11 $ 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:
1 2 $ kubectl create configmap cm-demo1 --from-file=testcm configmap "cm-demo1" created
from-file
参数指定在该目录下面的所有文件都会被用在 ConfigMap
里面创建一个键值对,键的名字就是文件名,值就是文件的内容, 创建完成过后,使用命令来查看 ConfigMap
列表:
1 2 3 $ kubectl get configmap NAME DATA AGE cm-demo1 2 17s
使用 describe
命令查看详细信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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>
可以看到 key
是 testcm
目录下面的文件名称,对应的 value
值的话就是文件内容,如果文件里面的配置信息很大的话,describe
的时候肯跟不会显示对应的值,要查看键值的话,可以使用如下的命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ kubectl get configmap cm-demo1 -o yaml apiVersion: v1 data: mysql.conf: | host=127.0.0.1 port=3306 redis.conf: | host=127.0.0.1 port=6379 kind: ConfigMap metadata: creationTimestamp: 2018-06-14T16:24:36Z name: cm-demo1 namespace: default resourceVersion: "3109975" selfLink: /api/v1/namespaces/default/configmaps/cm-demo1 uid: 6e0f4d82-6fef-11e8-a101-525400db4df7
除了通过文件目录进行创建, 也可以使用指定的文件进行创建 ConfigMap
, 我们创建一个 redis
配置的单独 ConfigMap
对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ kubectl create configmap cm-demo2 --from-file=testcm/redis.conf configmap "cm-demo2" created $ kubectl get configmap cm-demo2 -o yaml apiVersion: v1 data: redis.conf: | host=127.0.0.1 port=6379 kind: ConfigMap metadata: creationTimestamp: 2018-06-14T16:34:29Z name: cm-demo2 namespace: default resourceVersion: "3110758" selfLink: /api/v1/namespaces/default/configmaps/cm-demo2 uid: cf59675d-6ff0-11e8-a101-525400db4df7
可以看到关联 redis.conf
文件配置信息的 ConfigMap
对象创建成功了,--from-file
可以使用多次,可以使用两次分别指定 redis.conf
和 mysql.conf
文件,就和直接指定整个目录一样的效果了
通过字符串创建
通过帮助文档可以直接使用字符串进行创建, 通过 --from-literal
参数传递配置信息,同样的,这个参数可以使用多次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 kubectl create configmap cm-demo3 --from-literal=db.host=localhost --from-literal=db.port=3306 configmap "cm-demo3" created $ kubectl get configmap cm-demo3 -o yaml apiVersion: v1 data: db.host: localhost db.port: "3306" kind: ConfigMap metadata: creationTimestamp: 2018-06-14T16:43:12Z name: cm-demo3 namespace: default resourceVersion: "3111447" selfLink: /api/v1/namespaces/default/configmaps/cm-demo3 uid: 06eeec7e-6ff2-11e8-a101-525400db4df7
使用
ConfigMap
创建成功了,那么我们应该怎么在 Pod
中使用呢,我们说 ConfigMap
这些配置数据可以通过很多种方式在 Pod
里使用,主要有一下集中方式:
设置环境变量的值
在容器里设置命令行参数
在数据卷里面创建config文件
ConfigMap 填充环境变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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
1 kubectl create -f testcm-pod.yaml
这个 Pod 运行后会输出如下几行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ kubectl logs testcm1-pod KUBERNETES_SERVICE_PORT=443 KUBERNETES_PORT=tcp://10.96.0.1:443 HOSTNAME=testcm1-pod DB_PORT=3306 SHLVL=1 HOME=/root mysql.conf=host=127.0.0.1 port=3306 redis.conf=host=127.0.0.1 port=6379 KUBERNETES_PORT_443_TCP_ADDR=10.96.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.96.0.1:443 KUBERNETES_SERVICE_HOST=10.96.0.1 PWD=/ DB_HOST=localhost
DB_HOST
和 DB_PORT
都已经正常输出了,另外的环境变量是因为我们这里直接把 cm-demo1
给注入锦鲤啊了,所以把他们整个键值给输出出来了,这也是符合预期的, 另外我们可以使用 ConfigMap
来这只命令行参数,ConfigMap
也可以被用来设置容器中的命令货参数值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 后会输出如下信息
1 2 $ kubectl logs testcm2-pod localhost 3306
另外一种方式是非常常见的使用 ConfigMap
的方式: 通过数据卷使用,在数据卷里面使用 ConfigMap
, 就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apiVersion: v1 kind: Pod metadata: name: testcm3-pod spec: containers: - name: testcm3 image: busybox command: [ "/bin/sh" , "-c" , "cat /etc/config/redis.conf" ] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: cm-demo2
运行这个 Pod, 查看日志
1 2 3 $ kubectl logs testcm3-pod host=127.0.0.1 port=6379
也还在 ConfigMap
值被映射的数据卷里去控制路径,如下 Pod
定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion: v1 kind: Pod metadata: name: testcm4-pod spec: containers: - name: testcm4 image: busybox command: [ "/bin/sh" ,"-c" ,"cat /etc/config/path/to/msyql.conf" ] volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: cm-demo1 items: - key: mysql.conf path: path/to/msyql.conf
运行这个 Pod
,查看日志
1 2 3 $ kubectl logs testcm4-pod host=127.0.0.1 port=3306
需要注意的是,当 ConfigMap
以数据卷的形式挂载进 Pod
的时候,这时更新 ConfigMap
Pod
內挂载的配置信息会热更新,这时可以增加一些监测配置文件变更的脚本,然后 reload
对应服务