hostpath-provisioner
hostpath-provisioner copied to clipboard
pvc directory can not be deleted when I use NODE_HOST_PATH to set a custom directory as my hostpath mount point,such as /data
when I use NODE_HOST_PATH to set a custom directory as my hostpath mount point,such as /data. If i create pvc and pod by the yaml file below.The pvc directory is created normal in /data.but when I delete the pod and pvc, The pvc directory is still exists.
[root@easyk8s1 ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
hostpath hostpath Delete Immediate false 15m
managed-nfs-storage (default) fuseim.pri/ifs Delete Immediate false 11d
[root@easyk8s1 ~]# cat /root/hostpath-pvc.yaml
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-hostpath-pvc
spec:
storageClassName: "hostpath"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: test-deployment
labels:
app: test-deployment
spec:
replicas: 1
selector:
matchLabels:
app: test-deployment
template:
metadata:
labels:
app: test-deployment
spec:
containers:
- name: test-deployment
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
volumeMounts:
- name: hostpath-pvc
mountPath: "/usr/share/nginx/html"
volumes:
- name: hostpath-pvc
persistentVolumeClaim:
claimName: test-hostpath-pvc
[root@easyk8s1 ~]# kubectl get deployment -n hostpath-provisioner my-hostpath-provisioner -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2021-08-26T12:49:01Z"
generation: 1
labels:
app.kubernetes.io/instance: my-hostpath-provisioner
app.kubernetes.io/managed-by: Tiller
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.11
managedFields:
- apiVersion: apps/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
.: {}
f:app.kubernetes.io/instance: {}
f:app.kubernetes.io/managed-by: {}
f:app.kubernetes.io/name: {}
f:helm.sh/chart: {}
f:spec:
f:progressDeadlineSeconds: {}
f:replicas: {}
f:revisionHistoryLimit: {}
f:selector: {}
f:strategy:
f:type: {}
f:template:
f:metadata:
f:labels:
.: {}
f:app.kubernetes.io/instance: {}
f:app.kubernetes.io/name: {}
f:spec:
f:containers:
k:{"name":"hostpath-provisioner"}:
.: {}
f:env:
.: {}
k:{"name":"HOSTPATH_PROVISIONER_NAME"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"NODE_HOST_PATH"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"NODE_NAME"}:
.: {}
f:name: {}
f:valueFrom:
.: {}
f:fieldRef:
.: {}
f:apiVersion: {}
f:fieldPath: {}
f:image: {}
f:imagePullPolicy: {}
f:name: {}
f:resources:
.: {}
f:limits:
.: {}
f:cpu: {}
f:memory: {}
f:requests:
.: {}
f:cpu: {}
f:memory: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:volumeMounts:
.: {}
k:{"mountPath":"/mnt/hostpath"}:
.: {}
f:mountPath: {}
f:name: {}
f:dnsPolicy: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:serviceAccount: {}
f:serviceAccountName: {}
f:terminationGracePeriodSeconds: {}
f:volumes:
.: {}
k:{"name":"pv-volume"}:
.: {}
f:hostPath:
.: {}
f:path: {}
f:type: {}
f:name: {}
manager: Go-http-client
operation: Update
time: "2021-08-26T12:49:01Z"
- apiVersion: apps/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:deployment.kubernetes.io/revision: {}
f:status:
f:availableReplicas: {}
f:conditions:
.: {}
k:{"type":"Available"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
k:{"type":"Progressing"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
f:observedGeneration: {}
f:readyReplicas: {}
f:replicas: {}
f:updatedReplicas: {}
manager: kube-controller-manager
operation: Update
time: "2021-08-26T12:49:02Z"
name: my-hostpath-provisioner
namespace: hostpath-provisioner
resourceVersion: "143592"
selfLink: /apis/apps/v1/namespaces/hostpath-provisioner/deployments/my-hostpath-provisioner
uid: 8b07a84e-ceb3-48ca-8148-43e9077b1911
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/instance: my-hostpath-provisioner
app.kubernetes.io/name: hostpath-provisioner
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/instance: my-hostpath-provisioner
app.kubernetes.io/name: hostpath-provisioner
spec:
containers:
- env:
- name: NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: NODE_HOST_PATH
value: /data
- name: HOSTPATH_PROVISIONER_NAME
value: hostpath
image: quay.io/rimusz/hostpath-provisioner:v0.2.3
imagePullPolicy: IfNotPresent
name: hostpath-provisioner
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /mnt/hostpath
name: pv-volume
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: my-hostpath-provisioner
serviceAccountName: my-hostpath-provisioner
terminationGracePeriodSeconds: 30
volumes:
- hostPath:
path: /data
type: ""
name: pv-volume
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2021-08-26T12:49:02Z"
lastUpdateTime: "2021-08-26T12:49:02Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2021-08-26T12:49:01Z"
lastUpdateTime: "2021-08-26T12:49:02Z"
message: ReplicaSet "my-hostpath-provisioner-75d6bb5868" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
[root@easyk8s1 ~]# kubectl apply -f /root/hostpath-pvc.yaml
persistentvolumeclaim/test-hostpath-pvc created
deployment.apps/test-deployment created
[root@easyk8s1 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-hostpath-pvc Bound pvc-51b85064-d158-44cc-a0d5-10f7ad286407 100Mi RWO hostpath 14s
[root@easyk8s1 ~]# ls /data/
pvc-51b85064-d158-44cc-a0d5-10f7ad286407
[root@easyk8s1 ~]# kubectl delete -f /root/hostpath-pvc.yaml
persistentvolumeclaim "test-hostpath-pvc" deleted
deployment.apps "test-deployment" deleted
[root@easyk8s1 ~]# ls /data/
pvc-51b85064-d158-44cc-a0d5-10f7ad286407
[root@easyk8s1 ~]# kubectl logs -n hostpath-provisioner my-hostpath-provisioner-75d6bb5868-rgqpl
I0826 13:08:36.341866 1 controller.go:926] provision "default/test-hostpath-pvc" class "hostpath": started
I0826 13:08:36.357548 1 controller.go:1026] provision "default/test-hostpath-pvc" class "hostpath": volume "pvc-51b85064-d158-44cc-a0d5-10f7ad286407" provisioned
I0826 13:08:36.357653 1 controller.go:1040] provision "default/test-hostpath-pvc" class "hostpath": trying to save persistentvolume "pvc-51b85064-d158-44cc-a0d5-10f7ad286407"
I0826 13:08:36.358289 1 event.go:221] Event(v1.ObjectReference{Kind:"PersistentVolumeClaim", Namespace:"default", Name:"test-hostpath-pvc", UID:"51b85064-d158-44cc-a0d5-10f7ad286407", APIVersion:"v1", ResourceVersion:"146892", FieldPath:""}): type: 'Normal' reason: 'Provisioning' External provisioner is provisioning volume for claim "default/test-hostpath-pvc"
I0826 13:08:36.374979 1 controller.go:1047] provision "default/test-hostpath-pvc" class "hostpath": persistentvolume "pvc-51b85064-d158-44cc-a0d5-10f7ad286407" saved
I0826 13:08:36.375018 1 controller.go:1088] provision "default/test-hostpath-pvc" class "hostpath": succeeded
I0826 13:08:36.375078 1 event.go:221] Event(v1.ObjectReference{Kind:"PersistentVolumeClaim", Namespace:"default", Name:"test-hostpath-pvc", UID:"51b85064-d158-44cc-a0d5-10f7ad286407", APIVersion:"v1", ResourceVersion:"146892", FieldPath:""}): type: 'Normal' reason: 'ProvisioningSucceeded' Successfully provisioned volume pvc-51b85064-d158-44cc-a0d5-10f7ad286407
I0826 13:09:22.030954 1 controller.go:1097] delete "pvc-51b85064-d158-44cc-a0d5-10f7ad286407": started
I0826 13:09:22.035694 1 controller.go:1125] delete "pvc-51b85064-d158-44cc-a0d5-10f7ad286407": volume deleted
I0826 13:09:22.041431 1 controller.go:1135] delete "pvc-51b85064-d158-44cc-a0d5-10f7ad286407": persistentvolume deleted
I0826 13:09:22.041447 1 controller.go:1137] delete "pvc-51b85064-d158-44cc-a0d5-10f7ad286407": succeeded
Hello, any update on this. I ran into same issue using custom NODE_HOST_PATH. For some reason, only /mnt/hostpath
produces correct permissions (0777), using any other path e.g /mnt/mypath
produces wrong permissions (0755).
An observation is that when using default /mnt/hostpath
and creating a pvc, the folder is created automatically, while a custom path will not create the folder. This explains the different permissions as in default case, the provisioner is creating the folder with umask 0
, while in custom case, the pod is creating the folder with default umask 0022
.
Reproduction
(1) With default value
// deploy provisioner
$ helm upgrade hostpath-provisioner rimusz/hostpath-provisioner --install
// deploy pvc
$ kubectl create -f https://raw.githubusercontent.com/rimusz/hostpath-provisioner/master/deploy/test-claim.yaml
// pv folder is created with correct permissions
$ ll /mnt/hostpath
drwxrwxrwx 2 root root 4096 Oct 4 05:27 pvc-df22fb40-d0b8-45fc-a373-7f7841f32ac3/
(2) With custom value
// deploy provisioner
$ helm upgrade hostpath-provisioner rimusz/hostpath-provisioner --install --set nodeHostPath=/mnt/mypath
// deploy pvc
$ kubectl create -f https://raw.githubusercontent.com/rimusz/hostpath-provisioner/master/deploy/test-claim.yaml
// pv folder is not created
$ ll /mnt/mypath
<empty>
// deploy test-pod
$ kubectl create -f https://raw.githubusercontent.com/rimusz/hostpath-provisioner/master/deploy/test-pod.yaml
// pv folder is created with wrong permissions
$ ll /mnt/mypath
drwxr-xr-x 2 root root 4096 Oct 4 05:18 pvc-f8fe8d17-0593-474d-b0b3-4985d206e124/
Expectation
Folder should always be created by provisioner with relaxed permissions when using custom node hostpath.
Hello, I have faced the same problem, and I found a solution. You must change the mount path inside the pod with the same path outside the pod. Here is the complete yaml:
$ helm template hostpath .
---
# Source: hostpath-provisioner/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: hostpath-hostpath-provisioner
labels:
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.13
app.kubernetes.io/instance: hostpath
app.kubernetes.io/managed-by: Helm
---
# Source: hostpath-provisioner/templates/storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: hostpath
labels:
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.13
app.kubernetes.io/instance: hostpath
app.kubernetes.io/managed-by: Helm
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: hostpath
reclaimPolicy: Delete
---
# Source: hostpath-provisioner/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: hostpath-hostpath-provisioner
labels:
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.13
app.kubernetes.io/instance: hostpath
app.kubernetes.io/managed-by: Helm
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
# Source: hostpath-provisioner/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: hostpath-hostpath-provisioner
labels:
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.13
app.kubernetes.io/instance: hostpath
app.kubernetes.io/managed-by: Helm
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: hostpath-hostpath-provisioner
subjects:
- kind: ServiceAccount
name: hostpath-hostpath-provisioner
namespace: default
---
# Source: hostpath-provisioner/templates/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: hostpath-hostpath-provisioner-leader-locking
labels:
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.13
app.kubernetes.io/instance: hostpath
app.kubernetes.io/managed-by: Helm
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["list", "watch", "create"]
---
# Source: hostpath-provisioner/templates/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: hostpath-hostpath-provisioner-leader-locking
labels:
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.13
app.kubernetes.io/instance: hostpath
app.kubernetes.io/managed-by: Helm
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: hostpath-hostpath-provisioner-leader-locking
subjects:
- kind: ServiceAccount
name: hostpath-hostpath-provisioner
namespace: default
---
# Source: hostpath-provisioner/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hostpath-hostpath-provisioner
labels:
app.kubernetes.io/name: hostpath-provisioner
helm.sh/chart: hostpath-provisioner-0.2.13
app.kubernetes.io/instance: hostpath
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: hostpath-provisioner
app.kubernetes.io/instance: hostpath
template:
metadata:
labels:
app.kubernetes.io/name: hostpath-provisioner
app.kubernetes.io/instance: hostpath
spec:
serviceAccountName: hostpath-hostpath-provisioner
containers:
- name: hostpath-provisioner
image: "quay.io/rimusz/hostpath-provisioner:v0.2.5"
imagePullPolicy: IfNotPresent
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: NODE_HOST_PATH
value: "/Data/Volumes"
- name: HOSTPATH_PROVISIONER_NAME
value: "hostpath"
volumeMounts:
- name: pv-volume
mountPath: /Data/Volumes
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
volumes:
- name: pv-volume
hostPath:
path: /Data/Volumes
To wrap up: change the volumeMounts.pv-volume.mountPath
to be same as volumes.pv-volume.hostPath
in hostpath-provisioner/templates/deployment.yaml
(eg. /Data/Volumes
).
Bug still exist.
My solution for custom directory /media/default-storage
:
kubectl patch deployment hostpath-provisioner -n kube-system --patch-file hostpath-provisioner.patch.yaml
# hostpath-provisioner.patch.yaml
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- env:
- name: PV_DIR
value: /media/default-storage
name: hostpath-provisioner
volumeMounts:
- mountPath: /media/default-storage
name: pv-volume
volumes:
- hostPath:
path: /media/default-storage
name: pv-volume