云原生 | K8s中VolumeMounts.subPath的巧妙用法
source link: https://www.51cto.com/article/745433.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
有时,在单个 Pod 中共享卷以供多方使用是很有用的。volumeMounts.subPath 属性可用于指定所引用的卷内的子路径,而不是其根路径。
官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#using-subpath
二、使用场景
- 一个共享卷, 挂载多个路径。
- ConfigMap或Secret挂载到特定目录的特定路径, 而 该目录下已经有其他文件且不希望被覆盖掉。
三、共享卷中使用, 挂载多个路径
作为configmap/secret使用时,subPath代表configmap/secret的子路径。
【示例1】挂载目录,hostPath
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
nodeName: local-168-182-110 # 为了测试方便,指定调度机器
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql #挂载到容器的某个路径下
name: site-data #挂载设备的名字,与volumes[*].name 需要对应
subPath: mysql # volumes path中的子路径(会自动在volumes path目录下创建mysql空目录)
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html #挂载到容器的某个路径下
name: site-data # volumes path中的子路径(会自动在volumes path目录下创建site-data【空目录】)
subPath: html
volumes:
- name: nginx #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
hostPath:
path: /opt/k8s/subPath/lamp #此路径需要实现创建
【示例2】挂载目录,pvc
# StorageClass
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
# pvc
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-lamp-pv
labels:
name: local-lamp-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /opt/k8s/subPath/lamp-pvc
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- local-168-182-110
---
# pvc
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: my-lamp-site-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-storage
selector:
matchLabels:
name: local-lamp-pv
---
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site-pvc
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
如果使用PVC模板就不用手动创建PVC了,示例如下:
volumeClaimTemplates: #可看作pvc的模板
- metadata:
name: nginx-pvc
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "local-storage" #存储类名,就是上面nginx-sc.yaml metadata.name
resources:
requests:
storage: 1Gi
【示例3】共享单个文件那么如果 subPath 不是文件夹,而是一个文件,又该如何解决呢?同样的道理,只需要通过 subPath 指定出该文件即可,注意 subPath 要使用相对目录。具体如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-test
spec:
replicas: 1
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
nodeName: local-168-182-110 # 为了测试方便,指定调度机器
containers:
- name: nginx
image: docker.io/library/nginx:latest
volumeMounts:
- mountPath: /etc/nginx/nginx.conf
name: nginx-conf
subPath: nginx-conf
volumes:
- name: nginx-conf #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
hostPath:
path: /opt/k8s/subPath/nginx #此路径需要实现创建
【结论】以宿主机上的文件为准,会覆盖pod里原先默认的的文件内容。
四、ConfigMap 和 Secret 中使用 subPath
作为configmap/secret使用时,subPath代表configmap/secret的子路径。如果不使用subPath会把容器里原本的文件(volumeMounts.mountPath对应的目录)都清空,自会把ConfigMap 和 Secret 的文件放在volumeMounts.mountPath对应的目录下。
【示例1】ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx.conf: |+
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-test2
spec:
replicas: 1
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
nodeName: local-168-182-110 # 为了测试方便,指定调度机器
containers:
- name: nginx
image: docker.io/library/nginx:latest
volumeMounts:
- name: nginx-cm # 与volumes.name一致
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: nginx-cm
configMap:
name: nginx-conf # configMap名称
【示例1】Secret
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: admin
password: MWYyZDFlMmU2N2Rm
---
vim myapp-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-demo
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: mysql
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
volumeMounts:
- name: mysql
mountPath: /tmp/data
subPath: data
volumes:
- name: mysql
secret:
secretName: mysecret
【结论】会在/tmp目录下面存放data文件信息,如果存在则覆盖。如果不存在,则自动创建。
最后对volumeMounts.subPath来一个总结:
- subPath其实就是volumes挂载的子目录或单个文件,是不是目录和单文件,取决于subPath在volumes挂载的目录下是否存在subPath定义的文件(文件或目录),如果不存在,则会volumes对应的目录下创建一个subPath目录。
- 如果ConfigMap 和 Secret 中使用 subPath,如果不指定subPath,则会把volumeMounts.mountPath对应的目录下的文件都清掉,然后只存放ConfigMap 或者 Secret 定义的文件。
关于volumeMounts.subPath的用法就先到这里了,有疑问的小伙伴,欢迎给我留言哦,后续文章更精彩,请小伙伴耐心等待哦~
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK