diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 36b92f8c..ad8330a4 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -16,6 +16,8 @@ - [CSINode Object](csi-node-object.md) - [Features](features.md) - [Secrets & Credentials](secrets-and-credentials.md) + - [StorageClass Secrets](secrets-and-credentials-storage-class.md) + - [VolumeSnapshotClass Secrets](secrets-and-credentials-volume-snapshot-class.md) - [Topology](topology.md) - [Raw Block Volume](raw-block.md) - [Skip Attach](skip-attach.md) diff --git a/book/src/secrets-and-credentials-storage-class.md b/book/src/secrets-and-credentials-storage-class.md new file mode 100644 index 00000000..7212aa79 --- /dev/null +++ b/book/src/secrets-and-credentials-storage-class.md @@ -0,0 +1,256 @@ +# StorageClass Secrets + +The CSI [external-provisioner](external-provisioner.md) sidecar container facilitates the handling of secrets for the following operations: +* `CreateVolumeRequest` +* `DeleteVolumeRequest` +* `ControllerPublishVolumeRequest` +* `ControllerUnpublishVolumeRequest` +* `ControllerExpandVolumeRequest` +* `NodeStageVolumeRequest` +* `NodePublishVolumeRequest` + +CSI `external-provisioner` v1.0.1+ supports the following keys in `StorageClass.parameters`: + +* `csi.storage.k8s.io/provisioner-secret-name` +* `csi.storage.k8s.io/provisioner-secret-namespace` +* `csi.storage.k8s.io/controller-publish-secret-name` +* `csi.storage.k8s.io/controller-publish-secret-namespace` +* `csi.storage.k8s.io/node-stage-secret-name` +* `csi.storage.k8s.io/node-stage-secret-namespace` +* `csi.storage.k8s.io/node-publish-secret-name` +* `csi.storage.k8s.io/node-publish-secret-namespace` + +CSI `external-provisioner` v1.2.0+ adds support for the following keys in `StorageClass.parameters`: +* `csi.storage.k8s.io/controller-expand-secret-name` +* `csi.storage.k8s.io/controller-expand-secret-namespace` + +Cluster admins can populate the secret fields for the operations listed above with data from Kubernetes `Secret` objects by specifying these keys in the `StorageClass` object. + +## Examples + +### Basic Provisioning Secret + +In this example, the external-provisioner will fetch Kubernetes `Secret` object `fast-storage-provision-key` in the namespace `pd-ssd-credentials` and pass the credentials to the CSI driver named `csi-driver.team.example.com` in the `CreateVolume` CSI call. + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fast-storage +provisioner: csi-driver.team.example.com +parameters: + type: pd-ssd + csi.storage.k8s.io/provisioner-secret-name: fast-storage-provision-key + csi.storage.k8s.io/provisioner-secret-namespace: pd-ssd-credentials +``` + +All volumes provisioned using this `StorageClass` use the same secret. + +### Per Volume Secrets +In this example, the external-provisioner will generate the name of the Kubernetes `Secret` object and namespace for the `NodePublishVolume` CSI call, based on the PVC namespace and annotations, at volume provision time. + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fast-storage +provisioner: csi-driver.team.example.com +parameters: + type: pd-ssd + csi.storage.k8s.io/node-publish-secret-name: ${pvc.annotations['team.example.com/key']} + csi.storage.k8s.io/node-publish-secret-namespace: ${pvc.namespace} +``` + +This StorageClass will result in the creation of a `PersistentVolume` API object referencing a "node publish secret" in the same namespace as the `PersistentVolumeClaim` that triggered the provisioning and with a name specified as an annotation on the `PersistentVolumeClaim`. This could be used to give the creator of the `PersistentVolumeClaim` the ability to specify a secret containing a decryption key they have control over. + +### Multiple Operation Secrets +A drivers may support secret keys for multiple operations. In this case, you can provide secrets references for each operation: + +```yaml +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: fast-storage-all +provisioner: csi-driver.team.example.com +parameters: + type: pd-ssd + csi.storage.k8s.io/provisioner-secret-name: ${pvc.name} + csi.storage.k8s.io/provisioner-secret-namespace: ${pvc.namespace}-fast-storage + csi.storage.k8s.io/node-publish-secret-name: ${pvc.name}-${pvc.annotations['team.example.com/key']} + csi.storage.k8s.io/node-publish-secret-namespace: ${pvc.namespace}-fast-storage + +``` + +## Operations +Details for each secret supported by the external-provisioner can be found below. + +### Create/Delete Volume Secret + +The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`. + +* `csi.storage.k8s.io/provisioner-secret-name` +* `csi.storage.k8s.io/provisioner-secret-namespace` + +The values of both of these parameters, together, refer to the name and namespace of a `Secret` object in the Kubernetes API. + +If specified, the CSI `external-provisioner` will attempt to fetch the secret before provisioning and deletion. + +If the secret is retrieved successfully, the provisioner passes it to the CSI driver in the `CreateVolumeRequest.secrets` or `DeleteVolumeRequest.secrets` field. + +If no such secret exists in the Kubernetes API, or the provisioner is unable to fetch it, the provision operation will fail. + +Note, however, that the delete operation will continue even if the secret is not found (because, for example, the entire namespace containing the secret was deleted). In this case, if the driver requires a secret for deletion, then the volume and PV may need to be manually cleaned up. + +The values of these parameters may be "templates". The `external-provisioner` will automatically resolve templates at volume provision time, as detailed below: + +* `csi.storage.k8s.io/provisioner-secret-name` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + * Support added in CSI `external-provisioner` v1.2.0+ + * `${pvc.name}` + * Replaced with the name of the `PersistentVolumeClaim` object that triggered provisioning. + * Support added in CSI `external-provisioner` v1.2.0+ +* `csi.storage.k8s.io/provisioner-secret-namespace` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + +### Controller Publish/Unpublish Secret + +The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`: + +* `csi.storage.k8s.io/controller-publish-secret-name` +* `csi.storage.k8s.io/controller-publish-secret-namespace` + +The values of both of these parameters, together, refer to the name and namespace of a `Secret` object in the Kubernetes API. + +If specified, the CSI `external-provisioner` sets the `CSIPersistentVolumeSource.ControllerPublishSecretRef` field in the new `PersistentVolume` object to refer to this secret once provisioning is successful. + +The CSI `external-attacher` then attempts to fetch the secret referenced by the `CSIPersistentVolumeSource.ControllerPublishSecretRef`, if specified, before an attach or detach operation. + +If no such secret exists in the Kubernetes API, or the `external-attacher` is unable to fetch it, the attach or detach operation fails. + +If the secret is retrieved successfully, the `external-attacher` passes it to the CSI driver in the `ControllerPublishVolumeRequest.secrets` or `ControllerUnpublishVolumeRequest.secrets` field. + +The values of these parameters may be "templates". The `external-provisioner` will automatically resolve templates at volume provision time, as detailed below: + +* `csi.storage.k8s.io/controller-publish-secret-name` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.name}` + * Replaced with the name of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.annotations['']}` (e.g. `${pvc.annotations['example.com/key']}`) + * Replaced with the value of the specified annotation from the `PersistentVolumeClaim` object that triggered provisioning +* `csi.storage.k8s.io/controller-publish-secret-namespace` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + + +### Node Stage Secret + +The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`: + +* `csi.storage.k8s.io/node-stage-secret-name` +* `csi.storage.k8s.io/node-stage-secret-namespace` + +The value of both parameters, together, refer to the name and namespace of the `Secret` object in the Kubernetes API. + +If specified, the CSI `external-provisioner` sets the `CSIPersistentVolumeSource.NodeStageSecretRef` field in the new `PersistentVolume` object to refer to this secret once provisioning is successful. + +The Kubernetes kubelet then attempts to fetch the secret referenced by the `CSIPersistentVolumeSource.NodeStageSecretRef` field, if specified, before a mount device operation. + +If no such secret exists in the Kubernetes API, or the kubelet is unable to fetch it, the mount device operation fails. + +If the secret is retrieved successfully, the kubelet passes it to the CSI driver in the `NodeStageVolumeRequest.secrets` field. + +The values of these parameters may be "templates". The `external-provisioner` will automatically resolve templates at volume provision time, as detailed below: + +* `csi.storage.k8s.io/node-stage-secret-name` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.name}` + * Replaced with the name of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.annotations['']}` (e.g. `${pvc.annotations['example.com/key']}`) + * Replaced with the value of the specified annotation from the `PersistentVolumeClaim` object that triggered provisioning +* `csi.storage.k8s.io/node-stage-secret-namespace` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + +### Node Publish Secret + +The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`: + +* `csi.storage.k8s.io/node-publish-secret-name` +* `csi.storage.k8s.io/node-publish-secret-namespace` + +The value of both parameters, together, refer to the name and namespace of the `Secret` object in the Kubernetes API. + +If specified, the CSI `external-provisioner` sets the `CSIPersistentVolumeSource.NodePublishSecretRef` field in the new `PersistentVolume` object to refer to this secret once provisioning is successful. + +The Kubernetes kubelet, attempts to fetch the secret referenced by the `CSIPersistentVolumeSource.NodePublishSecretRef` field, if specified, before a mount operation. + +If no such secret exists in the Kubernetes API, or the kubelet is unable to fetch it, the mount operation fails. + +If the secret is retrieved successfully, the kubelet passes it to the CSI driver in the `NodePublishVolumeRequest.secrets` field. + +The values of these parameters may be "templates". The `external-provisioner` will automatically resolve templates at volume provision time, as detailed below: + +* `csi.storage.k8s.io/node-publish-secret-name` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.name}` + * Replaced with the name of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.annotations['']}` (e.g. `${pvc.annotations['example.com/key']}`) + * Replaced with the value of the specified annotation from the `PersistentVolumeClaim` object that triggered provisioning +* `csi.storage.k8s.io/node-publish-secret-namespace` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + +### Controller Expand (Volume Resize) Secret + +The CSI `external-provisioner` (v1.2.0+) looks for the following keys in `StorageClass.parameters`: + +* `csi.storage.k8s.io/controller-expand-secret-name` +* `csi.storage.k8s.io/controller-expand-secret-namespace` + +The value of both parameters, together, refer to the name and namespace of the `Secret` object in the Kubernetes API. + +If specified, the CSI `external-provisioner` sets the `CSIPersistentVolumeSource.ControllerExpandSecretRef` field in the new `PersistentVolume` object to refer to this secret once provisioning is successful. + +The `external-resizer` (v0.2.0+), attempts to fetch the secret referenced by the `CSIPersistentVolumeSource.ControllerExpandSecretRef` field, if specified, before starting a volume resize (expand) operation. + +If no such secret exists in the Kubernetes API, or the `external-resizer` is unable to fetch it, the resize (expand) operation fails. + +If the secret is retrieved successfully, the `external-resizer` passes it to the CSI driver in the `ControllerExpandVolumeRequest.secrets` field. + +The values of these parameters may be "templates". The `external-provisioner` will automatically resolve templates at volume provision time, as detailed below: + +* `csi.storage.k8s.io/controller-expand-secret-name` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.name}` + * Replaced with the name of the `PersistentVolumeClaim` object that triggered provisioning. + * `${pvc.annotations['']}` (e.g. `${pvc.annotations['example.com/key']}`) + * Replaced with the value of the specified annotation from the `PersistentVolumeClaim` object that triggered provisioning +* `csi.storage.k8s.io/controller-expand-secret-namespace` + * `${pv.name}` + * Replaced with name of the `PersistentVolume` object being provisioned. + * `${pvc.namespace}` + * Replaced with namespace of the `PersistentVolumeClaim` object that triggered provisioning. diff --git a/book/src/secrets-and-credentials-volume-snapshot-class.md b/book/src/secrets-and-credentials-volume-snapshot-class.md new file mode 100644 index 00000000..1aedc274 --- /dev/null +++ b/book/src/secrets-and-credentials-volume-snapshot-class.md @@ -0,0 +1,47 @@ +# VolumeSnapshotClass Secrets + +The CSI [external-snapshotter](external-snapshotter.md) sidecar container facilitates the handling of secrets for the following operations: +* `CreateSnapshotRequest` +* `DeleteSnapshotRequest` + +CSI `external-snapshotter` v1.0.1+ supports the following keys in `VolumeSnapshotClass.parameters`: + +* `csi.storage.k8s.io/snapshotter-secret-name` +* `csi.storage.k8s.io/snapshotter-secret-namespace` + +Cluster admins can populate the secret fields for the operations listed above with data from Kubernetes `Secret` objects by specifying these keys in the `VolumeSnapshotClass` object. + +## Operations +Details for each secret supported by the external-snapshotter can be found below. + +### Create/Delete VolumeSnapshot Secret + +CSI `external-snapshotter` v1.0.1+ looks for the following keys in `VolumeSnapshotClass.parameters`: + +* `csi.storage.k8s.io/snapshotter-secret-name` +* `csi.storage.k8s.io/snapshotter-secret-namespace` + +The values of both of these parameters, together, refer to the name and namespace of a `Secret` object in the Kubernetes API. + +If specified, the CSI `external-snapshotter` will attempt to fetch the secret before creation and deletion. + +If the secret is retrieved successfully, the snapshotter passes it to the CSI driver in the `CreateSnapshotRequest.secrets` or `DeleteSnapshotRequest.secrets` field. + +If no such secret exists in the Kubernetes API, or the snapshotter is unable to fetch it, the create operation will fail. + +Note, however, that the delete operation will continue even if the secret is not found (because, for example, the entire namespace containing the secret was deleted). In this case, if the driver requires a secret for deletion, then the volume and PV may need to be manually cleaned up. + +The values of these parameters may be "templates". The `external-snapshotter` will automatically resolve templates at snapshot create time, as detailed below: + +* `csi.storage.k8s.io/snapshotter-secret-name` + * `${volumesnapshotcontent.name}` + * Replaced with name of the `VolumeSnapshotContent` object being created. + * `${volumesnapshot.namespace}` + * Replaced with namespace of the `VolumeSnapshot` object that triggered creation. + * `${volumesnapshot.name}` + * Replaced with the name of the `VolumeSnapshot` object that triggered creation. +* `csi.storage.k8s.io/snapshotter-secret-namespace` + * `${volumesnapshotcontent.name}` + * Replaced with name of the `VolumeSnapshotContent` object being created. + * `${volumesnapshot.namespace}` + * Replaced with namespace of the `VolumeSnapshot` object that triggered creation. diff --git a/book/src/secrets-and-credentials.md b/book/src/secrets-and-credentials.md index db6ca717..ba7735b3 100644 --- a/book/src/secrets-and-credentials.md +++ b/book/src/secrets-and-credentials.md @@ -1,39 +1,20 @@ # Secrets and Credentials +Some drivers may require a secret in order to complete operations. + ## CSI Driver Secrets -Some drivers may require a secret in order to issue operations against a backend (a service account, for example). -If this secret is required at the "per driver" granularity (and not different "per CSI operation" or "per volume"), the secret may be injected in to CSI driver pods via [standard Kubernetes secret distribution mechanisms](https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/). +If a CSI Driver requires secrets for a backend (a service account, for example), and this secret is required at the "per driver" granularity (not different "per CSI operation" or "per volume"), then the secret SHOULD be injected directly in to CSI driver pods via [standard Kubernetes secret distribution mechanisms](https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/) during deployment. ## CSI Operation Secrets -The CSI spec also accepts secrets in each of the following protos: - -* `CreateVolumeRequest` -* `DeleteVolumeRequest` -* `ControllerPublishVolumeRequest` -* `ControllerUnpublishVolumeRequest` -* `CreateSnapshotRequest` -* `DeleteSnapshotRequest` -* `ControllerExpandVolumeRequest` -* `NodeStageVolumeRequest` -* `NodePublishVolumeRequest` +If a CSI Driver requires secrets "per CSI operation" or "per volume" or "per storage pool", the CSI spec allows secrets to be passed in for various CSI operations (including `CreateVolumeRequest`, `ControllerPublishVolumeRequest`, and more). -These enable CSI drivers to accept/require "per CSI operation" or "per volume" secrets (a volume encryption key, for example). +Cluster admins can populate such secrets by creating Kubernetes `Secret` objects and specifying the keys in the `StorageClass` or `SnapshotClass` objects. -The CSI [external-provisioner](external-provisioner.md) enables Kubernetes cluster admins to populate the secret fields for these protos with data from Kubernetes `Secret` objects. For example: - -```yaml -kind: StorageClass -apiVersion: storage.k8s.io/v1 -metadata: - name: fast-storage -provisioner: csi-driver.team.example.com -parameters: - type: pd-ssd - csi.storage.k8s.io/provisioner-secret-name: fast-storage-provision-key - csi.storage.k8s.io/provisioner-secret-namespace: pd-ssd-credentials -``` +The CSI sidecar containers facilitate the handling of secrets between Kubernetes and the CSI Driver. For more details see: +* [StorageClass Secrets](secrets-and-credentials-storage-class.md) +* [VolumeSnapshotClass Secrets](secrets-and-credentials-volume-snapshot-class.md) ### Secret RBAC Rules @@ -43,169 +24,6 @@ Please add or update RBAC rules if secret is expected to use. To set proper secret permission, uncomment related lines defined in `rbac.yaml` (e.g. [external-provisioner/deploy/kubernetes/rbac.yaml](https://github.com/kubernetes-csi/external-provisioner/blob/22bb6401d2484ee3ca18a23d75c3864c774e5f32/deploy/kubernetes/rbac.yaml#L24)) -### Create/Delete Volume Secret - -The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`: - -* `csi.storage.k8s.io/provisioner-secret-name` -* `csi.storage.k8s.io/provisioner-secret-namespace` - -The value of both parameters refers to the name and namespace of the `Secret` object in the Kubernetes API. - -The value of both parameters may be a literal or a template containing the following variable that are automatically replaced by the `external-provisioner` at provision time: - - * `${pv.name}` - * Automatically replaced with the name of the `PersistentVolume` object being provisioned at provision. - * `${pvc.namespace}` - * Automatically replaced with the namespace of the `PersistentVolumeClaim` object being provisione - -The value of `csi.storage.k8s.io/provisioner-secret-name` also supports the following template variables which are automatically replaced by the `external-provisioner` at provision time: - - * `${pvc.name}` - * Automatically replaced with the name of the `PersistentVolumeClaim` object being provisioned. - -If specified, the CSI `external-provisioner` will attempt to fetch the secret before provisioning and deletion. - -If the entire namespace was deleted, including the secret needed for deletion, then no secret will be passed to the delete call. - -If no such secret exists in the Kubernetes API, or the provisioner is unable to fetch it, the provision operation will fail. The delete operation will continue if the secret is not found. If this happens when the driver requires a secret for deletion, then the volume and PV may need to be manually cleaned up. - -If the secret is retrieved successfully, the provisioner passes it to the CSI driver in the `CreateVolumeRequest.secrets` or `DeleteVolumeRequest.secrets` field. - -### Controller Publish/Unpublish Secret - -The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`: - -* `csi.storage.k8s.io/controller-publish-secret-name` -* `csi.storage.k8s.io/controller-publish-secret-namespace` - -The value of both parameters refers to the name and namespace of the `Secret` object in the Kubernetes API. - -The value of both parameters may be a literal or a template containing the following variables that are automatically replaced by the `external-provisioner` at provision time: - - * `${pv.name}` - * Automatically replaced with the name of the `PersistentVolume` object being provisioned. - * `${pvc.namespace}` - * Automatically replaced with the namespace of the `PersistentVolumeClaim` object being provisioned. - -The value of `csi.storage.k8s.io/controller-publish-secret-name` also supports the following template variables which are automatically replaced by the `external-provisioner` at provision time: - - * `${pvc.name}` - * Automatically replaced with the name of the `PersistentVolumeClaim` object being provisioned. - * `${pvc.annotations['']}` (e.g. `${pvc.annotations['example.com/key']}`) - * Automatically replaced with the value of the specified annotation from the `PersistentVolumeClaim` object being provisioned. - -If specified, once provisioning is successful, the CSI `external-provisioner` sets the `CSIPersistentVolumeSource.ControllerPublishSecretRef` field in the new `PersistentVolume` object to refer to this secret. - -If specified, the CSI `external-attacher` attempts to fetch the secret referenced by the `CSIPersistentVolumeSource.ControllerPublishSecretRef` before an attach or detach operation. - -If no such secret exists in the Kubernetes API, or the `external-attacher` is unable to fetch it, the attach or detach operation fails. - -If the secret is retrieved successfully, the `external-attacher` passes it to the CSI driver in the `ControllerPublishVolumeRequest.secrets` or `ControllerUnpublishVolumeRequest.secrets` field. - -### Node Stage Secret - -The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`: - -* `csi.storage.k8s.io/node-stage-secret-name` -* `csi.storage.k8s.io/node-stage-secret-namespace` - -The value of both parameters refers to the name and namespace of the `Secret` object in the Kubernetes API. - -The value of both parameters may be a literal or a template containing the following variables that are automatically replaced by the `external-provisioner` at provision time: - - * `${pv.name}` - * Automatically replaced with the name of the `PersistentVolume` object being provisioned. - * `${pvc.namespace}` - * Automatically replaced with the namespace of the `PersistentVolumeClaim` object being provisioned. - -The value of `csi.storage.k8s.io/node-stage-secret-namespace` also supports the following template variables which are automatically replaced by the `external-provisioner` at provision time: - - * `${pvc.name}` - * Automatically replaced with the name of the `PersistentVolumeClaim` object being provisioned. - * `${pvc.annotations['']}` (e.g. `${pvc.annotations['example.com/key']}`) - * Automatically replaced with the value of the specified annotation from the `PersistentVolumeClaim` object being provisioned. - -If specified, once provisioning is successful, the CSI `external-provisioner` sets the `CSIPersistentVolumeSource.NodeStageSecretRef` field in the new `PersistentVolume` object to refer to this secret. - -If specified, the Kubernetes kubelet, attempts to fetch the secret referenced by the `CSIPersistentVolumeSource.NodeStageSecretRef` field before a mount device operation. - -If no such secret exists in the Kubernetes API, or the kubelet is unable to fetch it, the mount device operation fails. - -If the secret is retrieved successfully, the kubelet passes it to the CSI driver in the `NodeStageVolumeRequest.secrets` field. - -### Node Publish Secret - -The CSI `external-provisioner` (v1.0.1+) looks for the following keys in `StorageClass.parameters`: - -* `csi.storage.k8s.io/node-publish-secret-name` -* `csi.storage.k8s.io/node-publish-secret-namespace` - -The value of both parameters refers to the name and namespace of the `Secret` object in the Kubernetes API. - -The value of both parameters may be a literal or a template containing the following variables that are automatically replaced by the `external-provisioner` at provision time: - - * `${pv.name}` - * Automatically replaced with the name of the `PersistentVolume` object being provisioned. - * `${pvc.namespace}` - * Automatically replaced with the namespace of the `PersistentVolumeClaim` object being provisioned. - -The value of `csi.storage.k8s.io/node-publish-secret-name` also supports the following template variables which are automatically replaced by the `external-provisioner` at provision time: - - * `${pvc.name}` - * Automatically replaced with the name of the `PersistentVolumeClaim` object being provisioned. - * `${pvc.annotations['']}` (e.g. `${pvc.annotations['example.com/key']}`) - * Automatically replaced with the value of the specified annotation from the `PersistentVolumeClaim` object being provisioned. - -If specified, once provisioning is successful, the CSI `external-provisioner` sets the `CSIPersistentVolumeSource.NodePublishSecretRef` field in the new `PersistentVolume` object to refer to this secret. - -If specified, the Kubernetes kubelet, attempts to fetch the secret referenced by the `CSIPersistentVolumeSource.NodePublishSecretRef` field before a mount operation. - -If no such secret exists in the Kubernetes API, or the kubelet is unable to fetch it, the mount operation fails. - -If the secret is retrieved successfully, the kubelet passes it to the CSI driver in the `NodePublishVolumeRequest.secrets` field. - -## Example Storage Classes - -The following storage classes supply secrets to a sample CSI driver named `csi-driver.team.example.com`. - -### Multiple operations support secret keys -A drivers may support secret keys for multiple operations. In this case, you can provide secrets references for each operation: - -```yaml -kind: StorageClass -apiVersion: storage.k8s.io/v1 -metadata: - name: fast-storage-all -provisioner: csi-driver.team.example.com -parameters: - type: pd-ssd - csi.storage.k8s.io/provisioner-secret-name: ${pvc.name} - csi.storage.k8s.io/provisioner-secret-namespace: ${pvc.namespace}-fast-storage - csi.storage.k8s.io/node-publish-secret-name: ${pvc.name}-${pvc.annotations['team.example.com/key']} - csi.storage.k8s.io/node-publish-secret-namespace: ${pvc.namespace}-fast-storage - -``` - -### Only NodePublish supports secret keys -Some drivers may only support secret keys for a certain operation: - -```yaml -kind: StorageClass -apiVersion: storage.k8s.io/v1 -metadata: - name: fast-storage -provisioner: csi-driver.team.example.com -parameters: - type: pd-ssd - csi.storage.k8s.io/node-publish-secret-name: ${pvc.annotations['team.example.com/key']} - csi.storage.k8s.io/node-publish-secret-namespace: ${pvc.namespace} -``` - -This StorageClass instructs the CSI provisioner to do the following: -* Create a `PersistentVolume` with: - * a "node publish secret" in the same namespace as the `PersistentVolumeClaim` that triggered the provisioning, with a name specified as an annotation on the `PersistentVolumeClaim`. This could be used to give the creator of the `PersistentVolumeClaim` the ability to specify a secret containing a decryption key they have control over. - ## Handling Sensitive Information CSI Drivers that accept secrets SHOULD handle this data carefully. It may contain sensitive information and MUST be treated as such (e.g. not logged).