为了支持单一个pod多次使用同一个volume而设计,subpath翻译过来是子路径的意思,如果是数据卷挂载在容器,指的是存储卷目录的子路径,如果是配置项configMap/Secret,则指的是挂载在容器的子路径
nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
containers:
- image: busybox:1.0
imagePullPolicy: IfNotPresent
name: busybox1
command:
- "/bin/sh"
args:
- "-c"
- "sleep 36000"
volumeMounts:
- mountPath: /mnt
name: example-volume3
- image: busybox:1.0
imagePullPolicy: IfNotPresent
name: busybox2
command:
- "/bin/sh"
args:
- "-c"
- "sleep 36000"
volumeMounts:
- mountPath: /opt
name: example-volume3
volumes:
- name: example-volume3
persistentVolumeClaim:
claimName: nfs-pvc
Pod有两个名称为busybox1和busybox2的两个容器,都是调用nfs-pvc请求(所以两个容器使用相同的pv),分别挂载容器内/mnt、/opt目录
[root@master subpath]# kubectl apply -f nfs-pod.yaml
[root@master subpath]# kubectl exec -it nfs-pod -c busybox1 -- /bin/sh
/ # touch /mnt/aaaa
服务端存储卷根目录
[root@localhost default-nfs-pvc-pvc-74935cdc-a8f5-455b-9418-c21c10aee6c0]# pwd
/opt/default-nfs-pvc-pvc-74935cdc-a8f5-455b-9418-c21c10aee6c0
[root@localhost default-nfs-pvc-pvc-74935cdc-a8f5-455b-9418-c21c10aee6c0]# ls
aaaa
进入另一个busybox2容器,发现在opt下出现了busybox1在/mnt目录下创建的文件
[root@master subpath]# kubectl exec -it nfs-pod -c busybox2 -- /bin/sh
~ # ls /opt/
aaaa
加上subPath参数后
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod2
spec:
containers:
- image: busybox:1.0
imagePullPolicy: IfNotPresent
name: busybox1
command:
- "/bin/sh"
args:
- "-c"
- "sleep 36000"
volumeMounts:
- mountPath: /mnt
subPath: mnt
name: example-volume3
- image: busybox:1.0
imagePullPolicy: IfNotPresent
name: busybox2
command:
- "/bin/sh"
args:
- "-c"
- "sleep 36000"
volumeMounts:
- mountPath: /opt
subPath: opt
name: example-volume3
volumes:
- name: example-volume3
persistentVolumeClaim:
claimName: nfs-pvc2
服务端存储卷根目录下出现子目录
[root@localhost default-nfs-pvc2-pvc-65769a72-e735-4a58-aef9-63bce183ac73]# pwd
/opt/default-nfs-pvc2-pvc-65769a72-e735-4a58-aef9-63bce183ac73
[root@localhost default-nfs-pvc2-pvc-65769a72-e735-4a58-aef9-63bce183ac73]# ll
总用量 0
drwxrwxrwx. 2 root root 18 3月 17 10:58 mnt
drwxrwxrwx. 2 root root 6 3月 17 10:57 opt
进入busybox1的容器中mnt目录下创建文件
[root@master subpath]# kubectl exec -it nfs-pod2 -c busybox1 -- /bin/sh
/ # touch /mnt/bbbb
此时进入busybox2的容器的opt目录下,并不会出现bbbb文件
[root@master subpath]# kubectl exec -it nfs-pod2 -c busybox2 -- /bin/sh
/ # ls /opt/
/ #
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod5
spec:
containers:
- image: busybox:1.0
imagePullPolicy: IfNotPresent
name: busybox1
command:
- "/bin/sh"
args:
- "-c"
- "sleep 36000"
volumeMounts:
- mountPath: /home
name: example-volume3
- mountPath: /opt
name: example-volume3
volumes:
- name: example-volume3
persistentVolumeClaim:
claimName: nfs-pvc5
Pod中只有一个容器,外挂目录分别是/opt与/home,进入容器,在/opt目录下创建bbb文件,由于没有subPath参数,文件创建在存储卷的根目录,所以/home目录下也会产生bbb文件
[root@master subpath]# kubectl apply -f nfs-pod5.yaml
[root@master subpath]# kubectl exec -it nfs-pod5 -- /bin/sh
/ # touch /opt/bbb
/ # ls /home/
bbb
服务端存储卷
[root@localhost default-nfs-pvc5-pvc-4af7377e-5941-4e49-8846-d5f983a8139b]# ls
bbb
加上subPath参数后
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod6
spec:
containers:
- image: busybox:1.0
imagePullPolicy: IfNotPresent
name: busybox1
command:
- "/bin/sh"
args:
- "-c"
- "sleep 36000"
volumeMounts:
- mountPath: /home
subPath: home
name: example-volume3
- mountPath: /opt
subPath: opt
name: example-volume3
volumes:
- name: example-volume3
persistentVolumeClaim:
claimName: nfs-pvc6
Pod中只有一个容器,外挂目录分别是/opt与/home,进入容器,在/opt目录下创建bbbb文件,由于添加subPath参数,文件创建在存储卷的对应的子目录,所以/home目录下不会产生bbb文件
[root@master subpath]# kubectl exec -it nfs-pod6 -- /bin/sh
/ # touch /opt/bbbb
/ # ls /home/
/ #
服务端存储卷
[root@localhost default-nfs-pvc6-pvc-35e5e4ad-c30c-4a93-8650-0573d6f0d11d]# ls
home opt
不加subPath参数,容器中挂载的目录文件都会被覆盖
tomcatconfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: tomcat-config
labels:
app: tomcat-config
data:
test1.xml: |
test1
test2.xml: |
test2
tomcat-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: tomcatpod
spec:
containers:
- image: tomcat:1.0
imagePullPolicy: IfNotPresent
name: tomcat
volumeMounts:
- mountPath: /usr/local/tomcat/temp
name: tomcat-config
volumes:
- name: tomcat-config
configMap:
name: tomcat-config
[root@master configmap]# kubectl apply -f tomcatconfigmap.yaml
configmap/tomcat-config created
[root@master configmap]# kubectl apply -f tomcat-pod.yaml
pod/tomcatpod created
[root@master configmap]# kubectl exec -it tomcatpod -- /bin/bash
root@tomcatpod:/usr/local/tomcat# cd temp/
root@tomcatpod:/usr/local/tomcat/temp# ls
test1.xml test2.xml
加上subPath参数,容器中挂载的目录文件就不会被覆盖
tomcat-podsubpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: tomcatpodsubpath
spec:
containers:
- image: tomcat:1.0
imagePullPolicy: IfNotPresent
name: tomcat
volumeMounts:
- mountPath: /usr/local/tomcat/temp/test3.xml #最终容器中的文件名
subPath: test1.xml #configmap中的键。一般来说,名称应该保持一致,这边只是演示
name: tomcat-config
- mountPath: /usr/local/tomcat/temp/test2.xml
subPath: test2.xml
name: tomcat-config
volumes:
- name: tomcat-config
configMap:
name: tomcat-config
[root@master configmap]# kubectl apply -f tomcat-podsubpath.yaml
[root@master configmap]# kubectl exec -it tomcatpodsubpath -- /bin/bash
root@tomcatpodsubpath:/usr/local/tomcat# ls temp
safeToDelete.tmp test2.xml test3.xml
root@tomcatpodsubpath:/usr/local/tomcat# cat temp/test3.xml
test1