| --- |
| apiVersion: apps/v1 |
| kind: Deployment |
| metadata: |
| annotations: |
| kubectl.kubernetes.io/last-applied-configuration: | |
| {"apiVersion":"apps/v1beta2","kind":"Deployment","metadata":{"annotations":{},"name":"local-path-provisioner","namespace":"local-path-storage"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"local-path-provisioner"}},"template":{"metadata":{"labels":{"app":"local-path-provisioner"}},"spec":{"containers":[{"command":["local-path-provisioner","--debug","start","--config","/etc/config/config.json"],"env":[{"name":"POD_NAMESPACE","valueFrom":{"fieldRef":{"fieldPath":"metadata.namespace"}}}],"image":"rancher/local-path-provisioner:v0.0.2","imagePullPolicy":"Always","name":"local-path-provisioner","volumeMounts":[{"mountPath":"/etc/config/","name":"config-volume"}]}],"serviceAccountName":"local-path-provisioner-service-account","volumes":[{"configMap":{"name":"local-path-config"},"name":"config-volume"}]}}}} |
| labels: |
| app: local-path-provisioner |
| name: local-path-provisioner |
| namespace: local-path-storage |
| spec: |
| progressDeadlineSeconds: 600 |
| replicas: 1 |
| revisionHistoryLimit: 10 |
| selector: |
| matchLabels: |
| app: local-path-provisioner |
| strategy: |
| rollingUpdate: |
| maxSurge: 25% |
| maxUnavailable: 25% |
| type: RollingUpdate |
| template: |
| metadata: |
| labels: |
| app: local-path-provisioner |
| spec: |
| containers: |
| - command: |
| - local-path-provisioner |
| - --debug |
| - start |
| - --config |
| - /etc/config/config.json |
| env: |
| - name: POD_NAMESPACE |
| valueFrom: |
| fieldRef: |
| apiVersion: v1 |
| fieldPath: metadata.namespace |
| image: rancher/local-path-provisioner:v0.0.19 |
| imagePullPolicy: Always |
| name: local-path-provisioner |
| resources: {} |
| terminationMessagePath: /dev/termination-log |
| terminationMessagePolicy: File |
| volumeMounts: |
| - mountPath: /etc/config/ |
| name: config-volume |
| dnsPolicy: ClusterFirst |
| restartPolicy: Always |
| schedulerName: default-scheduler |
| securityContext: {} |
| serviceAccount: local-path-provisioner-service-account |
| serviceAccountName: local-path-provisioner-service-account |
| terminationGracePeriodSeconds: 30 |
| volumes: |
| - configMap: |
| defaultMode: 420 |
| name: local-path-config |
| name: config-volume |
| --- |
| apiVersion: v1 |
| data: |
| config.json: |- |
| { |
| "nodePathMap":[ |
| { |
| "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES", |
| "paths":["/var/k8s"] |
| } |
| ] |
| } |
| helperPod.yaml: "apiVersion: v1\nkind: Pod\nmetadata:\n name: helper-pod\nspec:\n hostPID: true\n containers:\n - name: helper-pod\n image: alpine:3.20\n securityContext:\n privileged: true\n" |
| setup: "#!/bin/sh\n# Creates a ZFS dataset per PV. The helper pod runs with hostPID, and all\n# ZFS and filesystem operations are performed in the host's mount namespace\n# (nsenter -t 1 -m). Running zfs directly inside the helper container would\n# mount the dataset only inside the container's own mount namespace; the\n# workload would then write into the parent dataset, and the child dataset\n# would shadow that data after the next host reboot.\nset -eu\n\nwhile getopts \"m:s:p:\" opt\ndo\n case $opt in\n p)\n absolutePath=$OPTARG\n ;;\n s)\n sizeInBytes=$OPTARG\n ;;\n m)\n volMode=$OPTARG\n ;;\n esac\ndone\n\nhost() { nsenter -t 1 -m -- \"$@\"; }\n\nhost zfs create \"rpool${absolutePath}\"\nhost zfs mount \"rpool${absolutePath}\" 2>/dev/null || :\nhost findmnt -n -o SOURCE \"${absolutePath}\" | grep -qx \"rpool${absolutePath}\"\nhost chmod 0777 \"${absolutePath}\"\n" |
| teardown: | |
| #!/bin/sh |
| # Unmounts (but keeps) the PV's ZFS dataset. Runs in the host's mount |
| # namespace; see setup.sh. |
| set -eu |
| |
| while getopts "m:s:p:" opt |
| do |
| case $opt in |
| p) |
| absolutePath=$OPTARG |
| ;; |
| s) |
| sizeInBytes=$OPTARG |
| ;; |
| m) |
| volMode=$OPTARG |
| ;; |
| esac |
| done |
| |
| nsenter -t 1 -m -- zfs set mountpoint=none "rpool${absolutePath}" |
| kind: ConfigMap |
| metadata: |
| annotations: |
| kubectl.kubernetes.io/last-applied-configuration: | |
| {"apiVersion":"v1","data":{"config.json":"{\n \"nodePathMap\":[\n {\n \"node\":\"DEFAULT_PATH_FOR_NON_LISTED_NODES\",\n \"paths\":[\"/var/k8s\"]\n }\n ]\n}"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"local-path-config","namespace":"local-path-storage"}} |
| name: local-path-config |
| namespace: local-path-storage |
| --- |
| apiVersion: v1 |
| kind: ServiceAccount |
| metadata: |
| annotations: |
| kubectl.kubernetes.io/last-applied-configuration: | |
| {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"local-path-provisioner-service-account","namespace":"local-path-storage"}} |
| name: local-path-provisioner-service-account |
| namespace: local-path-storage |
| --- |
| apiVersion: rbac.authorization.k8s.io/v1 |
| kind: RoleBinding |
| metadata: |
| name: local-path-provisioner:psp:default |
| namespace: local-path-storage |
| roleRef: |
| apiGroup: rbac.authorization.k8s.io |
| kind: ClusterRole |
| name: psp:default |
| subjects: |
| - kind: ServiceAccount |
| name: local-path-provisioner-service-account |
| namespace: local-path-storage |
| --- |
| apiVersion: rbac.authorization.k8s.io/v1 |
| kind: ClusterRole |
| metadata: |
| annotations: |
| kubectl.kubernetes.io/last-applied-configuration: | |
| {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRole","metadata":{"annotations":{},"name":"local-path-provisioner-role"},"rules":[{"apiGroups":[""],"resources":["nodes","persistentvolumeclaims"],"verbs":["get","list","watch"]},{"apiGroups":[""],"resources":["endpoints","persistentvolumes","pods"],"verbs":["*"]},{"apiGroups":[""],"resources":["events"],"verbs":["create","patch"]},{"apiGroups":["storage.k8s.io"],"resources":["storageclasses"],"verbs":["get","list","watch"]}]} |
| name: local-path-provisioner-role |
| rules: |
| - apiGroups: |
| - "" |
| resources: |
| - nodes |
| - persistentvolumeclaims |
| - configmaps |
| verbs: |
| - get |
| - list |
| - watch |
| - apiGroups: |
| - "" |
| resources: |
| - endpoints |
| - persistentvolumes |
| - pods |
| verbs: |
| - '*' |
| - apiGroups: |
| - "" |
| resources: |
| - events |
| verbs: |
| - create |
| - patch |
| - apiGroups: |
| - storage.k8s.io |
| resources: |
| - storageclasses |
| verbs: |
| - get |
| - list |
| - watch |
| --- |
| apiVersion: rbac.authorization.k8s.io/v1 |
| kind: ClusterRoleBinding |
| metadata: |
| annotations: |
| kubectl.kubernetes.io/last-applied-configuration: | |
| {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"local-path-provisioner-bind"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"local-path-provisioner-role"},"subjects":[{"kind":"ServiceAccount","name":"local-path-provisioner-service-account","namespace":"local-path-storage"}]} |
| name: local-path-provisioner-bind |
| roleRef: |
| apiGroup: rbac.authorization.k8s.io |
| kind: ClusterRole |
| name: local-path-provisioner-role |
| subjects: |
| - kind: ServiceAccount |
| name: local-path-provisioner-service-account |
| namespace: local-path-storage |
| --- |
| apiVersion: storage.k8s.io/v1 |
| kind: StorageClass |
| metadata: |
| annotations: |
| kubectl.kubernetes.io/last-applied-configuration: | |
| {"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{},"name":"local-path"},"provisioner":"rancher.io/local-path","reclaimPolicy":"Delete","volumeBindingMode":"WaitForFirstConsumer"} |
| name: local-path |
| provisioner: rancher.io/local-path |
| reclaimPolicy: Delete |
| volumeBindingMode: WaitForFirstConsumer |