Context
Assume we are sketching a Kubernetes
deployment of a containerized ducktales
application. This application both leverages a configuration file, duck.properties
, and some data. Because they do not obey the same constraints, we are likely to find them persisted accordingly and thus split in two. This said, during runtime, application expects to have both of them located at the same place, under its /data
folder.

Here we can imagine data to be 3D models for our duck team while configuration gathers some dynamic settings like the color of the caps.
Stitching
Luckily, Kubernetes
comes in with its built-in volumes mounting feature to perform stitching. Here we mount data from a persistentVolumeClaim
through mountPath
, and configuration from dedicated configMap
section combining both mountPath
and subPath
.
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
26
27
28
29
30
31
32
33
34
35
|
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: ducktales
image: ducktales:1987
volumeMounts:
- name: config-volume
mountPath: /data/duck.properties
subPath: duck.properties
- name: backup-volume
mountPath: /data
volumes:
- name: config-volume
configMap:
name: instance-config
- name: backup-volume
persistentVolumeClaim:
claimName: shared-storage
---
apiVersion: v1
kind: ConfigMap
data:
duck.properties : |
cap-color-one=red
cap-color-one=blue
cap-color-one=green
---
apiVersion: v1
kind: PersistentVolumeClaim
spec:
accessModes:
- ReadWriteMany
|
Inspecting living ducktales
pod confirms setup is as expected:
1
2
3
4
5
6
7
8
|
ls /data
# => duck.properties huey/ dewey/ louie/
cat duck.properties
# => cap-color-one=red
# => cap-color-one=blue
# => cap-color-one=green
|
Default
Imagine now we would like to fallback to default for configuration, we can simply remove the matching mount.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- - name: ducktales
+ - name: ducktales-origin
image: ducktales:1987
volumeMounts:
- - name: config-volume
- mountPath: /data/duck.properties
- subPath: duck.properties
- name: backup-volume
mountPath: /data
volumes:
- - name: config-volume
- configMap:
- name: instance-config
- name: backup-volume
persistentVolumeClaim:
claimName: shared-storage
|
We can notice that even if duck.properties
was previously mounted within ducktales
pod /data
folder, collocating with persistent data, it appears file content was not persisted in the persistent volume. We can check this by inspecting the brand-new ducktales-origin
pod, and see that even if a duck.properties
file is still present, it appears to be empty.
1
2
3
4
5
6
|
ls /data
# => duck.properties huey/ dewey/ louie/
cat duck.properties
# => Ø
|
Siblings
This also means that two instances can peacefully leverage common data while being customized independently. Let’s introduce a new instance with a new set of settings to check this assertion. This scenario is common, e.g., for canary deployment where we would like to test new settings while working at existing data, or for collaboration purpose where we would like to customize our application according to external context. Here we are. For Halloween, we decided to promote a dedicated color schema instead of the plain old one.
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: ducktales
image: ducktales:1987
volumeMounts:
- name: config-volume
mountPath: /data/duck.properties
subPath: duck.properties
- name: backup-volume
mountPath: /data
+ - name: ducktales-halloween
+ image: ducktales:1987
+ volumeMounts:
+ - name: config-volume
+ mountPath: /data/duck.properties
+ subPath: duck-halloween.properties
+ - name: backup-volume
+ mountPath: /data
volumes:
- name: config-volume
configMap:
name: instance-config
- name: backup-volume
persistentVolumeClaim:
claimName: shared-storage
---
apiVersion: v1
kind: ConfigMap
data:
duck.properties : |
cap-color-one=red
cap-color-one=blue
cap-color-one=green
+ duck-halloween.properties : |
+ cap-color-one=orange
+ cap-color-one=black
+ cap-color-one=purple
|
Let’s inspect ducktales
pod:
1
2
3
4
5
6
7
8
|
ls /data
# => duck.properties huey/ dewey/ louie/
cat duck.properties
# => cap-color-one=red
# => cap-color-one=blue
# => cap-color-one=green
|
and do the same for ducktales-halloween
one:
1
2
3
4
5
6
7
8
|
ls /data
# => duck.properties huey/ dewey/ louie/
cat duck.properties
# => cap-color-one=orange
# => cap-color-one=black
# => cap-color-one=purple
|
Closing
Data is a complex topic and there are a couple of good design pattern to have in mind to streamline their usage. One of them is to ensure we keep persistence and runtime agnostic of each others. By doing so, we need some tooling to translate from one realm to the other. Here we see how we could leverage Kubernetes
built-in volume mounting feature to compose heterogenous source to a compelling runtime setup while ensuring we keep enough flexibility to address upcoming scenario.