diff --git a/charts/ceph-csi-rbd/README.md b/charts/ceph-csi-rbd/README.md index c048a6d73..117facbe7 100644 --- a/charts/ceph-csi-rbd/README.md +++ b/charts/ceph-csi-rbd/README.md @@ -151,6 +151,7 @@ charts and their default values. | `storageClass.pool` | Ceph pool into which the RBD image shall be created | `replicapool` | | `storageClass.thickProvision` | Specifies whether thick provision should be enabled | `false` | | `storageclass.imageFeatures` | Specifies RBD image features | `layering` | +| `storageclass.tryOtherMounters` | Specifies whether to try other mounters in case if the current mounter fails to mount the rbd image for any reason | `false` | | `storageClass.mounter` | Specifies RBD mounter | `""` | | `storageClass.cephLogDir` | ceph client log location, it is the target bindmount path used inside container | `"/var/log/ceph"` | | `storageClass.cephLogStrategy` | ceph client log strategy, available options `remove` or `compress` or `preserve` | `"remove"` | diff --git a/charts/ceph-csi-rbd/templates/storageclass.yaml b/charts/ceph-csi-rbd/templates/storageclass.yaml index caba90305..e4da5166f 100644 --- a/charts/ceph-csi-rbd/templates/storageclass.yaml +++ b/charts/ceph-csi-rbd/templates/storageclass.yaml @@ -19,6 +19,9 @@ parameters: pool: {{ .Values.storageClass.pool }} imageFeatures: {{ .Values.storageClass.imageFeatures }} thickProvision: {{ .Values.storageClass.thickProvision | quote}} +{{- if .Values.storageClass.tryOtherMounters }} + tryOtherMounters: {{ .Values.storageClass.tryOtherMounters | quote}} +{{- end }} {{- if .Values.storageClass.mounter }} mounter: {{ .Values.storageClass.mounter }} {{- end }} diff --git a/charts/ceph-csi-rbd/values.yaml b/charts/ceph-csi-rbd/values.yaml index d0ae4f92e..2bf97d554 100644 --- a/charts/ceph-csi-rbd/values.yaml +++ b/charts/ceph-csi-rbd/values.yaml @@ -289,6 +289,15 @@ storageClass: # imageFeatures: layering,journaling,exclusive-lock imageFeatures: layering + # (optional) Specifies whether to try other mounters in case if the current + # mounter fails to mount the rbd image for any reason. True means fallback + # to next mounter, default is set to false. + # Note: tryOtherMounters is currently useful to fallback from krbd to rbd-nbd + # in case if any of the specified imageFeatures is not supported by krbd + # driver on node scheduled for application pod launch, but in the future this + # should work with any mounter type. + # tryOtherMounters: false + # (optional) uncomment the following to use rbd-nbd as mounter # on supported nodes # mounter: rbd-nbd diff --git a/docs/deploy-rbd.md b/docs/deploy-rbd.md index f8fa2dea1..2dd798c1e 100644 --- a/docs/deploy-rbd.md +++ b/docs/deploy-rbd.md @@ -56,7 +56,7 @@ make image-cephcsi | `volumeNamePrefix` | no | Prefix to use for naming RBD images (defaults to `csi-vol-`). | | `snapshotNamePrefix` | no | Prefix to use for naming RBD snapshot images (defaults to `csi-snap-`). | | `imageFeatures` | yes | RBD image features. CSI RBD currently supports `layering`, `journaling`, `exclusive-lock` features. If `journaling` is enabled, must enable `exclusive-lock` too. See [man pages](http://docs.ceph.com/docs/master/man/8/rbd/#cmdoption-rbd-image-feature) Note that the required support for [object-map and fast-diff were added in 5.3 and journaling does not have KRBD support yet](https://docs.ceph.com/en/latest/rbd/rbd-config-ref/#image-features). deep-flatten is added for cloned images. | -| | +| `tryOtherMounters` | no | Specifies whether to try other mounters in case if the current mounter fails to mount the rbd image for any reason | | `mapOptions` | no | Map options to use when mapping rbd image. See [krbd](https://docs.ceph.com/docs/master/man/8/rbd/#kernel-rbd-krbd-options) and [nbd](https://docs.ceph.com/docs/master/man/8/rbd-nbd/#options) options. | | `unmapOptions` | no | Unmap options to use when unmapping rbd image. See [krbd](https://docs.ceph.com/docs/master/man/8/rbd/#kernel-rbd-krbd-options) and [nbd](https://docs.ceph.com/docs/master/man/8/rbd-nbd/#options) options. | | `csi.storage.k8s.io/provisioner-secret-name`, `csi.storage.k8s.io/node-stage-secret-name` | yes (for Kubernetes) | name of the Kubernetes Secret object containing Ceph client credentials. Both parameters should have the same value | diff --git a/examples/rbd/storageclass.yaml b/examples/rbd/storageclass.yaml index a53aace7c..baba539b2 100644 --- a/examples/rbd/storageclass.yaml +++ b/examples/rbd/storageclass.yaml @@ -39,6 +39,15 @@ parameters: # imageFeatures: layering,journaling,exclusive-lock imageFeatures: layering + # (optional) Specifies whether to try other mounters in case if the current + # mounter fails to mount the rbd image for any reason. True means fallback + # to next mounter, default is set to false. + # Note: tryOtherMounters is currently useful to fallback from krbd to rbd-nbd + # in case if any of the specified imageFeatures is not supported by krbd + # driver on node scheduled for application pod launch, but in the future this + # should work with any mounter type. + # tryOtherMounters: false + # (optional) mapOptions is a comma-separated list of map options. # For krbd options refer # https://docs.ceph.com/docs/master/man/8/rbd/#kernel-rbd-krbd-options diff --git a/internal/rbd/nodeserver.go b/internal/rbd/nodeserver.go index ea0c2634c..b14a381b9 100644 --- a/internal/rbd/nodeserver.go +++ b/internal/rbd/nodeserver.go @@ -68,8 +68,9 @@ const ( xfsReflinkNoSupport xfsReflinkSupport - staticVol = "staticVolume" - volHealerCtx = "volumeHealerContext" + staticVol = "staticVolume" + volHealerCtx = "volumeHealerContext" + tryOtherMounters = "tryOtherMounters" ) var ( @@ -218,6 +219,11 @@ func populateRbdVol( krbdSupported := false if req.GetVolumeContext()["mounter"] != rbdNbdMounter { krbdSupported = isKrbdFeatureSupported(ctx, req.GetVolumeContext()["imageFeatures"]) + if !krbdSupported && !parseBoolOption(ctx, req.GetVolumeContext(), tryOtherMounters, false) { + log.ErrorLog(ctx, "unsupported krbd Feature, set `tryOtherMounters:true` or fix krbd driver") + + return nil, status.Errorf(codes.Internal, "unsupported krbd Feature") + } } if krbdSupported { rv.MapOptions = req.GetVolumeContext()["mapOptions"]