blob: cc80544eeaa05770df3aa1c112a0da4704f6e688 [file] [log] [blame]
Matthias Andreas Benkardea839162026-11-04 20:47:43 +01001# local-path-provisioner v0.0.37, based on upstream deploy/local-path-storage.yaml
2# with these local changes:
3# - PVs live under /var/k8s; setup.sh/teardown.sh create and unmount one
4# ZFS dataset per PV (rpool/var/k8s/<pv>) in the host mount namespace.
5# - The helper pod needs hostPID and privileged for nsenter.
6# - The namespace (PSA enforce=privileged) is not managed here.
7# setup and teardown below must stay in sync with setup.sh and teardown.sh.
8# The provisioner reads helperPod.yaml only at startup; restart it after
9# changing that.
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010010apiVersion: apps/v1
11kind: Deployment
12metadata:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010013 name: local-path-provisioner
14 namespace: local-path-storage
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010015 labels:
16 app: local-path-provisioner
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010017spec:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010018 replicas: 1
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010019 selector:
20 matchLabels:
21 app: local-path-provisioner
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010022 template:
23 metadata:
24 labels:
25 app: local-path-provisioner
26 spec:
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010027 serviceAccountName: local-path-provisioner-service-account
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010028 containers:
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010029 - name: local-path-provisioner
30 image: docker.io/rancher/local-path-provisioner:v0.0.37
31 imagePullPolicy: IfNotPresent
32 command:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010033 - local-path-provisioner
34 - --debug
35 - start
36 - --config
37 - /etc/config/config.json
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010038 # The helper pod needs hostPID for nsenter (see setup.sh).
39 - --allow-unsafe-helper-pod-template
40 ports:
41 - name: health
42 containerPort: 8080
43 protocol: TCP
44 startupProbe:
45 httpGet:
46 path: /health
47 port: health
48 initialDelaySeconds: 5
49 periodSeconds: 5
50 failureThreshold: 12
51 livenessProbe:
52 httpGet:
53 path: /health
54 port: health
55 initialDelaySeconds: 10
56 periodSeconds: 10
57 readinessProbe:
58 httpGet:
59 path: /ready
60 port: health
61 initialDelaySeconds: 5
62 periodSeconds: 5
63 volumeMounts:
64 - name: config-volume
65 mountPath: /etc/config/
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010066 env:
67 - name: POD_NAMESPACE
68 valueFrom:
69 fieldRef:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010070 fieldPath: metadata.namespace
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010071 - name: CONFIG_MOUNT_PATH
72 value: /etc/config/
73 - name: HEALTH_PORT
74 value: "8080"
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010075 volumes:
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010076 - name: config-volume
77 configMap:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010078 name: local-path-config
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010079---
80apiVersion: v1
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010081kind: ConfigMap
82metadata:
83 name: local-path-config
84 namespace: local-path-storage
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010085data:
86 config.json: |-
87 {
88 "nodePathMap":[
89 {
90 "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
91 "paths":["/var/k8s"]
92 }
93 ]
94 }
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010095 setup: |
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +010096 #!/bin/sh
Matthias Andreas Benkardea839162026-11-04 20:47:43 +010097 # Creates a ZFS dataset per PV. The helper pod runs with hostPID, and all
98 # ZFS and filesystem operations are performed in the host's mount namespace
99 # (nsenter -t 1 -m). Running zfs directly inside the helper container would
100 # mount the dataset only inside the container's own mount namespace; the
101 # workload would then write into the parent dataset, and the child dataset
102 # would shadow that data after the next host reboot.
103 #
104 # The provisioner passes the volume path as $VOL_DIR (v0.0.2x and later);
105 # older versions passed it as -p.
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100106 set -eu
107
Matthias Andreas Benkardea839162026-11-04 20:47:43 +0100108 absolutePath=${VOL_DIR:-}
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100109 while getopts "m:s:p:" opt
110 do
111 case $opt in
112 p)
113 absolutePath=$OPTARG
114 ;;
115 s)
116 sizeInBytes=$OPTARG
117 ;;
118 m)
119 volMode=$OPTARG
120 ;;
121 esac
122 done
Matthias Andreas Benkardea839162026-11-04 20:47:43 +0100123 [ -n "$absolutePath" ] || { echo "setup: no volume path given" >&2; exit 1; }
124
125 host() { nsenter -t 1 -m -- "$@"; }
126
127 host zfs create "rpool${absolutePath}"
128 host zfs mount "rpool${absolutePath}" 2>/dev/null || :
129 host findmnt -n -o SOURCE "${absolutePath}" | grep -qx "rpool${absolutePath}"
130 host chmod 0777 "${absolutePath}"
131 teardown: |
132 #!/bin/sh
133 # Unmounts (but keeps) the PV's ZFS dataset. Runs in the host's mount
134 # namespace; see setup.sh.
135 set -eu
136
137 absolutePath=${VOL_DIR:-}
138 while getopts "m:s:p:" opt
139 do
140 case $opt in
141 p)
142 absolutePath=$OPTARG
143 ;;
144 s)
145 sizeInBytes=$OPTARG
146 ;;
147 m)
148 volMode=$OPTARG
149 ;;
150 esac
151 done
152 [ -n "$absolutePath" ] || { echo "teardown: no volume path given" >&2; exit 1; }
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100153
154 nsenter -t 1 -m -- zfs set mountpoint=none "rpool${absolutePath}"
Matthias Andreas Benkardea839162026-11-04 20:47:43 +0100155 helperPod.yaml: |
156 apiVersion: v1
157 kind: Pod
158 metadata:
159 name: helper-pod
160 spec:
161 priorityClassName: system-node-critical
162 tolerations:
163 - key: node.kubernetes.io/disk-pressure
164 operator: Exists
165 effect: NoSchedule
166 hostPID: true
167 containers:
168 - name: helper-pod
169 image: alpine:3.20
170 imagePullPolicy: IfNotPresent
171 securityContext:
172 privileged: true
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100173---
174apiVersion: v1
175kind: ServiceAccount
176metadata:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100177 name: local-path-provisioner-service-account
178 namespace: local-path-storage
179---
Matthias Andreas Benkardea839162026-11-04 20:47:43 +0100180# Since v0.0.24 helper pods run in the provisioner's namespace.
181apiVersion: rbac.authorization.k8s.io/v1
182kind: Role
183metadata:
184 name: local-path-provisioner-role
185 namespace: local-path-storage
186rules:
187 - apiGroups: [""]
188 resources: ["pods"]
189 verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
190---
191apiVersion: rbac.authorization.k8s.io/v1
192kind: RoleBinding
193metadata:
194 name: local-path-provisioner-bind
195 namespace: local-path-storage
196roleRef:
197 apiGroup: rbac.authorization.k8s.io
198 kind: Role
199 name: local-path-provisioner-role
200subjects:
201 - kind: ServiceAccount
202 name: local-path-provisioner-service-account
203 namespace: local-path-storage
204---
205# Leftover from PodSecurityPolicy times (psp:default no longer grants anything).
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100206apiVersion: rbac.authorization.k8s.io/v1
207kind: RoleBinding
208metadata:
209 name: local-path-provisioner:psp:default
210 namespace: local-path-storage
211roleRef:
212 apiGroup: rbac.authorization.k8s.io
213 kind: ClusterRole
214 name: psp:default
215subjects:
216 - kind: ServiceAccount
217 name: local-path-provisioner-service-account
218 namespace: local-path-storage
219---
220apiVersion: rbac.authorization.k8s.io/v1
221kind: ClusterRole
222metadata:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100223 name: local-path-provisioner-role
224rules:
Matthias Andreas Benkardea839162026-11-04 20:47:43 +0100225 - apiGroups: [""]
226 resources: ["nodes", "persistentvolumeclaims", "configmaps", "pods", "pods/log"]
227 verbs: ["get", "list", "watch"]
228 - apiGroups: [""]
229 resources: ["persistentvolumes"]
230 verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
231 - apiGroups: [""]
232 resources: ["events"]
233 verbs: ["create", "patch"]
234 - apiGroups: ["storage.k8s.io"]
235 resources: ["storageclasses"]
236 verbs: ["get", "list", "watch"]
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100237---
238apiVersion: rbac.authorization.k8s.io/v1
239kind: ClusterRoleBinding
240metadata:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100241 name: local-path-provisioner-bind
242roleRef:
243 apiGroup: rbac.authorization.k8s.io
244 kind: ClusterRole
245 name: local-path-provisioner-role
246subjects:
247 - kind: ServiceAccount
248 name: local-path-provisioner-service-account
249 namespace: local-path-storage
250---
251apiVersion: storage.k8s.io/v1
252kind: StorageClass
253metadata:
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100254 name: local-path
255provisioner: rancher.io/local-path
Matthias Andreas Benkard05e482e2026-11-04 11:05:51 +0100256volumeBindingMode: WaitForFirstConsumer
Matthias Andreas Benkardea839162026-11-04 20:47:43 +0100257reclaimPolicy: Delete