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

posted @ 2020-09-05 23:09  活的潇洒80  阅读(926)  评论(0编辑  收藏  举报