diff --git a/README.md b/README.md index e120441..fe57f75 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ **NFS subdir external provisioner** is an automatic provisioner that use your _existing and already configured_ NFS server to support dynamic provisioning of Kubernetes Persistent Volumes via Persistent Volume Claims. Persistent volumes are provisioned as `${namespace}-${pvcName}-${pvName}`. Note: This repository is migrated from https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client. As part of the migration: -- The container image name and repository has changed to `gcr.io/k8s-staging-sig-storage` and `nfs-subdir-external-provisioner` respectively. +- The container image name and repository has changed to `k8s.gcr.io/sig-storage` and `nfs-subdir-external-provisioner` respectively. - To maintain backward compatibility with earlier deployment files, the naming of NFS Client Provisioner is retained as `nfs-client-provisioner` in the deployment YAMLs. - One of the pending areas for development on this repository is to add automated e2e tests. If you would like to contribute, please raise an issue or reach us on the Kubernetes slack #sig-storage channel. @@ -178,8 +178,7 @@ On OpenShift the service account used to bind volumes does not have the necessar $ NAMESPACE=`oc project -q` $ sed -i'' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/rbac.yaml $ oc create -f deploy/rbac.yaml -$ oc create role use-scc-hostmount-anyuid --verb=use --resource=scc --resource-name=hostmount-anyuid -n $NAMESPACE -$ oc adm policy add-role-to-user use-scc-hostmount-anyuid system:serviceaccount:$NAMESPACE:nfs-client-provisioner +$ oc adm policy add-scc-to-user hostmount-anyuid system:serviceaccount:$NAMESPACE:nfs-client-provisioner ``` **Step 4: Configure the NFS subdir external provisioner** @@ -208,7 +207,7 @@ spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner - image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.2 + image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes diff --git a/charts/nfs-subdir-external-provisioner/Chart.yaml b/charts/nfs-subdir-external-provisioner/Chart.yaml index 7ec28c9..a6547ab 100644 --- a/charts/nfs-subdir-external-provisioner/Chart.yaml +++ b/charts/nfs-subdir-external-provisioner/Chart.yaml @@ -3,7 +3,7 @@ appVersion: 4.0.2 description: nfs-subdir-external-provisioner is an automatic provisioner that used your *already configured* NFS server, automatically creating Persistent Volumes. name: nfs-subdir-external-provisioner home: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner -version: 4.0.7 +version: 4.0.11 kubeVersion: ">=1.9.0-0" sources: - https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner diff --git a/charts/nfs-subdir-external-provisioner/README.md b/charts/nfs-subdir-external-provisioner/README.md index 48270e5..0055e79 100644 --- a/charts/nfs-subdir-external-provisioner/README.md +++ b/charts/nfs-subdir-external-provisioner/README.md @@ -48,32 +48,38 @@ The command removes all the Kubernetes components associated with the chart and The following tables lists the configurable parameters of this chart and their default values. -| Parameter | Description | Default | -| ----------------------------------- | ----------------------------------------------------------- | ------------------------------------------------- | -| `replicaCount` | Number of provisioner instances to deployed | `1` | -| `strategyType` | Specifies the strategy used to replace old Pods by new ones | `Recreate` | -| `image.repository` | Provisioner image | `gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner` | -| `image.tag` | Version of provisioner image | `v4.0.2` | -| `image.pullPolicy` | Image pull policy | `IfNotPresent` | -| `storageClass.name` | Name of the storageClass | `nfs-client` | -| `storageClass.defaultClass` | Set as the default StorageClass | `false` | -| `storageClass.allowVolumeExpansion` | Allow expanding the volume | `true` | -| `storageClass.reclaimPolicy` | Method used to reclaim an obsoleted volume | `Delete` | -| `storageClass.provisionerName` | Name of the provisionerName | null | -| `storageClass.archiveOnDelete` | Archive PVC when deleting | `true` | -| `storageClass.onDelete` | Strategy on PVC deletion. Overrides `archiveOnDelete` when set to lowercase values `delete` or `retain` | null | -| `storageClass.pathPattern` | Specifies a template for the directory name | null | -| `storageClass.accessModes` | Set access mode for PV | `ReadWriteOnce` | -| `leaderElection.enabled` | Enables or disables leader election | `true` | -| `nfs.server` | Hostname of the NFS server (required) | null (ip or hostname) | -| `nfs.path` | Basepath of the mount point to be used | `/nfs-storage` | -| `nfs.mountOptions` | Mount options (e.g. 'nfsvers=3') | null | -| `resources` | Resources required (e.g. CPU, memory) | `{}` | -| `rbac.create` | Use Role-based Access Control | `true` | -| `podSecurityPolicy.enabled` | Create & use Pod Security Policy resources | `false` | -| `priorityClassName` | Set pod priorityClassName | null | -| `serviceAccount.create` | Should we create a ServiceAccount | `true` | -| `serviceAccount.name` | Name of the ServiceAccount to use | null | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| `affinity` | Affinity settings | `{}` | -| `tolerations` | List of node taints to tolerate | `[]` | +| Parameter | Description | Default | +| ----------------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `replicaCount` | Number of provisioner instances to deployed | `1` | +| `strategyType` | Specifies the strategy used to replace old Pods by new ones | `Recreate` | +| `image.repository` | Provisioner image | `k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner` | +| `image.tag` | Version of provisioner image | `v4.0.2` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `imagePullSecrets` | Image pull secrets | `[]` | +| `storageClass.name` | Name of the storageClass | `nfs-client` | +| `storageClass.defaultClass` | Set as the default StorageClass | `false` | +| `storageClass.allowVolumeExpansion` | Allow expanding the volume | `true` | +| `storageClass.reclaimPolicy` | Method used to reclaim an obsoleted volume | `Delete` | +| `storageClass.provisionerName` | Name of the provisionerName | null | +| `storageClass.archiveOnDelete` | Archive PVC when deleting | `true` | +| `storageClass.onDelete` | Strategy on PVC deletion. Overrides archiveOnDelete when set to lowercase values 'delete' or 'retain' | null | +| `storageClass.pathPattern` | Specifies a template for the directory name | null | +| `storageClass.accessModes` | Set access mode for PV | `ReadWriteOnce` | +| `storageClass.annotations` | Set additional annotations for the StorageClass | `{}` | +| `leaderElection.enabled` | Enables or disables leader election | `true` | +| `nfs.server` | Hostname of the NFS server (required) | null (ip or hostname) | +| `nfs.path` | Basepath of the mount point to be used | `/nfs-storage` | +| `nfs.mountOptions` | Mount options (e.g. 'nfsvers=3') | null | +| `nfs.volumeName` | Volume name used inside the pods | `nfs-subdir-external-provisioner-root` | +| `resources` | Resources required (e.g. CPU, memory) | `{}` | +| `rbac.create` | Use Role-based Access Control | `true` | +| `podSecurityPolicy.enabled` | Create & use Pod Security Policy resources | `false` | +| `podAnnotations` | Additional annotations for the Pods | `{}` | +| `priorityClassName` | Set pod priorityClassName | null | +| `serviceAccount.create` | Should we create a ServiceAccount | `true` | +| `serviceAccount.name` | Name of the ServiceAccount to use | null | +| `serviceAccount.annotations` | Additional annotations for the ServiceAccount | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `affinity` | Affinity settings | `{}` | +| `tolerations` | List of node taints to tolerate | `[]` | +| `labels` | Additional labels for any resource created | `{}` | diff --git a/charts/nfs-subdir-external-provisioner/templates/_helpers.tpl b/charts/nfs-subdir-external-provisioner/templates/_helpers.tpl index b5eaabf..4b9d8fa 100644 --- a/charts/nfs-subdir-external-provisioner/templates/_helpers.tpl +++ b/charts/nfs-subdir-external-provisioner/templates/_helpers.tpl @@ -59,4 +59,24 @@ Return the appropriate apiVersion for podSecurityPolicy. {{- else -}} {{- print "extensions/v1beta1" -}} {{- end -}} -{{- end -}} \ No newline at end of file +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "nfs-subdir-external-provisioner.labels" -}} +chart: {{ template "nfs-subdir-external-provisioner.chart" . }} +heritage: {{ .Release.Service }} +{{ include "nfs-subdir-external-provisioner.selectorLabels" . }} +{{- with .Values.labels }} +{{- toYaml . | nindent 0 }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "nfs-subdir-external-provisioner.selectorLabels" -}} +app: {{ template "nfs-subdir-external-provisioner.name" . }} +release: {{ .Release.Name }} +{{- end }} diff --git a/charts/nfs-subdir-external-provisioner/templates/clusterrole.yaml b/charts/nfs-subdir-external-provisioner/templates/clusterrole.yaml index c80d5de..078cfcc 100644 --- a/charts/nfs-subdir-external-provisioner/templates/clusterrole.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/clusterrole.yaml @@ -3,12 +3,12 @@ kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ template "nfs-subdir-external-provisioner.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} name: {{ template "nfs-subdir-external-provisioner.fullname" . }}-runner rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] diff --git a/charts/nfs-subdir-external-provisioner/templates/clusterrolebinding.yaml b/charts/nfs-subdir-external-provisioner/templates/clusterrolebinding.yaml index 528c6de..c5e5582 100644 --- a/charts/nfs-subdir-external-provisioner/templates/clusterrolebinding.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/clusterrolebinding.yaml @@ -3,10 +3,7 @@ kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ template "nfs-subdir-external-provisioner.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} name: run-{{ template "nfs-subdir-external-provisioner.fullname" . }} subjects: - kind: ServiceAccount diff --git a/charts/nfs-subdir-external-provisioner/templates/deployment.yaml b/charts/nfs-subdir-external-provisioner/templates/deployment.yaml index d8107f3..12ba9b7 100644 --- a/charts/nfs-subdir-external-provisioner/templates/deployment.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/deployment.yaml @@ -3,27 +3,25 @@ kind: Deployment metadata: name: {{ template "nfs-subdir-external-provisioner.fullname" . }} labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ template "nfs-subdir-external-provisioner.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} strategy: type: {{ .Values.strategyType }} selector: matchLabels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.selectorLabels" . | nindent 6 }} template: metadata: annotations: + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- if and (.Values.tolerations) (semverCompare "<1.6-0" .Capabilities.KubeVersion.GitVersion) }} scheduler.alpha.kubernetes.io/tolerations: '{{ toJson .Values.tolerations }}' {{- end }} labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.selectorLabels" . | nindent 8 }} spec: serviceAccountName: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} {{- if .Values.nodeSelector }} @@ -37,16 +35,16 @@ spec: {{- if .Values.priorityClassName }} priorityClassName: {{ .Values.priorityClassName | quote }} {{- end }} - {{- if .Values.imagePullSecrets }} + {{- with .Values.imagePullSecrets }} imagePullSecrets: -{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- toYaml . | nindent 8 }} {{- end }} containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} volumeMounts: - - name: nfs-subdir-external-provisioner-root + - name: {{ .Values.nfs.volumeName }} mountPath: /persistentvolumes env: - name: PROVISIONER_NAME @@ -64,7 +62,7 @@ spec: {{ toYaml . | indent 12 }} {{- end }} volumes: - - name: nfs-subdir-external-provisioner-root + - name: {{ .Values.nfs.volumeName }} {{- if .Values.buildMode }} emptyDir: {} {{- else if .Values.nfs.mountOptions }} diff --git a/charts/nfs-subdir-external-provisioner/templates/persistentvolume.yaml b/charts/nfs-subdir-external-provisioner/templates/persistentvolume.yaml index 6dc31bc..88eb04d 100644 --- a/charts/nfs-subdir-external-provisioner/templates/persistentvolume.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/persistentvolume.yaml @@ -4,6 +4,7 @@ kind: PersistentVolume metadata: name: pv-{{ template "nfs-subdir-external-provisioner.fullname" . }} labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} nfs-subdir-external-provisioner: {{ template "nfs-subdir-external-provisioner.fullname" . }} spec: capacity: diff --git a/charts/nfs-subdir-external-provisioner/templates/persistentvolumeclaim.yaml b/charts/nfs-subdir-external-provisioner/templates/persistentvolumeclaim.yaml index 29d8544..993dc53 100644 --- a/charts/nfs-subdir-external-provisioner/templates/persistentvolumeclaim.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/persistentvolumeclaim.yaml @@ -3,6 +3,8 @@ kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pvc-{{ template "nfs-subdir-external-provisioner.fullname" . }} + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} spec: accessModes: - {{ .Values.storageClass.accessModes }} diff --git a/charts/nfs-subdir-external-provisioner/templates/podsecuritypolicy.yaml b/charts/nfs-subdir-external-provisioner/templates/podsecuritypolicy.yaml index ff07ee7..540492b 100644 --- a/charts/nfs-subdir-external-provisioner/templates/podsecuritypolicy.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/podsecuritypolicy.yaml @@ -4,10 +4,7 @@ kind: PodSecurityPolicy metadata: name: {{ template "nfs-subdir-external-provisioner.fullname" . }} labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} spec: privileged: false allowPrivilegeEscalation: false diff --git a/charts/nfs-subdir-external-provisioner/templates/role.yaml b/charts/nfs-subdir-external-provisioner/templates/role.yaml index 7953efe..9d17581 100644 --- a/charts/nfs-subdir-external-provisioner/templates/role.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/role.yaml @@ -3,10 +3,7 @@ kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ template "nfs-subdir-external-provisioner.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} rules: - apiGroups: [""] diff --git a/charts/nfs-subdir-external-provisioner/templates/rolebinding.yaml b/charts/nfs-subdir-external-provisioner/templates/rolebinding.yaml index 1203bba..6bba960 100644 --- a/charts/nfs-subdir-external-provisioner/templates/rolebinding.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/rolebinding.yaml @@ -3,10 +3,7 @@ kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ template "nfs-subdir-external-provisioner.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} subjects: - kind: ServiceAccount diff --git a/charts/nfs-subdir-external-provisioner/templates/serviceaccount.yaml b/charts/nfs-subdir-external-provisioner/templates/serviceaccount.yaml index 5fc184d..a68ff9e 100644 --- a/charts/nfs-subdir-external-provisioner/templates/serviceaccount.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/serviceaccount.yaml @@ -3,9 +3,10 @@ apiVersion: v1 kind: ServiceAccount metadata: labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ template "nfs-subdir-external-provisioner.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} name: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} {{- end -}} diff --git a/charts/nfs-subdir-external-provisioner/templates/storageclass.yaml b/charts/nfs-subdir-external-provisioner/templates/storageclass.yaml index 80122dd..698d32b 100644 --- a/charts/nfs-subdir-external-provisioner/templates/storageclass.yaml +++ b/charts/nfs-subdir-external-provisioner/templates/storageclass.yaml @@ -3,15 +3,15 @@ apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: labels: - app: {{ template "nfs-subdir-external-provisioner.name" . }} - chart: {{ template "nfs-subdir-external-provisioner.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} name: {{ .Values.storageClass.name }} -{{- if .Values.storageClass.defaultClass }} annotations: + {{- if .Values.storageClass.defaultClass }} storageclass.kubernetes.io/is-default-class: "true" -{{- end }} + {{- end }} + {{- with .Values.storageClass.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} provisioner: {{ template "nfs-subdir-external-provisioner.provisionerName" . }} allowVolumeExpansion: {{ .Values.storageClass.allowVolumeExpansion }} reclaimPolicy: {{ .Values.storageClass.reclaimPolicy }} diff --git a/charts/nfs-subdir-external-provisioner/values.yaml b/charts/nfs-subdir-external-provisioner/values.yaml index 02eda6e..0a4f03d 100644 --- a/charts/nfs-subdir-external-provisioner/values.yaml +++ b/charts/nfs-subdir-external-provisioner/values.yaml @@ -2,14 +2,16 @@ replicaCount: 1 strategyType: Recreate image: - repository: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner + repository: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner tag: v4.0.2 pullPolicy: IfNotPresent +imagePullSecrets: [] nfs: server: path: /nfs-storage mountOptions: + volumeName: nfs-subdir-external-provisioner-root # For creating the StorageClass automatically: storageClass: @@ -47,6 +49,9 @@ storageClass: # Set access mode - ReadWriteOnce, ReadOnlyMany or ReadWriteMany accessModes: ReadWriteOnce + # Storage class annotations + annotations: {} + leaderElection: # When set to false leader election will be disabled enabled: true @@ -61,6 +66,9 @@ rbac: podSecurityPolicy: enabled: false +# Deployment pod annotations +podAnnotations: {} + ## Set pod priorityClassName # priorityClassName: "" @@ -68,6 +76,9 @@ serviceAccount: # Specifies whether a ServiceAccount should be created create: true + # Annotations to add to the service account + annotations: {} + # The name of the ServiceAccount to use. # If not set and create is true, a name is generated using the fullname template name: @@ -85,3 +96,6 @@ nodeSelector: {} tolerations: [] affinity: {} + +# Additional labels for any resource created +labels: {} diff --git a/deploy/deployment.yaml b/deploy/deployment.yaml index 1b45fe2..26d2a23 100644 --- a/deploy/deployment.yaml +++ b/deploy/deployment.yaml @@ -21,7 +21,7 @@ spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner - image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.2 + image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes diff --git a/deploy/objects/clusterrole.yaml b/deploy/objects/clusterrole.yaml index d8564a7..1b5c2ef 100644 --- a/deploy/objects/clusterrole.yaml +++ b/deploy/objects/clusterrole.yaml @@ -3,6 +3,9 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] diff --git a/deploy/objects/deployment.yaml b/deploy/objects/deployment.yaml index b45e71d..df10aa3 100644 --- a/deploy/objects/deployment.yaml +++ b/deploy/objects/deployment.yaml @@ -14,7 +14,7 @@ spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner - image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.2 + image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes diff --git a/deploy/rbac.yaml b/deploy/rbac.yaml index 85a76d0..28dbb68 100644 --- a/deploy/rbac.yaml +++ b/deploy/rbac.yaml @@ -10,6 +10,9 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"]