前言
前⾯我们深入学习了 Servie 的使⽤, Service 是 Kubernetes 系统中⾮常重要的⼀个核⼼概念,这节课我们来学习另外⼀个⾮常重要的资源对象: ConfigMap
引入
应用部署的一个最佳实践是将应用所需的配置信息与程序进行分离,这样可以使得应用程序被更好地复用,通过不同的配置也能实现更灵活的功能。
将应用打包为容器镜像后,可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入,但在大规模容器集群的环境中,对多个容器进行不同的配置将变得非常复杂。
ConfigMap 给我们提供了向容器中注⼊配置信息的能⼒,不仅可以⽤来保存单个属性,也可以⽤来保存整个配置⽂件,⽐如我们可以⽤来配置⼀个 redis 服务的访问地址,也可以⽤来保存整个 redis 的配置⽂件。
创建
ConfigMap 资源对象使⽤ key-value 形式的键值对来配置数据,这些数据可以在 Pod ⾥⾯使⽤, ConfigMap 和我们后⾯要讲到的 Secrets ⽐较类似,⼀个⽐较⼤的区别是 ConfigMap 可以⽐较⽅便的处理⼀些⾮敏感的数据,⽐如密码之类的还是需要使⽤ Secrets 来进⾏管理。我们来举个例⼦说明下 ConfigMap 的使⽤⽅法:
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 属性下⾯进⾏配置,前两个被⽤来保存单个属性,后⾯⼀个被⽤来保存⼀个配置⽂件。
当然同样的我们可以使⽤ kubectl create -f xx.yaml
来创建上⾯的 ConfigMap 对象,但是如果我们不知道怎么创建 ConfigMap 的话,不要忘记 kubectl 是我们最好的⽼师,可以使⽤ kubectl createconfigmap -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>
我们可以看到两个 key 是 testcm ⽬录下⾯的⽂件名称,对应的 value 值的话就是⽂件内容,这⾥值得注意的是如果⽂件⾥⾯的配置信息很⼤的话,describe 的时候可能不会显示对应的值,要查看键值的话,可以使⽤如下命令:
$ 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 对象:
$ 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
参数传递配置信息,同样的,这个参数可以使⽤多次,格式如下:
$ 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