下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

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

作者:匿名     来源: 云计算点击数:629发布时间: 2023-02-02 22:31:24

标签: k8s云原生巧妙用法

  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的用法就先到这里了,有疑问的小伙伴,欢迎给我留言哦,后续文章更精彩,请小伙伴耐心等待哦~

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

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

赞(8)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程