Skip to content

Commit e821731

Browse files
committed
Enhance helper Pod interface and configuration.
* Make the helper Pod receive only environment variables instead of args (this changes the interface in a non-backward compatible way but is simpler to use and potentially provides more backward compatibility in the future). * Adds the manager options `--pvc-annotation[-required]` to pass through annotations from the PVC to the PV and to the helper Pod. * Merge the helper Pod's `data` VolumeMount with the one provided with the template to be able to specify `mountPropagation` within the template. * Rename `helperPod.yaml` to `helper-pod.yaml` (more convenient and if we break sth we can break this as well). * Expose `--helper-pod-timeout` option. * Provide a basic usage example of the new features (`examples/cache`). * Support forceful termination of the manager binary (2xCtrl+c - since this is annoying during development otherwise). Closes rancher#164 Closes rancher#165 Signed-off-by: Max Goltzsche <[email protected]>
1 parent 01eaa8c commit e821731

28 files changed

+685
-481
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
./.dapper
22
./.cache
33
./dist
4+
./examples/cache/testmount

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@
55
*.swp
66
.idea
77
.vscode/
8-
Dockerfile.dapper[0-9]*
8+
Dockerfile.dapper[0-9]*
9+
local-path-provisioner
10+
/examples/cache/testmount
11+

README.md

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ Now you've verified that the provisioner works as expected.
119119

120120
### Customize the ConfigMap
121121

122-
The configuration of the provisioner is a json file `config.json` and two bash scripts `setup` and `teardown`, stored in the a config map, e.g.:
122+
The configuration of the provisioner is a json file `config.json`, a Pod template `helper-pod.yaml` and two bash scripts `setup` and `teardown`, e.g.:
123123
```
124124
kind: ConfigMap
125125
apiVersion: v1
@@ -146,41 +146,11 @@ data:
146146
}
147147
setup: |-
148148
#!/bin/sh
149-
while getopts "m:s:p:" opt
150-
do
151-
case $opt in
152-
p)
153-
absolutePath=$OPTARG
154-
;;
155-
s)
156-
sizeInBytes=$OPTARG
157-
;;
158-
m)
159-
volMode=$OPTARG
160-
;;
161-
esac
162-
done
163-
164-
mkdir -m 0777 -p ${absolutePath}
149+
mkdir -m 0777 -p "$VOL_DIR"
165150
teardown: |-
166151
#!/bin/sh
167-
while getopts "m:s:p:" opt
168-
do
169-
case $opt in
170-
p)
171-
absolutePath=$OPTARG
172-
;;
173-
s)
174-
sizeInBytes=$OPTARG
175-
;;
176-
m)
177-
volMode=$OPTARG
178-
;;
179-
esac
180-
done
181-
182-
rm -rf ${absolutePath}
183-
helperPod.yaml: |-
152+
rm -rf "$VOL_DIR"
153+
helper-pod.yaml: |-
184154
apiVersion: v1
185155
kind: Pod
186156
metadata:
@@ -209,16 +179,26 @@ The configuration must obey following rules:
209179
3. No duplicate paths allowed for one node.
210180
4. No duplicate node allowed.
211181

212-
#### Scripts `setup` and `teardown` and `helperPod.yaml`
182+
#### Scripts `setup` and `teardown` and the `helper-pod.yaml` template
213183

214-
The script `setup` will be executed before the volume is created, to prepare the directory on the node for the volume.
184+
* The `setup` script is run before the volume is created, to prepare the volume directory on the node.
185+
* The `teardown` script is run after the volume is deleted, to cleanup the volume directory on the node.
186+
* The `helper-pod.yaml` template is used to create a helper Pod that runs the `setup` or `teardown` script.
215187

216-
The script `teardown` will be executed after the volume is deleted, to cleanup the directory on the node for the volume.
188+
The scripts receive their input as environment variables:
217189

218-
The yaml file `helperPod.yaml` will be created by local-path-storage to execute `setup` or `teardown` script with three paramemters `-p <path> -s <size> -m <mode>` :
219-
* path: the absolute path provisioned on the node
220-
- size: pvc.Spec.resources.requests.storage in bytes
221-
* mode: pvc.Spec.VolumeMode
190+
| Environment variable | Description |
191+
| -------------------- | ----------- |
192+
| `VOL_DIR` | Volume directory that should be created or removed. |
193+
| `VOL_NAME` | Name of the PersistentVolume. |
194+
| `VOL_TYPE` | Type of the PersistentVolume (`Block` or `Filesystem`). |
195+
| `VOL_SIZE_BYTES` | Requested volume size in bytes. |
196+
| `PVC_NAME` | Name of the PersistentVolumeClaim. |
197+
| `PVC_NAMESPACE` | Namespace of the PersistentVolumeClaim. |
198+
| `PVC_ANNOTATION` | Value of the PersistentVolumeClaim annotation specified by the manager's `--pvc-annotation` option. |
199+
| `PVC_ANNOTATION_{SUFFIX}` | Value of the PersistentVolumeClaim annotation with the prefix specified by the manager's `--pvc-annotation` option. The `SUFFIX` is the normalized path within the annotation name after the `/`. E.g. if `local-path-provisioner` is run with `--pvc-annotation=storage.example.org` the PVC annotation `storage.example.org/cache-name` is passed through to the Pod as env var `PVC_ANNOTATION_CACHE_NAME`. If the helper Pod requires such an annotation `local-path-provisioner` can be run with e.g. `--pvc-annotation-required=storage.example.org/cache-name`. |
200+
201+
Additional environment variables and defaults for the optional `PVC_ANNOTATION*` can be specified within the helper Pod template.
222202

223203
#### Reloading
224204

debug/config.yaml

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,41 +39,11 @@ data:
3939
}
4040
setup: |-
4141
#!/bin/sh
42-
while getopts "m:s:p:" opt
43-
do
44-
case $opt in
45-
p)
46-
absolutePath=$OPTARG
47-
;;
48-
s)
49-
sizeInBytes=$OPTARG
50-
;;
51-
m)
52-
volMode=$OPTARG
53-
;;
54-
esac
55-
done
56-
57-
mkdir -m 0777 -p ${absolutePath}
42+
mkdir -m 0777 -p "$VOL_DIR"
5843
teardown: |-
5944
#!/bin/sh
60-
while getopts "m:s:p:" opt
61-
do
62-
case $opt in
63-
p)
64-
absolutePath=$OPTARG
65-
;;
66-
s)
67-
sizeInBytes=$OPTARG
68-
;;
69-
m)
70-
volMode=$OPTARG
71-
;;
72-
esac
73-
done
74-
75-
rm -rf ${absolutePath}
76-
helperPod.yaml: |-
45+
rm -rf "$VOL_DIR"
46+
helper-pod.yaml: |-
7747
apiVersion: v1
7848
kind: Pod
7949
metadata:

deploy/chart/templates/configmap.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ data:
1313
{{ .Values.configmap.setup | nindent 4 }}
1414
teardown: |-
1515
{{ .Values.configmap.teardown | nindent 4 }}
16-
helperPod.yaml: |-
16+
helper-pod.yaml: |-
1717
{{ .Values.configmap.helperPod | nindent 4 }}
1818

deploy/chart/values.yaml

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -93,41 +93,10 @@ configmap:
9393
# specify the custom script for setup and teardown
9494
setup: |-
9595
#!/bin/sh
96-
while getopts "m:s:p:" opt
97-
do
98-
case $opt in
99-
p)
100-
absolutePath=$OPTARG
101-
;;
102-
s)
103-
sizeInBytes=$OPTARG
104-
;;
105-
m)
106-
volMode=$OPTARG
107-
;;
108-
esac
109-
done
110-
111-
mkdir -m 0777 -p ${absolutePath}
96+
mkdir -m 0777 -p "$VOL_DIR"
11297
teardown: |-
11398
#!/bin/sh
114-
while getopts "m:s:p:" opt
115-
do
116-
case $opt in
117-
p)
118-
absolutePath=$OPTARG
119-
;;
120-
s)
121-
sizeInBytes=$OPTARG
122-
;;
123-
m)
124-
volMode=$OPTARG
125-
;;
126-
esac
127-
done
128-
129-
rm -rf ${absolutePath}
130-
# specify the custom helper pod yaml
99+
rm -rf "$VOL_DIR"
131100
helperPod: |-
132101
apiVersion: v1
133102
kind: Pod

deploy/example-config.yaml

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,41 +23,11 @@ data:
2323
}
2424
setup: |-
2525
#!/bin/sh
26-
while getopts "m:s:p:" opt
27-
do
28-
case $opt in
29-
p)
30-
absolutePath=$OPTARG
31-
;;
32-
s)
33-
sizeInBytes=$OPTARG
34-
;;
35-
m)
36-
volMode=$OPTARG
37-
;;
38-
esac
39-
done
40-
41-
mkdir -m 0777 -p ${absolutePath}
26+
mkdir -m 0777 -p "$VOL_DIR"
4227
teardown: |-
4328
#!/bin/sh
44-
while getopts "m:s:p:" opt
45-
do
46-
case $opt in
47-
p)
48-
absolutePath=$OPTARG
49-
;;
50-
s)
51-
sizeInBytes=$OPTARG
52-
;;
53-
m)
54-
volMode=$OPTARG
55-
;;
56-
esac
57-
done
58-
59-
rm -rf ${absolutePath}
60-
helperPod.yaml: |-
29+
rm -rf "$VOL_DIR"
30+
helper-pod.yaml: |-
6131
apiVersion: v1
6232
kind: Pod
6333
metadata:
@@ -66,5 +36,3 @@ data:
6636
containers:
6737
- name: helper-pod
6838
image: busybox
69-
70-

deploy/local-path-storage.yaml

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -110,41 +110,11 @@ data:
110110
}
111111
setup: |-
112112
#!/bin/sh
113-
while getopts "m:s:p:" opt
114-
do
115-
case $opt in
116-
p)
117-
absolutePath=$OPTARG
118-
;;
119-
s)
120-
sizeInBytes=$OPTARG
121-
;;
122-
m)
123-
volMode=$OPTARG
124-
;;
125-
esac
126-
done
127-
128-
mkdir -m 0777 -p ${absolutePath}
113+
mkdir -m 0777 -p "$VOL_DIR"
129114
teardown: |-
130115
#!/bin/sh
131-
while getopts "m:s:p:" opt
132-
do
133-
case $opt in
134-
p)
135-
absolutePath=$OPTARG
136-
;;
137-
s)
138-
sizeInBytes=$OPTARG
139-
;;
140-
m)
141-
volMode=$OPTARG
142-
;;
143-
esac
144-
done
145-
146-
rm -rf ${absolutePath}
147-
helperPod.yaml: |-
116+
rm -rf "$VOL_DIR"
117+
helper-pod.yaml: |-
148118
apiVersion: v1
149119
kind: Pod
150120
metadata:
@@ -153,5 +123,3 @@ data:
153123
containers:
154124
- name: helper-pod
155125
image: busybox
156-
157-

examples/cache/README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Example cache provisioner
2+
3+
This example shows how to use short-lived PersistentVolumes for caching.
4+
A [buildah](https://github.com/containers/buildah)-based helper Pod is used to provision a container file system based on an image as PersistentVolume and commit it when deprovisioning.
5+
Users can select the desired cache or rather the image using a PersistentVolumeClaim annotation that is passed through to the helper Pod as environment variable.
6+
7+
While it is not part of this example caches could also be synchronized across nodes using an image registry.
8+
The [cache-provisioner](https://github.com/mgoltzsche/cache-provisioner) project aims to achieve this as well as other cache management features.
9+
10+
## Test
11+
12+
### Test the helper Pod separately
13+
14+
The helper Pod can be tested separately using docker locally:
15+
```sh
16+
./helper-test.sh
17+
```
18+
19+
### Test the integration
20+
21+
_Please note that a non-overlayfs storage directory (`/data/example-cache-storage`) must be configured._
22+
_The provided configuration is known to work with minikube (`minikube start`) and kind (`kind create cluster; kind export kubeconfig`)._
23+
24+
Install the example kustomization:
25+
```sh
26+
kustomize build . | kubectl apply -f -
27+
```
28+
29+
If you want to test changes to the `local-path-provisioner` binary locally:
30+
```sh
31+
kubectl delete -n example-cache-storage deploy example-cache-local-path-provisioner
32+
(
33+
cd ../..
34+
go build .
35+
./local-path-provisioner --debug start \
36+
--namespace=example-cache-storage \
37+
--configmap-name=example-cache-local-path-config \
38+
--service-account-name=example-cache-local-path-provisioner-service-account \
39+
--provisioner-name=storage.example.org/cache \
40+
--pvc-annotation=storage.example.org \
41+
--pvc-annotation-required=storage.example.org/cache-name
42+
)
43+
```
44+
45+
Within another terminal create an example Pod and PVC that pulls and runs a container image using [podman](https://github.com/containers/podman):
46+
```sh
47+
kubectl apply -f test-pod.yaml
48+
kubectl logs -f cached-build
49+
```
50+
51+
If the Pod and PVC are removed and recreated you can observe that, during the 2nd Pod execution on the same node, the image for the nested container doesn't need to be pulled again since it is cached:
52+
```sh
53+
kubectl delete -f test-pod.yaml
54+
kubectl apply -f test-pod.yaml
55+
kubectl logs -f cached-build
56+
```

examples/cache/config/config.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"nodePathMap": [
3+
{
4+
"node": "DEFAULT_PATH_FOR_NON_LISTED_NODES",
5+
"paths": ["/data/example-cache-storage"]
6+
},
7+
{
8+
"node": "minikube",
9+
"paths": ["/data/example-cache-storage"]
10+
},
11+
{
12+
"node": "kind-control-plane",
13+
"paths": ["/var/opt/example-cache-storage"]
14+
}
15+
]
16+
}

examples/cache/config/helper-pod.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: helper-pod
5+
spec:
6+
containers:
7+
- name: helper
8+
image: quay.io/buildah/stable:v1.18.0
9+
imagePullPolicy: IfNotPresent
10+
securityContext:
11+
privileged: true
12+
hostPID: true
13+
volumeMounts:
14+
- name: data
15+
mountPropagation: Bidirectional

0 commit comments

Comments
 (0)