云原生 | K8s中VolumeMounts.subPath的巧妙用法

    作者:匿名更新于: 2023-02-02 22:31:24

      subPath其实就是volumes挂载的子目录或单个文件,是不是目录和单文件,取决于subPath在volumes挂载的目录下是否存在subPath定义的文件(文件或目录),如果不存在,则会volumes对应的目录下创建一个subPath目录。

      一、概述

      有时,在单个 Pod 中共享卷以供多方使用是很有用的。volumeMounts.subPath 属性可用于指定所引用的卷内的子路径,而不是其根路径。

      官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#using-subpath

      二、使用场景

      一个共享卷, 挂载多个路径。

      ConfigMap或Secret挂载到特定目录的特定路径, 而 该目录下已经有其他文件且不希望被覆盖掉。

      三、共享卷中使用, 挂载多个路径

      作为configmap/secret使用时,subPath代表configmap/secret的子路径。

      【示例1】挂载目录,hostPath

      复制

      1.  apiVersion: v1

      2.  kind: Pod

      3.  metadata:

      4.  name: my-lamp-site

      5.  spec:

      6.  nodeName: local-168-182-110 # 为了测试方便,指定调度机器

      7.  containers:

      8.  - name: mysql

      9.  image: mysql

      10.  env:

      11.  - name: MYSQL_ROOT_PASSWORD

      12.  value: "rootpasswd"

      13.  volumeMounts:

      14.  - mountPath: /var/lib/mysql #挂载到容器的某个路径下

      15.  name: site-data #挂载设备的名字,与volumes[*].name 需要对应

      16.  subPath: mysql # volumes path中的子路径(会自动在volumes path目录下创建mysql空目录)

      17.  - name: php

      18.  image: php:7.0-apache

      19.  volumeMounts:

      20.  - mountPath: /var/www/html #挂载到容器的某个路径下

      21.  name: site-data # volumes path中的子路径(会自动在volumes path目录下创建site-data【空目录】)

      22.  subPath: html

      23.  volumes:

      24.  - name: nginx #和上面保持一致 这是本地的文件路径,上面是容器内部的路径

      25.  hostPath:

      26.  path: /opt/k8s/subPath/lamp #此路径需要实现创建

      【示例2】挂载目录,pvc

      复制

      1.  # StorageClass

      2.  kind: StorageClass

      3.  apiVersion: storage.k8s.io/v1

      4.  metadata:

      5.  name: local-storage

      6.  provisioner: kubernetes.io/no-provisioner

      7.  volumeBindingMode: WaitForFirstConsumer

      8.  ---

      9.  # pvc

      10.  apiVersion: v1

      11.  kind: PersistentVolume

      12.  metadata:

      13.  name: local-lamp-pv

      14.  labels:

      15.  name: local-lamp-pv

      16.  spec:

      17.  capacity:

      18.  storage: 1Gi

      19.  accessModes:

      20.  - ReadWriteOnce

      21.  persistentVolumeReclaimPolicy: Retain

      22.  storageClassName: local-storage

      23.  local:

      24.  path: /opt/k8s/subPath/lamp-pvc

      25.  nodeAffinity:

      26.  required:

      27.  nodeSelectorTerms:

      28.  - matchExpressions:

      29.  - key: kubernetes.io/hostname

      30.  operator: In

      31.  values:

      32.  - local-168-182-110

          33.

      34.  ---

      35.  # pvc

      36.  kind: PersistentVolumeClaim

      37.  apiVersion: v1

      38.  metadata:

      39.  name: my-lamp-site-data

      40.  spec:

      41.  accessModes:

      42.  - ReadWriteOnce

      43.  resources:

      44.  requests:

      45.  storage: 1Gi

      46.  storageClassName: local-storage

      47.  selector:

      48.  matchLabels:

      49.  name: local-lamp-pv

      50.  ---

      51.  apiVersion: v1

      52.  kind: Pod

      53.  metadata:

      54.  name: my-lamp-site-pvc

      55.  spec:

      56.  containers:

      57.  - name: mysql

      58.  image: mysql

      59.  env:

      60.  - name: MYSQL_ROOT_PASSWORD

      61.  value: "rootpasswd"

      62.  volumeMounts:

      63.  - mountPath: /var/lib/mysql

      64.  name: site-data

      65.  subPath: mysql

      66.  - name: php

      67.  image: php:7.0-apache

      68.  volumeMounts:

      69.  - mountPath: /var/www/html

      70.  name: site-data

      71.  subPath: html

      72.  volumes:

      73.  - name: site-data

      74.  persistentVolumeClaim:

      75.  claimName: my-lamp-site-data

      如果使用PVC模板就不用手动创建PVC了,示例如下:

      复制

      1.  volumeClaimTemplates: #可看作pvc的模板

      2.  - metadata:

      3.  name: nginx-pvc

      4.  spec:

      5.  accessModes: [ "ReadWriteOnce" ]

      6.  storageClassName: "local-storage" #存储类名,就是上面nginx-sc.yaml metadata.name

      7.  resources:

      8.  requests:

      9.  storage: 1Gi

      【示例3】共享单个文件那么如果 subPath 不是文件夹,而是一个文件,又该如何解决呢?同样的道理,只需要通过 subPath 指定出该文件即可,注意 subPath 要使用相对目录。具体如下所示:

      复制

      1.  apiVersion: apps/v1

      2.  kind: Deployment

      3.  metadata:

      4.  name: deployment-test

      5.  spec:

      6.  replicas: 1

      7.  selector:

      8.  matchLabels:

      9.  app: nginx-pod

      10.  template:

      11.  metadata:

      12.  labels:

      13.  app: nginx-pod

      14.  spec:

      15.  nodeName: local-168-182-110 # 为了测试方便,指定调度机器

      16.  containers:

      17.  - name: nginx

      18.  image: docker.io/library/nginx:latest

      19.  volumeMounts:

      20.  - mountPath: /etc/nginx/nginx.conf

      21.  name: nginx-conf

      22.  subPath: nginx-conf

      23.  volumes:

      24.  - name: nginx-conf #和上面保持一致 这是本地的文件路径,上面是容器内部的路径

      25.  hostPath:

      26.  path: /opt/k8s/subPath/nginx #此路径需要实现创建

      【结论】以宿主机上的文件为准,会覆盖pod里原先默认的的文件内容。

      四、ConfigMap 和 Secret 中使用 subPath

      作为configmap/secret使用时,subPath代表configmap/secret​的子路径。如果不使用subPath​会把容器里原本的文件(volumeMounts.mountPath​对应的目录)都清空,自会把ConfigMap 和 Secret 的文件放在volumeMounts.mountPath对应的目录下。

      【示例1】ConfigMap

      复制

      1.  apiVersion: v1

      2.  kind: ConfigMap

      3.  metadata:

      4.  name: nginx-conf

      5.  data:

      6.  nginx.conf: |+

      7.  worker_processes 1;

      8.  events {

      9.  worker_connections 1024;

      10.  }

      11.  http {

      12.  include mime.types;

      13.  default_type application/octet-stream;

      14.  sendfile on;

      15.  keepalive_timeout 65;

      16.  server {

      17.  listen 80;

      18.  server_name localhost;

      19.  location / {

      20.  root html;

      21.  index index.html index.htm;

      22.  }

      23.  error_page 500 502 503 504 /50x.html;

      24.  location = /50x.html {

      25.  root html;

      26.  }

      27.  }

      28.  }

      29.  ---

      30.  apiVersion: apps/v1

      31.  kind: Deployment

      32.  metadata:

      33.  name: deployment-test2

      34.  spec:

      35.  replicas: 1

      36.  selector:

      37.  matchLabels:

      38.  app: nginx-pod

      39.  template:

      40.  metadata:

      41.  labels:

      42.  app: nginx-pod

      43.  spec:

      44.  nodeName: local-168-182-110 # 为了测试方便,指定调度机器

      45.  containers:

      46.  - name: nginx

      47.  image: docker.io/library/nginx:latest

      48.  volumeMounts:

      49.  - name: nginx-cm # 与volumes.name一致

      50.  mountPath: /etc/nginx/nginx.conf

      51.  subPath: nginx.conf

      52.  volumes:

      53.  - name: nginx-cm

      54.  configMap:

      55.  name: nginx-conf # configMap名称

      【示例1】Secret

      复制

      1.  apiVersion: v1

      2.  kind: Secret

      3.  metadata:

      4.  name: mysecret

      5.  type: Opaque

      6.  data:

      7.  username: admin

      8.  password: MWYyZDFlMmU2N2Rm

          9.

      10.  ---

          11.

      12.  vim myapp-demo.yaml

      13.  apiVersion: apps/v1

      14.  kind: Deployment

      15.  metadata:

      16.  name: mysql-demo

      17.  namespace: default

      18.  spec:

      19.  replicas: 1

      20.  selector:

      21.  matchLabels:

      22.  app: myapp

      23.  template:

      24.  metadata:

      25.  labels:

      26.  app: myapp

      27.  spec:

      28.  containers:

      29.  - name: myapp

      30.  image: mysql

      31.  imagePullPolicy: IfNotPresent

      32.  ports:

      33.  - name: http

      34.  containerPort: 80

      35.  volumeMounts:

      36.  - name: mysql

      37.  mountPath: /tmp/data

      38.  subPath: data

      39.  volumes:

      40.  - name: mysql

      41.  secret:

      42.  secretName: mysecret

      【结论】会在/tmp目录下面存放data文件信息,如果存在则覆盖。如果不存在,则自动创建。

      最后对volumeMounts.subPath来一个总结:

      1.subPath其实就是volumes挂载的子目录或单个文件,是不是目录和单文件,取决于subPath在volumes挂载的目录下是否存在subPath定义的文件(文件或目录),如果不存在,则会volumes对应的目录下创建一个subPath目录。

      2.如果ConfigMap 和 Secret 中使用 subPath,如果不指定subPath,则会把volumeMounts.mountPath对应的目录下的文件都清掉,然后只存放ConfigMap 或者 Secret 定义的文件。

      关于volumeMounts.subPath的用法就先到这里了,有疑问的小伙伴,欢迎给我留言哦,后续文章更精彩,请小伙伴耐心等待哦~

      来源: 大数据与云原生技术分享

        >>>>>>点击进入计算专题

云计算 更多推荐

课课家教育

未登录