Using subPath in K8S Volume

This article was last updated on: July 24, 2024 am

Using subPath

Sometimes it is useful to share volumes within a single Pod for use by multiple parties. The volumeMounts.subPath property can be used to specify a subpath within the referenced volume, rather than its root path.

The following is an example of a Pod with a LAMP stack (Linux Apache Mysql PHP) using the same shared volume. The HTML content is mapped to the html folder of the volume, and the database will be stored in the mysql folder of the volume:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
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

To explain the above configuration.

The name under volumeMounts is the name of the volume assigned to this pod, site-data, which is used as a subpath for mysql and html for php: mysql and html respectively.
2. volumes For the site-data volume, it is provided in the form of a PVC with the name: my-lamp-site-data

Use subPath with extended environment variables

FEATURE STATE: Kubernetes v1.15 feature-state-beta.txt

Use the subPathExpr field to construct the subPath directory name from the Downward API environment variable. The VolumeSubpathEnvExpansion function switch must be enabled before this feature can be used. The subPath and subPathExpr properties are mutually exclusive.

In this example, the Pod uses subPathExpr to create the directory pod1 in the hostPath volume /var/log/pods, based on the Pod name in the Downward API. The host directory /var/log/pods/pod1 is mounted to the container’s /logs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods

Description.

  1. env, configured POD_NAME environment variable, the value of this variable from metadata.name, that is pod1. 2.
  2. subPathExpr: $(POD_NAME) subpath is $(POD_NAME) variable, which is pod1.
  3. volume uses hostPath, the actual path is: /var/log/pods. Then the full path is /var/log/pods/pod1.

Summary

subPath is still quite useful, it’s a small feature, but it does help with submission efficiency. For example, the container I built yesterday for Zendo. It’s a typical LAMP: Linux + Apache + Mysql + PHP.

Among these components.

  • www/html of Apache needs to be mounted
  • mysql database needs to be mounted
  • php application data needs to be mounted

If I don’t use subPath, then I have to do this: (nfs for example)

  1. manually create 3 subdirectories under nfs: html mysql php
  2. create 3 PVs, which are: apache-volume mysql-volume php-volume
  3. write 3 PVCs, which are: apache-claim mysql-claim php-claim. And 2 and 3 are best built with one pv + one PVC. To avoid the boundary mess. 4.
  4. and then modify the Deployment configuration, one by one to mount it.

△ counted, 10 steps.

Use subPath, really save workload: (or nfs for example)

  1. create 1 PV, for: LAMP-volume. 2.
  2. create a PVC, as: LAMP-claim 3.
  3. modify Deployment configuration, mount a PVC, and use subPath to differentiate.

△ Counting, 3 steps.