Kubernetes进阶实战读书笔记:配置容器应用(configmap)
一、向POD环境变量传递configmap对象键值数据
1、资源清单
[root@master chapter8]# cat cat configmap-env.yaml cat: cat: No such file or directory apiVersion: v1 kind: ConfigMap metadata: name: busybox-httpd-config namespace: default data: httpd_port: "8080" verbose_level: "-vv" --- apiVersion: v1 kind: Pod metadata: name: configmap-env-demo namespace: default spec: containers: - image: busybox name: busybox-httpd command: ["/bin/httpd"] args: ["-f","-p","$(HTTPD_PORT)","$(HTTPD_LOG_VERBOSE)"] env: - name: HTTPD_PORT valueFrom: configMapKeyRef: name: busybox-httpd-config key: httpd_port - name: HTTPD_LOG_VERBOSE valueFrom: configMapKeyRef: name: busybox-httpd-config key: verbose_level optional: true
2、创建及验证
[root@master chapter8]# kubectl apply -f configmap-env.yaml configmap/busybox-httpd-config created pod/configmap-env-demo created
[root@master chapter8]# kubectl get pod|grep configmap configmap-env-demo 1/1 Running 0 40s
[root@master chapter8]# kubectl exec configmap-env-demo ps aus kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. PID USER TIME COMMAND 1 root 0:00 /bin/httpd -f -p 8080 -vv 6 root 0:00 ps aus
3、pod.spec.containers.env.valueFrom字段详解
[root@master chapter8]# kubectl explain pod.spec.containers.env.valueFrom KIND: Pod VERSION: v1 RESOURCE: valueFrom <Object> DESCRIPTION: Source for the environment variable's value. Cannot be used if value is not empty. EnvVarSource represents a source for the value of an EnvVar. FIELDS: configMapKeyRef <Object> #configMap对象中的特定key Selects a key of a ConfigMap. fieldRef <Object> #当前pod资源的指定字段、目前支持使用的字段包括metadata.name、metadata.name、metadata.namespace、metadata.labels、sepc.nodeName、spec.serviceAccount、sepc.nodeName、status.podIP、status.hostIP Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. resourceFieldRef <Object> #当前容器的特定系统资源的最小值(配额)或最大值(限额)、目前支持的引用包括limits.cpu、limits.memory、limits.ephemeral-storage、requests.cpu、requests.memory、requests.ephemeral-storage Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. secretKeyRef <Object> #secret对象中的特定key Selects a key of a secret in the pod's namespace
如果键名中使用了连接线"-"、那么在转换为变量名时、连接线将被自动替换为下划线"_"
3、envfrom:直接将configmap资源中的所有键值一次性地完成导入
1、资源清单
[root@master chapter8]# cat configmap-envfrom-pod.yaml apiVersion: v1 kind: Pod metadata: name: configmap-envfrom-demo namespace: default spec: containers: - image: busybox name: busybox-httpd command: ["/bin/httpd"] args: ["-f","-p","$(HTCFG_httpd_port)","$(HTCFG_verbose_level)"] envFrom: - prefix: HTCFG_ configMapRef: name: busybox-httpd-config optional: false
2、创建验证
[root@master chapter8]# kubectl apply -f configmap-envfrom-pod.yaml pod/configmap-envfrom-demo created [root@master chapter8]# kubectl get pod|grep configmap configmap-env-demo 1/1 Running 0 3m46s configmap-envfrom-demo 1/1 Running 0 30s [root@master chapter8]# kubectl exec configmap-envfrom-demo printenv kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=configmap-envfrom-demo HTCFG_verbose_level=-vv HTCFG_httpd_port=8080 ......
二、configmap存储卷
1、挂载整个存储卷
资源清单
[root@master chapter8]# cat configmap-volume-pod.yaml apiVersion: v1 kind: Pod metadata: name: configmap-volume-demo namespace: default spec: containers: - image: nginx:alpine name: web-server volumeMounts: - name: ngxconfig mountPath: /etc/nginx/conf.d/ readOnly: true volumes: - name: ngxconfig configMap: name: nginx-config-files
创建
[root@master chapter8]# kubectl apply -f configmap-volume-pod.yaml pod/configmap-volume-demo created [root@master chapter8]# kubectl get cm NAME DATA AGE busybox-httpd-config 2 19h nginx-config-files 3 7s special-config 2 23h [root@master chapter8]# kubectl get pod|grep configmap-volume-demo configmap-volume-demo 1/1 Running 0 11m
2、验证挂载整个存储卷
[root@master chapter8]# POD_IP=$(kubectl get pods configmap-volume-demo -o go-template={{.status.podIP}}) [root@master chapter8]# curl http://${POD_IP}:8080/nginx-status
Active connections: 1
server accepts handled requests
8 8 8
Reading: 0 Writing: 1 Waiting: 0
[root@master chapter8]# kubectl exec configmap-volume-demo ls /etc/nginx/conf.d/ kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. myserver-gzip.cfg myserver-status.cfg myserver.conf [root@master chapter8]# kubectl exec configmap-volume-demo -- nginx -T 2020/09/02 02:09:44 [warn] 28#28: duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4 nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok # configuration file /etc/nginx/nginx.conf: user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; } # configuration file /etc/nginx/mime.types: types { text/html html htm shtml; text/css css; ...... } # configuration file /etc/nginx/conf.d/myserver.conf: server { listen 8080; server_name www.ikubernetes.io; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; } } # configuration file /etc/nginx/conf.d/myserver-gzip.cfg: gzip on; gzip_comp_level 5; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/html text/css application/xml text/javascript; # configuration file /etc/nginx/conf.d/myserver-status.cfg: location /nginx-status { stub_status on; access_log off; } nginx: configuration file /etc/nginx/nginx.conf test is successful
由上面两个命令的结果可见、nginx-config-files中的三个文件都被添加到了容器中、并且实现了由容器应用nginx加载并生效
3、挂在存储卷重的部分键值
资源清单
[root@master chapter8]# cat configmap-volume-pod-2.yaml apiVersion: v1 kind: Pod metadata: name: configmap-volume-demo-2 namespace: default spec: containers: - image: nginx:alpine name: web-server volumeMounts: - name: ngxconfig mountPath: /etc/nginx/conf.d/ readOnly: true volumes: - name: ngxconfig configMap: name: nginx-config-files items: - key: myserver.conf path: myserver.conf mode: 0644 - key: myserver-gzip.cfg path: myserver-compression.cfg
4、pod.spec.volumes.configMap.items字段详解
[root@master chapter8]# kubectl explain pod.spec.volumes.configMap.items KIND: Pod VERSION: v1 RESOURCE: items <[]Object> DESCRIPTION: If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. Maps a string key to a path within a volume. FIELDS: key <string> -required- #要引用的键名称、必选字段 The key to project. mode <integer> #文件的权限模型、可用范围为0到0777 Optional: mode bits to use on this file, must be a value between 0 and 0777. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. path <string> -required- #对应的键于挂载点目录中生成的文件的相对路径、可以不同与键名称、必选字段 The relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'.
上面的配置示例中myserver-gzip.cfg映射成了myserver-compression.cfg文件、而myserver.conf则保持了与键名同名、并明确指定使用0644的权限从而达成了仅装载部分文件至容器之目的
5、独立挂在存储卷重中的键值
1、资源清单
[root@master chapter8]# cat configmap-volume-pod-3.yaml apiVersion: v1 kind: Pod metadata: name: configmap-volume-demo-3 namespace: default spec: containers: - image: nginx:alpine name: web-server volumeMounts: - name: ngxconfig mountPath: /etc/nginx/conf.d/myserver.conf subPath: myserver.conf readOnly: true - name: ngxconfig mountPath: /etc/nginx/conf.d/myserver-status.cfg subPath: myserver-status.cfg readOnly: true volumes: - name: ngxconfig configMap: name: nginx-config-files
2、创建验证
[root@master chapter8]# kubectl apply -f configmap-volume-pod-3.yaml pod/configmap-volume-demo-3 created [root@master chapter8]# kubectl exec configmap-volume-demo-3 ls /etc/nginx/conf.d kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead. default.conf myserver-status.cfg myserver.conf
三、容器应用重载新配置
1、使用configmap的优势
相较于环境变量来说、使用configmap资源为容器应用提供配置的优势之一在于其支持容器应用动态更新其配置:用户直接更新configmap对象、然后由容器应用重载其配置文件即可
[root@master chapter8]# kubectl exec -it configmap-volume-demo -- ls -lA /etc/nginx/conf.d total 0 drwxr-xr-x 2 root root 79 Sep 2 02:00 ..2020_09_02_02_00_39.612704422 lrwxrwxrwx 1 root root 31 Sep 2 02:00 ..data -> ..2020_09_02_02_00_39.612704422 lrwxrwxrwx 1 root root 24 Sep 2 02:00 myserver-gzip.cfg -> ..data/myserver-gzip.cfg lrwxrwxrwx 1 root root 26 Sep 2 02:00 myserver-status.cfg -> ..data/myserver-status.cfg lrwxrwxrwx 1 root root 20 Sep 2 01:59 myserver.conf -> ..data/myserver.conf
细心的读者或许已经发现、挂在configmap存储卷的挂载点目录中的文件是符号链接,它们指向了当前目录中"..data"而"..data" 也是符号链接、它只指向了名字形如"..2020_09_02_02_00_39.612704422"的目录、这个目录才是存储卷的真正挂载点
2、两级符号链接设定的好处
在引用的configmap对象中的数据发生改变时、它将被被重新挂在至一个新的数据临时目录下,而后"..data"将指向此新的挂载点、便达到了同时更新存储卷上下文件数据之目的例如用:kubectl edit cm nginx-config-files编辑如下内容:
[root@master chapter8]# kubectl edit cm nginx-config-files configmap/nginx-config-files edited
修改后查看
[root@master chapter8]# kubectl exec -it configmap-volume-demo -- ls -lA /etc/nginx/conf.d total 0 drwxr-xr-x 2 root root 79 Sep 2 03:35 ..2020_09_02_03_35_24.756696013 lrwxrwxrwx 1 root root 31 Sep 2 03:35 ..data -> ..2020_09_02_03_35_24.756696013 lrwxrwxrwx 1 root root 24 Sep 2 02:00 myserver-gzip.cfg -> ..data/myserver-gzip.cfg lrwxrwxrwx 1 root root 26 Sep 2 02:00 myserver-status.cfg -> ..data/myserver-status.cfg lrwxrwxrwx 1 root root 20 Sep 2 01:59 myserver.conf -> ..data/myserver.conf
重载nginx服务
[root@master chapter8]# kubectl exec configmap-volume-demo -- nginx -s reload 2020/09/02 03:36:35 [warn] 77#77: duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4 nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/conf.d/myserver-gzip.cfg:4 2020/09/02 03:36:35 [notice] 77#77: signal process started
此时、如果于容器之外的位置访问/nginx-status页面的请求时被拒绝的、则表明新配置已然生效,如下面的命令及其结果所示
[root@master chapter8]# curl http://${POD_IP}:8080/nginx-status <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.19.2</center> </body> </html>
然而、需要注意的是、对于不支持配置文件重载操作的容器应用来说、只有那些在configmap对象更新后创建的POD资源中的容器会应用到新配置、此时如果不重启旧有的容器、则会导致配置不一致的问题,即使对于支持重载操作的应用来说,由于新的配置信息并非同步推送进所有的容器中、而且各容器的重载操作也未必能同时进行、因此在更新时、短时间内仍然存在配置不一致的现象
另外使用独立挂在存储卷重的文件的容器、其挂在配置文件的方式并非以两级链接的方式、因此存储卷无法确保所有的挂载的文件可以被同事更新至容器中
因此为了确保配置信息的一致性、目前这种类型的挂在不支持文件更新操作
四、使用configmap资源的注意事项
在POD资源中调用configmap兑现更需要注意以下几个问题:
1、以存储卷方式引用的configmap必须事先于pod存在、除非在pod中将他们全部标记为"optional"否则将会导致pod无法正常启动的错误;同样、即使存在configmap、在引用的键不存在时,也会导致一样的错误
2、当以环境变量方式注入的configmap中的键不存在时会被忽略、pod可以正常启动、但错误引用的信息会以"lnvalidVariableNames"事件记录与日志中
3、configmap是名称空间级的资源、因此、引用它的pod必须处于同一名称空间中
4、kubectl不支持引用kubernetes API server 上存在的configmap、这些包括那些通过kubectl的"--manifest-url"或"--config"选项、以及kubectl REST API创建的pod