在Kubernetes中,资源对象和信息都存储在Etcd中,但是对于某一个服务的配置该如何管理了?
当然你可以在镜像打包的时候,将配置文件直接配置打包到镜像里面,这样确实可以达到目的。
但是大部分的容器是在运行之后需要改配置,每次都重新打包确实会是一个不小的工作。
当然可以通过文件映射或者环境变量来改变容器的配置,这是稍微比较不错的做法。
但是如果在大规模集群中,容器的配置管理将是一个非常麻烦的事项。
Kubernetes从1.2开始提供一种统一的应用配置管理方案——ConfigMap。
ConfigMap将应用所需的配置信息与程序进行分离,这样配置信息可以更好的被多次复用。
在Kubernetes中,配置信息会被封装成一个个资源资源对象,这样便于集中管理和使用。
如果你需要修改配置,那么只需要修改ConfigMap的引用对象或者直接修改ConfigMao资源对象的配置就可以了。
1.ConfigMap
ConfigMap供容器使用的典型用法如下:
(1)生成为容器内的环境变量
(2)以Volume的形式挂载为容器内部的文件或者目录
ConfigMap以一个或多个key:value的形式保存在Kubernetes系统中供应用使用,
既可以用于表示一个变量的值(例如apploglevel=info),也可以用于表示一个一个完整配置文件的内容(server.xml=<?xml>)。
2.创建ConfigMap资源对象
(1)通过yaml配置文件方式创建
apiVersion: v1 kind: ConfigMap metadata: name: cm-appvars data: apploglevel: info #将值指定为字符串 appdatadir: /var/data #指定为文件名或者目录
ConfigMap是以键值(key=value)对的形式保存配置信息,key可以是任何不重复字符串,value可以是字符串也可以是文件名目录名。
#创建configmap资源对象 root@console:/k8s-script/chapter02# kubectl create -f cm-appvars.yaml configmap "cm-appvars" created #查看configMap资源对象 root@console:/k8s-script/chapter02# kubectl get configmap NAME DATA AGE cm-appvars 2 15s #查看资源对象的详细信息 root@console:/k8s-script/chapter02# kubectl describe configmap/cm-appvars Name: cm-appvars Namespace: default Labels: <none> Annotations: <none> Data ==== appdatadir: ---- /var/data apploglevel: ---- info Events: <none> #以yaml的格式输出资源对象的详细 root@console:/k8s-script/chapter02# kubectl get configmap/cm-appvars -o yaml apiVersion: v1 data: appdatadir: /var/data apploglevel: info kind: ConfigMap metadata: creationTimestamp: 2019-07-08T03:27:17Z name: cm-appvars namespace: default resourceVersion: "117304" selfLink: /api/v1/namespaces/default/configmaps/cm-appvars uid: 49baf4d4-a130-11e9-9c97-52540095a842
Kubernetes还支持将配置文件的内容定义为ConfigMap的用法。
apiVersion: v1 kind: ConfigMap metadata: name: cm-appconfigfiles data: key-config.json: '{ "server":"192.168.1.1", "server_port":8038, "password":"666666", "timeout":300, "method":"aes-256-cfb", "fast_open": false }'
相关操作:
#创建ConfigMap资源对象 root@console:/k8s-script/chapter02# kubectl create -f cm-appconfigfiles.yaml configmap "cm-appconfigfiles" created #查看ConfigMap资源对象 root@console:/k8s-script/chapter02# kubectl get configmap NAME DATA AGE cm-appconfigfiles 1 16s cm-appvars 2 28m #查看资源对象的详细信息 root@console:/k8s-script/chapter02# kubectl describe configmap/cm-appconfigfiles Name: cm-appconfigfiles Namespace: default Labels: <none> Annotations: <none> Data ==== key-config.json: ---- { "server":"192.168.1.1", "server_port":8038, "password":"666666", "timeout":300, "method":"aes-256-cfb", "fast_open": false } Events: <none>
(2)通过kubectl命令行方式创建
不使用yaml文件,直接通过kubectl create configmap也可以创建ConfigMap,
可以使用参数--from-file或--from-literal指定内容,并且可以在一行命令中指定多个参数。
A.通过--from-file参数从文件中进行创建,可以指定key的名称,也可以在一个命令行中创建多个key的ConfigMap。
root@console:~# kubectl create configmap cm-ssh-config.xml --from-file=ssh_config configmap "cm-ssh-config.xml" created root@console:~# kubectl get configmap NAME DATA AGE cm-appconfigfiles 1 2h cm-appvars 2 2h cm-ssh-config.xml 1 17s
B.通过--from-file参数从目录中进行创建,该目录的每个配置文件名都被设置为key,文件的内容被设置为value。
root@console:~# kubectl create configmap cm-appconf --from-file=configfiles configmap "cm-appconf" created root@console:~# kubectl describe configmap cm-appconf Name: cm-appconf Namespace: default Labels: <none> Annotations: <none> Data ==== server.xml: ---- logging.properties: ---- Events: <none>
C.--from-literal从文本中进行创建,直接将指定的key#=value#创建为ConfigMap。
root@console:~# kubectl create configmap cm-appenv --from-literal=loglevel=info --from-literal=appdatadir=/var/data configmap "cm-appenv" created root@console:~# kubectl describe configmap/cm-appenv Name: cm-appenv Namespace: default Labels: <none> Annotations: <none> Data ==== appdatadir: ---- /var/data loglevel: ---- info Events: <none>
3.在Pod中使用ConfigMap
(1)通过环境变量使用ConfigMap
apiVersion: v1 kind: Pod metadata: name: cm-test-pod spec: containers: - name: cm-test image: busybox:latest command: ["/bin/sh","-c","env|grep APP"] env: - name: APPLOGLEVEL valueFrom: configMapKeyRef: name: cm-appvars key: apploglevel - name: APPDATADIR valueFrom: configMapKeyRef: name: cm-appvars key: appdatadir
在创建cm-test-pod这个Pod的时候,将cm-appvars这个configmap中内容以环境变量的方式进行引入。
并且在容器进行启动的时候显示这个两个环境变量的值。
root@console:/k8s-script/chapter02# kubectl create -f cm-test-pod.yaml pod "cm-test-pod" created #查看日志,确定已经引入到了环境变量中 root@console:/k8s-script/chapter02# kubectl logs cm-test-pod APPDATADIR=/var/data APPLOGLEVEL=info
从kubernetes1.6版本开始,引入了一个新的字段envFrom,
实现在Pod环境内直接将ConfigMap中所定义的key=value自动生成环境变量。
apiVersion: v1 kind: Pod metadata: name: cm-test-pod2 spec: containers: - name: cm-test image: busybox:latest imagePullPolicy: Never command: ["/bin/sh","-c","env"] envFrom: - configMapRef: name: cm-appvars
相关操作:
#创建Pod root@console:/k8s-script/chapter02# kubectl create -f cm-test-pod2.yaml pod "cm-test-pod2" created #查看环境变量 root@console:/k8s-script/chapter02# kubectl log cm-test-pod2|grep app apploglevel=info appdatadir=/var/data
(2)通过volumeMount使用ConfigMap
apiVersion: v1 kind: Pod metadata: name: cm-test-app spec: volumes: - name: serverxml configMap: name: cm-appconf items: - key: key-serverxml path: server.xml - key: key-logging.properties path: logging.properties containers: - name: cm-test-app image: kubeguide/tomcat-app:v1 ports: - containerPort: 8080 volumeMounts: - name: serverxml mountPath: /configfiles
4.使用ConfigMap的限制条件
(1)ConfigMap必须在Pod之前创建
(2)COnfigMap受Namespace限制,只能处于相同Namespaces中的Pod可以引用它
(3)ConfigMap中的配额管理还未能实现
(4)kubelet只支持可以被API Server管理的Pod使用ConfigMap。
kubelet在本Node上通过--manifest-url或--config自动创建的静态Pod将无法引用ConfigMap
(5)在Pod对ConfigMap进行挂载(volumeMount)操作时,容器内部只能挂载为“目录”,无法挂载为“文件”。
在挂载到容器内部后,目录中将包含ConfigMap定义的每个item,如果该目录下原来还有其它文件,
则容器内的该目录将会被挂载的ConfigMap覆盖。如果应用程序需要保留原来的其它文件,则需要进行额外的处理。
可以将ConfigMap挂载到容器内部的临时目录,再通过启动脚本将配置文件复制或链接到应用所用的实际配置目录下。