ConfigMap对象用于为容器中的应用提供配置数据以定制程序的行为,不过敏感的配置信息,例如密钥、证书等通常由Secret对象来进行配置。他们将相应的配置信息保存于对象中,而后在pod资源上以存储卷的形式将其挂载并获取相关的配置,以实现配置与镜像文件的解耦。ConfigMap对象将配置数据以键值对的形式进行存储,这些数据可以在pod对象中使用或为系统组件提供配置,例如控制器对象等。不过,无论应用程序如何使用ConfigMap对象中的数据,用户都完全可以通过在不同的环境中创建名称相同但内存不同的ConfigMap对象,从而为不同环境中同一功能的pod资源提供不同的配置信息,实现应用于配置的灵活勾兑。
一、创建ConfigMap对象
COnfigMap既可以使用命令create创建也可以使用资源配置清单创建
$ kubectl create configmap map-name data-source 其中,map-name为configmap对象的名称,data-source为数据源,它可以通过直接值、文件或目录来获取。无论是哪一种数据源供给方式,都要转换为configmap对象的k-v数据,
其中k由用户在命令行给出或是文件数据源的文件名,它仅能由数字、字母、连接号和点号组成,而v则是直接值或文件数据源的内容
1、利用直接值创建
使用“--from-literal”选项可在命令行直接给出键值对来创建configmap对象,重复使用此选项则可以传递多个键值对。
$ kubectl create configmap test --from-literal=key-name1=value1 --from-literal=key-name2=value2
使用“get configmap”命令可用于查看创建的test对象的相关信息:
[root@master ~]# kubectl get configmap test -o yaml apiVersion: v1 data: key1: value1 key2: value2 kind: ConfigMap metadata: creationTimestamp: "2019-08-19T06:00:43Z" name: test namespace: default resourceVersion: "231099" selfLink: /api/v1/namespaces/default/configmaps/test uid: ae14bc78-c246-11e9-827a-000c29b9991f
此类方式提供的数据量有限,一般是在仅通过有限的几个数据项即可为pod资源提供足够的配置信息时使用。
2、基于文件创建
为“kubectl create configmap”命令使用“--from-file”选项即可基于文件内容来创建configmap对象,可重复使用多个“--from-file”选项来传递多个文件内容:
$ kubectl create configmap test1 --from-file=./test1 $ cat ./test1 server { listen 80; server_name wiki.test.com; access_log /data/logs/nginx/wiki.test.access.log; error_log /data/logs/nginx/wiki.test.error.log; location / { proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://192.168.10.54:8090; } }
这种方式创建的configmap对象,其数据存储的键为文件路径的基名,值为文件内容:
[root@master configmap]# kubectl get configmap -o yaml apiVersion: v1 items: - apiVersion: v1 data: test1: "server { listen 80; server_name wiki.test.com; access_log /data/logs/nginx/wiki.test.access.log; error_log /data/logs/nginx/wiki.test.error.log; location / { proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://192.168.10.54:8090; } } " kind: ConfigMap metadata: creationTimestamp: "2019-08-19T06:10:56Z" name: test1 namespace: default resourceVersion: "231991" selfLink: /api/v1/namespaces/default/configmaps/test1 uid: 1b6ba6b1-c248-11e9-827a-000c29b9991f kind: List metadata: resourceVersion: "" selfLink: ""
如果需要自行指定键名,则可在“--from-file”选项中直接指定自定义的键:
$ kubectl create cm test2 --from-file=serverconfig=./test1 [root@master configmap]# kubectl get cm test2 -o yaml apiVersion: v1 data: serverconfig: "server { listen 80; server_name wiki.test.com; access_log /data/logs/nginx/wiki.test.access.log; error_log /data/logs/nginx/wiki.test.error.log; location / { proxy_set_header Host $host:$server_port; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://192.168.10.54:8090; } } " kind: ConfigMap metadata: creationTimestamp: "2019-08-19T06:42:54Z" name: test2 namespace: default resourceVersion: "234767" selfLink: /api/v1/namespaces/default/configmaps/test2 uid: 92cfc599-c24c-11e9-827a-000c29b9991f
3、基于目录创建
如果配置文件数量较多且存储于有限的目录中时,kubectl还提供了基于目录直接将多个文件分别收纳为键值数据的configmap资源创建方式。将“--from-file”选项后面所跟的路径指向一个目录路径就能将目录下的所有文件一同创建于同一configmap资源中:
$ kubectl create cm test3 --from-file=test3=./ [root@master configmap]# kubectl describe cm test3
Name: test3
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
test1:
----
server {
listen 80;
server_name wiki.test.com;
access_log /data/logs/nginx/wiki.test.access.log;
error_log /data/logs/nginx/wiki.test.error.log;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://192.168.10.54:8090;
}
}
test2:
----
server {
listen 80;
server_name apidoc.test.com;
access_log /data/logs/nginx/apidoc.access.log;
error_log /data/logs/nginx/apidoc.error.log;
location / {
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://192.168.10.54:9013;
}
}
Events: <none>
PS: describe命令和get -o yaml命令都可显示由文件创建而成的键及其值,不过两者使用的键和值之间的分隔符不同。
4、使用清单创建
基于配置文件创建configmap资源时,它所使用的字段包括通常的apiVersion、kind、metadata字段,以及用于存储数据的关键字段data:
[root@master configmap]# cat cm1.yaml apiVersion: v1 kind: ConfigMap metadata: name: cm1 namespace: testing data: log_level: INFO log_file: /var/log/test.log
如果其值来自于文件内容时,则使用配置文件创建configmap资源的便捷性还不如直接通过命令行的方式,因此,建议直接使用命令行加载文件或目录的方式进行创建。为了便于配置留存,可以在创建完成后使用get -o yaml命令获取到相关信息后再进行编辑留存。
二、向pod环境变量传递configmap对象键值数据
pod资源的环境变量值引用configmap对象的数据时,通过在env字段中为valueFrom内嵌configMapKeyRef对象即可实现:
valueFrom:
configMapKeyRef:
name:
key:
optional:
其中,字段name的值为要引用的ConfigMap对象的名称,字段key可用于指定要引用ConfigMap对象中某键的键名,而字段optional则用于为当前pod资源指明此引用是否为可选。
apiVersion: v1 kind: ConfigMap metadata: name: cm-test namespace: testing data: httpd_port: "8080" verbose_level: "-vv" --- apiVersion: v1 kind: Pod metadata: name: cm-pod namespace: testing spec: containers: - name: nginx image: nginx:1.12-alpine env: - name: HTTPD_PORT valueFrom: configMapKeyRef: name: cm-test key: httpd_port - name: HTTPD_LOG_VERBOSE valueFrom: configMapKeyRef: name: cm-test key: verbose_level
pod资源还支持在容器中使用envFrom字段直接将configmap资源中的所有键值一次性地完成导入:
apiVersion: v1 kind: ConfigMap metadata: name: cm-test namespace: testing data: httpd_port: "8080" verbose_level: "-vv" --- apiVersion: v1 kind: Pod metadata: name: cm-pod namespace: testing spec: containers: - name: nginx image: nginx:1.12-alpine envFrom: - prefix: HTCFG_ configMapRef: name: cm-test optional: false
envFrom字段值是对象列表,可用于同时从多个configmap对象导入键值数据。为了避免从多个configmap引用键值数据时产生键名冲突,可以在每个引用中将被导入的键使用prefix字段(可选)指定一个特定的前缀,如“HTCFG_”,于是,configmap对象中的httpd_port键将称为pod对象中名为HTCFG_httpd_port的变量。
三、configmap存储卷
1、挂载整个存储卷
关联为pod资源的存储卷时,configmap对象中的每个键都对应地表现为一个文件,键名转为文件名,而键值则为相应文件的内容,即便是通过直接值创建的键值数据,也一样表现为文件视图。挂载于容器上之后,由键值数据表现出的文件位于挂载点目录中,容器中的进程可直接读取这些文件的内容。配置pod资源时,基于存储卷的方式引用configmap对象时,仅需要指明存储卷名称及要引用的configmap对象名称即可:
apiVersion: v1 kind: Pod metadata: name: cm-vol namespace: testing spec: containers: - name: vol-nginx image: nginx:1.12-alpine volumeMounts: - name: ngxconfig mountPath: /etc/nginx/conf.d readOnly: true volumes: - name: ngxconfig configMap: name: ngx-cm
2、挂载存储卷中的部分键值
如果在configmap中有多个键值,当前只挂载部分键值,则可:
apiVersion: v1 kind: Pod metadata: name: cm-vol namespace: testing spec: containers: - name: vol-nginx image: nginx:1.12-alpine volumeMounts: - name: ngxconfig mountPath: /etc/nginx/conf.d readOnly: true volumes: - name: ngxconfig configMap: name: ngx-cm items: - key: test.conf path: test2.conf mode: 0644 - key: test1.conf path: test1.conf
其中,key:要引用的键名称,必选字段;path:对应的键于挂载点目录中生成的文件的相对路径,可以不同于键名称,必选字段;mode:文件的权限模型,可用范围:0-0777,默认0644
3、独立挂载存储卷中的键值
前述方式中,无论是装载所有文件还是部分文件,挂载点目录下原有的文件都会被隐藏。对于期望configmap对象提供的配置文件补充于挂载点目录下的需求来说,这种方式显然难以如愿。事实上,此种需求可以通过容器的volumeMouts字段中使用subPath字段来解决,它可以支持用户从存储卷挂载单个文件或单个目录而非整个存储卷。
apiVersion: v1 kind: Pod metadata: name: cm-vol namespace: testing spec: containers: - name: vol-nginx image: nginx:1.12-alpine volumeMounts: - name: ngxconfig mountPath: /etc/nginx/conf.d/test.conf subPath: test.conf readOnly: false - name: ngxconfig mountPath: /etc/nginx/test1.conf subPath: test1.conf volumes: - name: ngxconfig configMap: name: ngx-cm