K8S的mountPath和subPath

1 mountPath

mountPath是容器内部文件系统的挂载点,它定义了容器内部将外部存储卷(如 PersistentVolume、ConfigMap、Secret 等)挂载到哪个路径下。通过 mountPath,容器可以访问这些挂载的数据或配置。

2 subPath

subPath 是 mountPath 下的子路径,它允许容器将挂载的数据卷中的特定文件或目录挂载到容器中的指定路径下。这样可以实现更加精细的文件系统级别的访问控制。

3 mountPath使用场景

比如我需要创建一个nginx deployment,需要将自定义的nginx.conf配置文件独立出来,作为一个configmap来挂载到pod中。

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  my-nginx.conf: |
    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-config-volume
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: nginx-config-volume
        configMap:
          name: nginx-config

部署完成后,你可以进入pod,可以看到如下文件,这就是通过configmap挂载到容器中。

bash 复制代码
kubectl exec -it nginx-deployment-5b4699b7dd-fh4qc -- /bin/sh
# cd /etc/nginx/conf.d
# ls
my-nginx.conf

4 subPath使用场景

如果我想直接通过configmap定义/etc/nginx/nginx.conf,这时候如果还是只使用mountPath,就会有问题了。

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    user  nginx;
    worker_processes  auto;

    error_log  /var/log/nginx/error.log notice;
    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;
    }

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-config-volume
          mountPath: /etc/nginx
      volumes:
      - name: nginx-config-volume
        configMap:
          name: nginx-config

创建容器后,服务无法起来,会报错,因为此时容器中的/etc/nginx/目录会被我们挂载的configmap给覆盖,所以原先/etc/nginx/目录下的文件都无法被pod访问,也就报错了。

bash 复制代码
2024/03/25 06:56:58 [emerg] 1#1: open() "/etc/nginx/mime.types" failed (2: No such file or directory) in /etc/nginx/nginx.conf:14
nginx: [emerg] open() "/etc/nginx/mime.types" failed (2: No such file or directory) in /etc/nginx/nginx.conf:14

那如果我将volumeMount改为如下配置呢,

yaml 复制代码
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-config-volume
          mountPath: /etc/nginx/nginx.conf

此时原来/etc/nginx/目录下的文件都不会受影响,但是依旧会报错,连容器都无法创建,

bash 复制代码
Error: failed to create containerd task: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/var/lib/kubelet/pods/6755a0be-2f05-4edb-813b-ece2dcc2e8f1/volumes/kubernetes.io~configmap/nginx-config-volume" to rootfs at "/etc/nginx/nginx.conf": mount /var/lib/kubelet/pods/6755a0be-2f05-4edb-813b-ece2dcc2e8f1/volumes/kubernetes.io~configmap/nginx-config-volume:/etc/nginx/nginx.conf (via /proc/self/fd/6), flags: 0x5001: not a directory: unknown

这是因为此时容器中/etc/nginx/nginx.conf这个路径已经是存在的,镜像中默认的文件,没法作为mountpath使用。

当然,你可以将nginx.conf换成其他名字,比如mynginx.conf,

yaml 复制代码
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-config-volume
          mountPath: /etc/nginx/mynginx.conf

这样就不会报错,但是这样的效果是,容器中会创建一个目录/etc/nginx/mynginx.conf/,这个目录下有个文件nginx.conf,与最开始我们在/etc/nginx/conf.d/定义my-nginx.conf一样,但这并不是我们所要的。

bash 复制代码
kubectl exec -it nginx-deployment-6bf5f55df8-f452d -- /bin/sh
# cd /etc/nginx/mynginx.conf/
# ls
nginx.conf

这个时候,我们就需要使用subPath了,将volumeMount做如下修改,

yaml 复制代码
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-config-volume
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf

这时服务就按照我们预期启动了,容器内文件如下,而且nginx.conf的内容就是我们configmap中定义的配置,

bash 复制代码
kubectl exec -it nginx-deployment-bb7d454c6-75bwz -- /bin/sh
# cd /etc/nginx/
# ls
conf.d	fastcgi_params	mime.types  modules  nginx.conf  scgi_params  uwsgi_params

类似的场景,比如需要在/etc/nginx/conf.d/为不同的host定义不同的配置,我们就可以创建多个configmap,配合使用subPath来挂载到同一个目录下,

yaml 复制代码
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-config-volume
          mountPath: /etc/nginx/conf.d/nginx.conf
          subPath: nginx.conf
        - name: my-nginx-config-volume
          mountPath: /etc/nginx/conf.d/my-nginx.conf
          subPath: my-nginx.conf

参考文档:

  1. https://stackoverflow.com/questions/65399714/what-is-the-difference-between-subpath-and-mountpath-in-kubernetes
相关推荐
matlab的学徒1 小时前
Kubernetes(K8S)全面解析:核心概念、架构与实践指南
linux·容器·架构·kubernetes
没有口袋啦3 小时前
K8s集群多节点部署(Ubuntu22.04)
docker·云原生·容器·kubernetes
荣光波比3 小时前
K8S(三)—— 基于kubeadm 1.20版本部署Kubernetes集群与Harbor私有仓库实战
云原生·容器·kubernetes
荣光波比4 小时前
K8S(二)—— K8S 1.28 集群部署指南(kubeadm 方式)
云原生·容器·kubernetes
问道飞鱼4 小时前
【Kubernets进阶】Kubernetes VPA (Vertical Pod Autoscaler) 详解与配置指南
云原生·容器·kubernetes·vpa
荣光波比21 小时前
K8S(一)—— 云原生与Kubernetes(K8S)从入门到实践:基础概念与操作全解析
云原生·容器·kubernetes
伞啊伞21 小时前
K8s概念基础(一)
云原生·容器·kubernetes
hello_2501 天前
k8s基础监控promql
云原生·容器·kubernetes
静谧之心1 天前
在 K8s 上可靠运行 PD 分离推理:RBG 的设计与实现
云原生·容器·golang·kubernetes·开源·pd分离
1024find1 天前
Spark on k8s部署
大数据·运维·容器·spark·kubernetes