一、什麼是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
[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
PV建立成功後,再建立PVC
[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
在pod中宣告並使用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
[root@k8s-master zhanglei]# kubectl describe pod pod-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: Type Status Initialized True Ready False ContainersReady False PodScheduled True 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: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulled 21m (x555 over 16d) kubelet, k8s-master Successfully pulled image "ubuntu" Normal Created 21m (x555 over 16d) kubelet, k8s-master Created container ubuntu-subpath-container Normal Started 21m (x555 over 16d) kubelet, k8s-master Started container ubuntu-subpath-container Normal Pulling 6m10s (x562 over 16d) kubelet, k8s-master Pulling image "ubuntu" Warning BackOff 71s (x11744 over 16d) kubelet, k8s-master Back-off restarting failed container
現在來驗證下在宿主機儲存卷的目錄下是否有2個子目錄,1個是ubuntutest用來掛載容器1的,另外1個是nginxtest用來掛載容器2的
[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]#
進入到容器中,掛載一個檔案,驗證是否可以同步到儲存卷
[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
[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
2)在Pod中使用configMap
[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
[root@k8s-master consecret]# kubectl describe pod pod-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: Type Status Initialized True Ready True ContainersReady True PodScheduled True 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>
在容器掛載路徑驗證下是否將configMap中example.property.1掛載在容器中,且是否會覆蓋掉原有的目錄
root@pod-conf-testvolume:/# cd /etc/nginx root@pod-conf-testvolume:/etc/nginx# ls conf.d fastcgi_params koi-win modules scgi_params win-utf example.property.1 koi-utf mime.types nginx.conf uwsgi_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中的使用場景。