当挂载ConfigMap或Secret到容器内部时,会覆盖原有目录,直接挂载一不小心就会引发很多问题,比如将nginx.conf挂载到/etc/nginx/nginx.conf,如果使用ConfigMap挂载,就会把/etc/nginx这个目录完全覆盖掉,只会留下一个nginx.conf,这样会导致Nginx找不到系统文件,从而导致Nginx无法启动,所以需要使用subPath字段解决挂载覆盖的问题。

一、演示环境准备

接下来导出nginx.conf文件进行修改进行挂载覆盖演示

1.创建工作目录

[root@k8s-master01 ~]# mkdir -p configmap/conf

2.编写配置文件

[root@k8s-master01 ~]# vim configmap/conf/redis.conf
Password=123

3.创建ConfigMap,,其中--from-file参数用于指定文件

[root@k8s-master01 ~]# kubectl create cm cmfromfile --from-file=/root/configmap/conf/redis.conf
configmap/cmfromfile created

4.验证

[root@k8s-master01 ~]# kubectl get cm
NAME               DATA   AGE
cmfromdir          2      7m18s
cmfromfile         1      2m21s
kube-root-ca.crt   1      25h

[root@k8s-master01 ~]# kubectl get cm cmfromfile -oyaml
apiVersion: v1
data:
  redis.conf: |
    Password=123
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-03T08:19:26Z"
  name: cmfromfile
  namespace: default
  resourceVersion: "33521"
  uid: acf5f51a-5cd8-413e-bf81-14a779b2f2fa

[root@k8s-master01 ~]# kubectl describe cm cmfromfile
Name:         cmfromfile
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
redis.conf:
----
Password=123

BinaryData
====

Events:  <none>

5.编写dp-cm.yaml

[root@k8s-master01 conf]# vim dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: conf
           mountPath: /etc/config
      volumes:
       - name: conf
         configMap:
          name: cmfromfile

6.创建Pod

$ kubectl create  -f dp-cm.yaml

7.导出nginx.conf文件到当前目录下

[root@k8s-master01 conf]# kubectl exec -it  dp-cm-6b49968558-bflhj -- cat /etc/nginx/nginx.conf > nginx.conf

8.修改nginx.conf文件,这里只加了注释(演示环境)方便后面演示

[root@k8s-master01 conf]# cat nginx.conf
#test
user  nginx;
worker_processes  1;

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;
}

9.查看容器内/etc/nginx/目录下除nginx.conf外还有其他文件

[root@k8s-master01 conf]# kubectl exec -it  dp-cm-6b49968558-bflhj -- ls  /etc/nginx/ -l
total 68
drwxr-xr-x    1 root     root            26 Apr 10  2019 conf.d
-rw-r--r--    1 root     root          1077 Apr 10  2019 fastcgi.conf
-rw-r--r--    1 root     root          1077 Apr 10  2019 fastcgi.conf.default
-rw-r--r--    1 root     root          1007 Apr 10  2019 fastcgi_params
-rw-r--r--    1 root     root          1007 Apr 10  2019 fastcgi_params.default
-rw-r--r--    1 root     root          2837 Apr 10  2019 koi-utf
-rw-r--r--    1 root     root          2223 Apr 10  2019 koi-win
-rw-r--r--    1 root     root          5170 Apr 10  2019 mime.types
-rw-r--r--    1 root     root          5170 Apr 10  2019 mime.types.default
lrwxrwxrwx    1 root     root            27 Apr 10  2019 modules -> ../../usr/lib/nginx/modules
-rw-rw-r--    1 root     root           643 Apr 10  2019 nginx.conf
-rw-r--r--    1 root     root          2656 Apr 10  2019 nginx.conf.default
-rw-r--r--    1 root     root           636 Apr 10  2019 scgi_params
-rw-r--r--    1 root     root           636 Apr 10  2019 scgi_params.default
-rw-r--r--    1 root     root           664 Apr 10  2019 uwsgi_params
-rw-r--r--    1 root     root           664 Apr 10  2019 uwsgi_params.default
-rw-r--r--    1 root     root          3610 Apr 10  2019 win-utf

二、演示挂载覆盖

上面条件准备完成

1.创建ConfigMap,,其中--from-file参数用于指定文件

$ kubectl create cm nginx-conf --from-file=/root/configmap/conf/nginx.conf

2.修改dp-cm.yaml

$ vim dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
         - name: conf
           mountPath: /etc/nginx/
      volumes:
       - name: conf
         configMap:
          name: nginx-conf

3.更新Yaml

$ kubectl delete -f dp-cm.yaml ; kubectl apply -f dp-cm.yaml

4.查看新起的Pod显示Error,并查看日志信息,发现/etc/nginx/目录下的文件都被覆盖

[root@k8s-master01 conf]# kubectl get po
NAME                            READY   STATUS    RESTARTS          AGE
cluster-test-79b978867f-4x2lw   1/1     Running   101 (5m54s ago)   52d
dp-cm-84d74dcb4b-kpkq4          0/1     Error     2 (17s ago)       19s

[root@k8s-master01 conf]# kubectl logs -f  dp-cm-84d74dcb4b-kpkq4
2023/05/03 09:05:12 [emerg] 1#1: open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)

三、使用SubPath解决挂载覆盖问题

1.修改Yaml文件

$ vim dp-cm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dp-cm
  name: dp-cm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dp-cm
  template:
    metadata:
      labels:
        app: dp-cm
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
        name: nginx
        volumeMounts:
          - name: conf
            mountPath: /etc/nginx/nginx.conf
            subPath: nginx.conf
      volumes:
       - name: conf
         configMap:
           name: nginx-conf

2.重新起Pod

$ kubectl replace   -f dp-cm.yaml

3.查看新起的Pod状态

[root@k8s-master01 conf]# kubectl get po
NAME                            READY   STATUS    RESTARTS        AGE
dp-cm-5478545d-jjhnm            1/1     Running   0               3m12s

4.进入容器查看nginx.conf文件,观察到挂载文件已替换成自己的文件

[root@k8s-master01 conf]# kubectl exec -it dp-cm-5478545d-jjhnm -- cat /etc/nginx/nginx.conf
#test
user  nginx;
worker_processes  1;

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;
}