Kubernetes-subPath的使用

落花踏尽游何处,笑入胡姬酒肆中。这篇文章主要讲述Kubernetes-subPath的使用相关的知识,希望能为你提供帮助。
一、什么是subPath
为了支持单一个pod多次使用同一个volume而设计,subpath翻译过来是子路径的意思,如果是存储卷挂载在容器,指的是存储卷目录的子路径,如果是配置项configMap/Secret,则指的是挂载在容器目录的子路径。
 
二、subPath的使用场景
1、 1个pod中可以拉起多个容器,有时候希望将不同容器的路径挂载在存储卷volume的子路径,这个时候需要用到subpath
2、volume支持将configMap/Secret挂载在容器的路径,但是会覆盖掉容器路径下原有的文件,如何支持选定configMap/Secret的每个key-value挂载在容器中,且不会覆盖掉原目录下的文件,这个时候也可以用到subpath
 
三、subPath的使用
1、存储卷
      采用hostpath的方式创建PV,宿主机的映射目录为/data/pod/volume5
??

Kubernetes-subPath的使用

文章图片
??
[root@k8s-master zhanglei]# cat pv-subpath.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv-subpath-05
labels:
release: stable
spec:
capacity:
storage: 0.1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
hostPath:
path: /data/pod/volume5# 宿主机的目录

[root@k8s-master zhanglei]# kubectl create -f pv-subpath.yaml   
??
Kubernetes-subPath的使用

文章图片
??
PV创建成功后,再创建PVC
??
Kubernetes-subPath的使用

文章图片
??
[root@k8s-master zhanglei]# cat pvc-subpath.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-subpath
namespace: default
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 0.05Gi

[root@k8s-master zhanglei]# kubectl create -f pvc-subpath.yaml

??
Kubernetes-subPath的使用

文章图片
??
在pod中声明并使用subpath

??
Kubernetes-subPath的使用

文章图片
??
[root@k8s-master zhanglei]# cat pod-subpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-subpath-zltest
spec:
containers:
- name: ubuntu-subpath-container
image: ubuntu
volumeMounts:
- mountPath: /var/lib/ubuntu# 容器1的挂载目录
name: subpath-vol
subPath: ubuntutest# 宿主机volume5的子目录1
- name: nginx-subpath-container
image: nginx
volumeMounts:
- mountPath: /var/www/nginx# 容器2的挂载目录
name: subpath-vol
subPath: nginxtest# 宿主机volume5的子目录2
volumes:
- name: subpath-vol
persistentVolumeClaim:
claimName: pvc-subpath# PVC的名字

  [root@k8s-master zhanglei]# kubectl create -f pod-subpath.yaml
??
Kubernetes-subPath的使用

文章图片
??
??
Kubernetes-subPath的使用

文章图片
??
[root@k8s-master zhanglei]# kubectl describe podpod-subpath-zltest
Name:pod-subpath-zltest
Namespace:default
Priority:0
Node:k8s-master/192.168.126.129
Start Time:Fri, 29 May 2020 16:45:49 +0800
Labels:< none>
Annotations:cni.projectcalico.org/podIP: 10.122.235.235/32
cni.projectcalico.org/podIPs: 10.122.235.235/32
Status:Running
IP:10.122.235.235
IPs:
IP:10.122.235.235
Containers:
ubuntu-subpath-container:
Container ID:docker://6e5cb30ee7e03b77d2ca22e4cd818ff326fa40836427fe17b1584646b4388dce
Image:ubuntu
Image ID:docker-pullable://ubuntu@sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7
Port:< none>
Host Port:< none>
State:Waiting
Reason:CrashLoopBackOff
Last State:Terminated
Reason:Completed
Exit Code:0
Started:Sun, 14 Jun 2020 22:38:11 +0800
Finished:Sun, 14 Jun 2020 22:38:11 +0800
Ready:False
Restart Count:558
Environment:< none>
Mounts:
/var/lib/ubuntu from subpath-vol (rw,path="ubuntutest")
/var/run/secrets/kubernetes.io/serviceaccount from default-token-74s86 (ro)
nginx-subpath-container:
Container ID:docker://95101741eb1b6aa4c1e53d8fc4ab8006e74fd2eb923eca211ca20a01edcd7630
Image:nginx
Image ID:docker-pullable://nginx@sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097
Port:< none>
Host Port:< none>
State:Running
Started:Fri, 29 May 2020 16:47:14 +0800
Ready:True
Restart Count:0
Environment:< none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-74s86 (ro)
/var/www/nginx from subpath-vol (rw,path="nginxtest")
Conditions:
TypeStatus
InitializedTrue
ReadyFalse
ContainersReadyFalse
PodScheduledTrue
Volumes:
subpath-vol:
Type:PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName:pvc-subpath
ReadOnly:false
default-token-74s86:
Type:Secret (a volume populated by a Secret)
SecretName:default-token-74s86
Optional:false
QoS Class:BestEffort
Node-Selectors:< none>
Tolerations:node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
TypeReasonAgeFromMessage
-------------------------
NormalPulled21m (x555 over 16d)kubelet, k8s-masterSuccessfully pulled image "ubuntu"
NormalCreated21m (x555 over 16d)kubelet, k8s-masterCreated container ubuntu-subpath-container
NormalStarted21m (x555 over 16d)kubelet, k8s-masterStarted container ubuntu-subpath-container
NormalPulling6m10s (x562 over 16d)kubelet, k8s-masterPulling image "ubuntu"
WarningBackOff71s (x11744 over 16d)kubelet, k8s-masterBack-off restarting failed container

??
Kubernetes-subPath的使用

文章图片
??
现在来验证下在宿主机存储卷的目录下是否有2个子目录,1个是ubuntutest用来挂载容器1的,另外1个是nginxtest用来挂载容器2的
??
Kubernetes-subPath的使用

文章图片
??
[root@k8s-master /]# cd data/pod/volume5
[root@k8s-master volume5]# ls
nginxtest ubuntutest
[root@k8s-master volume5]# cd nginxtest/      # 可以看到是1个目录,非文件
[root@k8s-master nginxtest]#
??
Kubernetes-subPath的使用

文章图片
??
进入到容器中,挂载一个文件,验证是否可以同步到存储卷
[root@k8s-master nginxtest]# kubectl exec -it pod-subpath-zltest -c nginx-subpath-container -- bash
root@pod-subpath-zltest:/# cd /var/www/nginx
root@pod-subpath-zltest:/var/www/nginx# ls
nginx-test-subpath.txt

[root@k8s-master volume5]# cd nginxtest/
[root@k8s-master nginxtest]# ls
nginx-test-subpath.txt

可以看到容器1的目录/var/www/nginx  和存储卷的子目录 nginxtest完成了映射,容器2类似,这里不再赘述。
2、配置项-configMap
1)创建configMap
??
Kubernetes-subPath的使用

文章图片
??
[root@k8s-master consecret]# cat conf-subpath.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: conf-subpath-zltest
namespace: default
data:
example.property.1: hello# key-value键值对
example.property.2: world
example.property.file: |-
property.1=value-1
property.2=value-2
property.3=value-3

??
Kubernetes-subPath的使用

文章图片
??
2)在Pod中使用configMap
??
Kubernetes-subPath的使用

文章图片
??
[root@k8s-master consecret]# cat pod-conf-subpath.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
purpose: test-configmap-volume
name: pod-conf-testvolume
spec:
containers:
- name: test-configmap-volume
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/example.property.1# 容器挂载目录
subPath: example.property.1# 将key名称作为文件名,hello作为文件内容
volumes:
- name: config-volume
configMap:
name: conf-subpath-zltest# 指定使用哪个CM

[root@k8s-master consecret]# kubectl create -f pod-conf-subpath.yaml

??
Kubernetes-subPath的使用

文章图片
??
??
Kubernetes-subPath的使用

文章图片
??
[root@k8s-master consecret]# kubectl describe podpod-conf-testvolume
Name:pod-conf-testvolume
Namespace:default
Priority:0
Node:k8s-master/192.168.126.129
Start Time:Wed, 03 Jun 2020 11:46:36 +0800
Labels:purpose=test-configmap-volume
Annotations:cni.projectcalico.org/podIP: 10.122.235.249/32
cni.projectcalico.org/podIPs: 10.122.235.249/32
Status:Running
IP:10.122.235.249
IPs:
IP:10.122.235.249
Containers:
test-configmap-volume:
Container ID:docker://e2cf37cb24af32023eb5d22389545c3468104a4344c47363b5330addc40cb914
Image:nginx
Image ID:docker-pullable://nginx@sha256:883874c218a6c71640579ae54e6952398757ec65702f4c8ba7675655156fcca6
Port:< none>
Host Port:< none>
State:Running
Started:Wed, 03 Jun 2020 11:46:53 +0800
Ready:True
Restart Count:0
Environment:< none>
Mounts:
/etc/nginx/example.property.1 from config-volume (rw,path="example.property.1")
/var/run/secrets/kubernetes.io/serviceaccount from default-token-74s86 (ro)
Conditions:
TypeStatus
InitializedTrue
ReadyTrue
ContainersReadyTrue
PodScheduledTrue
Volumes:
config-volume:
Type:ConfigMap (a volume populated by a ConfigMap)
Name:conf-subpath-zltest
Optional:false
default-token-74s86:
Type:Secret (a volume populated by a Secret)
SecretName:default-token-74s86
Optional:false
QoS Class:BestEffort
Node-Selectors:< none>
Tolerations:node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:< none>

??
Kubernetes-subPath的使用

文章图片
??
在容器挂载路径验证下是否将configMap中example.property.1挂载在容器中,且是否会覆盖掉原有的目录
root@pod-conf-testvolume:/# cd/etc/nginx
root@pod-conf-testvolume:/etc/nginx# ls
conf.dfastcgi_paramskoi-winmodulesscgi_paramswin-utf
example.property.1koi-utfmime.typesnginx.confuwsgi_params

从上可以看到example.property.1已经挂载到容器中,且未对目录原有的文件进行覆盖
root@pod-conf-testvolume:/etc/nginx# cd example.property.1
bash: cd: example.property.1: Not a directory
root@pod-conf-testvolume:/etc/nginx# cat example.property.1
helloroot@pod-conf-testvolume:/etc/nginx#

从上可以验证configMap的subpath用法支持将configMap中的每对key-value以key名称作为文件名,value作为文件内容挂载到容器的目录中。
四、总结
本文介绍了subpath分别在持久化存储卷和配置项configMap中的使用,丰富了volume在pod中的使用场景。

【Kubernetes-subPath的使用】 

    推荐阅读