了解kubernetes的ConfigMap

许多服务在启动/运行时需要读取配置文件、环境变量或命令行参数等信息,我们可以很方便地使用ConfigMap为pod完成这些配置信息的设置与更新。通过下面的例子来了解下ConfigMap吧。

生成ConfigMap

有两个文件info1 info2保存了配置信息

1
2
3
4
5
6
7
8
ming@ming-master:~/temp/configmap$ ls
info1 info2
ming@ming-master:~/temp/configmap$ cat info1
name=mengyuan
corp=tenxcloud
ming@ming-master:~/temp/configmap$ cat info2
name=wanglei
corp=tenxcloud

执行kubectl create configmap conf --from-file=.命令生成ConfigMap
conf是指定的ConfigMap的名字,--from-file=.指定了当前目录,只会将当前目录下的文件做为配置文件而不去读子目录。也可以从文件或命令行中取得配置,详细参考官网

1
2
ming@ming-master:~/temp/configmap$ kubectl create configmap conf --from-file=.
configmap "conf" created

然后使用kubectl describe configmap查看下刚生成的ConfigMap

1
2
3
4
5
6
7
8
9
10
ming@ming-master:~/temp/configmap$ kubectl describe configmap conf
Name: conf
Namespace: default
Labels: <none>
Annotations: <none>

Data
====
info1: 29 bytes
info2: 28 bytes

或使用kubectl get configmap *** -o yaml查看详细信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ming@ming-master:~/temp/configmap$ kubectl get configmap conf -o yaml
apiVersion: v1
data:
info1: |
name=mengyuan
corp=tenxcloud
info2: |
name=wanglei
corp=tenxcloud
kind: ConfigMap
metadata:
creationTimestamp: 2016-05-06T19:09:22Z
name: conf
namespace: default
resourceVersion: "4578"
selfLink: /api/v1/namespaces/default/configmaps/conf
uid: 0aa0a417-13be-11e6-8ead-000c2911326e

在pod中使用ConfigMap

ConfigMap生成后如何在pod中使用呢,继续使用上面的例子进行说明。假设我们的容器服务需要info1与info2两个配置文件。
pod文件如下,注意volumeMountsvolumes段,volumeMounts.name要与volumes.name一致,volumes.configMap.name与上面创建的ConfigMap名字一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ming@ming-master:~/temp/configmap$ cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
name: testconfigmap
spec:
containers:
- name: testconfigmap
image: index.tenxcloud.com/tenxcloud/ubuntu
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: conf
restartPolicy: Never

启动pod

1
2
ming@ming-master:~/temp/configmap$ kubectl create -f pod.yaml 
pod "testconfigmap" created

启动成功,到slave中的容器看下info1 info2两个文件是否正常

1
2
3
4
5
6
7
8
9
10
11
ming@ming-slave:~$ docker ps |grep ubuntu.*testconfigmap
9431b36fa6f6 index.tenxcloud.com/tenxcloud/ubuntu "/run.sh" About a minute ago Up About a minute k8s_testconfigmap.469034b4_testconfigmap_default_1f88674f-13c5-11e6-8ead-000c2911326e_b0994daa
ming@ming-slave:~$ docker exec -it k8s_testconfigmap.469034b4_testconfigmap_default_1f88674f-13c5-11e6-8ead-000c2911326e_b0994daa /bin/bash
root@testconfigmap:/# ls /etc/config/
info1 info2
root@testconfigmap:/# cat /etc/config/info1
name=mengyuan
corp=tenxcloud
root@testconfigmap:/# cat /etc/config/info2
name=wanglei
corp=tenxcloud

bingo!

更进一步:热更新配置文件

可以使用kubectl replace命令来更新ConfigMap,但此命令格式为kubectl replace -f FILENAME [flags]-f后面需要指定ConfigMap的配置文件
而上面是用--from-file指定目录取得的配置文件,更新文件后如何更新ConfigMap还没有查到正常的方法,下面说下比较恶心的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ming@ming-master:~/temp$ kubectl get configmap conf -o yaml
apiVersion: v1
data:
info1: |
name=mengyuan
corp=tenxcloud
info2: |
name=wanglei
corp=tenxcloud
kind: ConfigMap
metadata:
creationTimestamp: 2016-05-06T19:09:22Z
name: conf
namespace: default
resourceVersion: "5148"
selfLink: /api/v1/namespaces/default/configmaps/conf
uid: 0aa0a417-13be-11e6-8ead-000c2911326e

取得ConfigMap信息保存到文件再删除/添加内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ming@ming-master:~/temp$ cat /tmp/configmap 
apiVersion: v1
data:
info1: |
name=mengyuan
corp=tenxcloud
add new line 1
info2: |
name=wanglei
corp=tenxcloud
add new line 2
kind: ConfigMap
metadata:
name: conf
namespace: default

然后再使用kubectl replace修改ConfigMap

1
2
ming@ming-master:~/temp$ kubectl replace -f /tmp/configmap 
configmap "conf" replaced

成功,切回slave看下配置文件

1
2
3
4
5
6
7
8
root@testconfigmap:/# cat /etc/config/info1
name=mengyuan
corp=tenxcloud
add new line 1
root@testconfigmap:/# cat /etc/config/info2
name=wanglei
corp=tenxcloud
add new line 2

修改成功

一些限制及问题

  • 当create ConfigMap时–from-file指定的是目录时,在更新文件后,如何正常的更新ConfigMap
  • 如何为有子目录的配置目录生成ConfigMap(子目录中也有配置文件)
  • 配置文件不能实时更新,在master上使用kubectrl replacekubectl edit更新configmap后,相关pod内的文件延迟更新(测试两次30s,1min)(下一次syncLoop时,才会更新配置
  • 环境变量更新后旧Pod内环境变量不会改变,新启动的Pod是最新的环境变量
  • 配置文件名(做为configmap.data中的key名字)有限制,Data contains the configuration data. Each key must be a valid DNS_SUBDOMAIN with an optional leading dot(可以有横线-.小写字母)

参考资料