Repository: rook/rook
Pull request #10342 (2022-05-27 05:37:00)

ceph: Add holder pod if csi host networking is disabled

<!-- Please take a look at our [Contributing](https://rook.io/docs/rook/latest/development-flow.html)
documentation before submitting a Pull Request!
Thank you for contributing to Rook! -->

**Description of your changes:**

If csi is configured not the use the hostnetworking, deploy the holder pod for executing the commands with nsenter.
The implementation is the same as multus.

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>


**Which issue is resolved by this Pull Request:**
Resolves #

**Checklist:**

- [ ] **Commit Message Formatting**: Commit titles and messages follow guidelines in the [developer guide](https://rook.io/docs/rook/latest/development-flow.html#commit-structure).
- [ ] **Skip Tests for Docs**: If this is only a documentation change, add the label `skip-ci` on the PR.
- [ ] Reviewed the developer guide on [Submitting a Pull Request](https://rook.io/docs/rook/latest/development-flow.html#submitting-a-pull-request)
- [ ] [Pending release notes](https://github.com/rook/rook/blob/master/PendingReleaseNotes.md) updated with breaking and/or notable changes for the next minor release.
- [ ] Documentation has been updated, if necessary.
- [ ] Unit tests have been added, if necessary.
- [ ] Integration tests have been added, if necessary.


Note:
```
Added DNM label as testing is still pending
```

Madhu-1: working as expected and even CI is passing. @travisn @leseb PTAL
leseb: > > Nit. Also do we need to update the CSI templates?
> 
> @leseb For which parameters? i didn't see any problem with CI tests and local testing. let me know if i missed anything.

For hostnetworking here: https://github.com/rook/rook/blob/master/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin.yaml#L25

Do we need to flip https://github.com/rook/rook/blob/master/pkg/operator/ceph/csi/csi.go#L87 to false?


leseb: > 



> > > > Nit. Also do we need to update the CSI templates?
> > > 
> > > 
> > > @leseb For which parameters? i didn't see any problem with CI tests and local testing. let me know if i missed anything.
> > 
> > 
> > For hostnetworking here: https://github.com/rook/rook/blob/master/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin.yaml#L25
> 
> As the `CSI_ENABLE_HOST_NETWORK` is already set to false in configmap/ENV cephcsi pods will use pod networking only.
> 
> > Do we need to flip https://github.com/rook/rook/blob/master/pkg/operator/ceph/csi/csi.go#L87 to false?
> 
> lets change the default later once its stable

Isn't the next Rook release sufficient to give it time to stabilize?
Madhu-1: > > 
> 
> > > > > Nit. Also do we need to update the CSI templates?
> > > > 
> > > > 
> > > > @leseb For which parameters? i didn't see any problem with CI tests and local testing. let me know if i missed anything.
> > > 
> > > 
> > > For hostnetworking here: https://github.com/rook/rook/blob/master/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin.yaml#L25
> > 
> > 
> > As the `CSI_ENABLE_HOST_NETWORK` is already set to false in configmap/ENV cephcsi pods will use pod networking only.
> > > Do we need to flip https://github.com/rook/rook/blob/master/pkg/operator/ceph/csi/csi.go#L87 to false?
> > 
> > 
> > lets change the default later once its stable
> 
> Isn't the next Rook release sufficient to give it time to stabilize?

let's backport this to 1.9 and change the default to pod network in master and make it default in 1.10 @leseb WDYT?
Rakshith-R: let's keep nfsplugin on hostnetworking by default until https://github.com/rook/rook/issues/10372 is resolved ? 
Otherwise, It would face the same troubles we faced when we didn't have holder pod design for rbd and cephfs.
Rakshith-R: cc @nixpanic 
Rakshith-R: cc @nixpanic  @BlaineEXE 
Madhu-1: > let's keep nfsplugin on hostnetworking by default until #10372 is resolved ? Otherwise, It would face the same troubles we faced when we didn't have holder pod design for rbd and cephfs.

Yes, this PR is not touching the NFS driver. I created issue #10372 to track pod networking for NFS
mergify[bot]: This pull request has merge conflicts that must be resolved before it can be merged. @Madhu-1 please rebase it. https://rook.io/docs/rook/latest/Contributing/development-flow/#updating-your-fork
Madhu-1: > @Madhu-1 looks like the CI is failing but I don't think it's a CI issue anymore.

Yes, something is wrong, csi holder pod is not getting deployed. will check and update

Patch:
diff --git a/pkg/operator/ceph/csi/controller.go b/pkg/operator/ceph/csi/controller.go
index 48eb2ba86..e7d26aa3a 100644
--- a/pkg/operator/ceph/csi/controller.go
+++ b/pkg/operator/ceph/csi/controller.go
@@ -19,6 +19,7 @@ package csi
 import (
 	"context"
 	"os"
+	"strconv"
 
 	cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
 	cephclient "github.com/rook/rook/pkg/daemon/ceph/client"
@@ -46,11 +47,11 @@ const (
 
 // ReconcileCSI reconciles a ceph-csi driver
 type ReconcileCSI struct {
-	client           client.Client
-	context          *clusterd.Context
-	opManagerContext context.Context
-	opConfig         opcontroller.OperatorConfig
-	multusClusters   []ClusterDetail
+	client             client.Client
+	context            *clusterd.Context
+	opManagerContext   context.Context
+	opConfig           opcontroller.OperatorConfig
+	clustersWithHolder []ClusterDetail
 }
 
 // ClusterDetail is a struct that holds the information of a cluster, it knows its internals (like
@@ -69,11 +70,11 @@ func Add(mgr manager.Manager, context *clusterd.Context, opManagerContext contex
 // newReconciler returns a new reconcile.Reconciler
 func newReconciler(mgr manager.Manager, context *clusterd.Context, opManagerContext context.Context, opConfig opcontroller.OperatorConfig) reconcile.Reconciler {
 	return &ReconcileCSI{
-		client:           mgr.GetClient(),
-		context:          context,
-		opConfig:         opConfig,
-		opManagerContext: opManagerContext,
-		multusClusters:   []ClusterDetail{},
+		client:             mgr.GetClient(),
+		context:            context,
+		opConfig:           opConfig,
+		opManagerContext:   opManagerContext,
+		clustersWithHolder: []ClusterDetail{},
 	}
 }
 
@@ -153,6 +154,29 @@ func (r *ReconcileCSI) reconcile(request reconcile.Request) (reconcile.Result, e
 
 		return reconcile.Result{}, nil
 	}
+	// Fetch the operator's configmap. We force the NamespaceName to the operator since the request
+	// could be a CephCluster. If so the NamespaceName will be the one from the cluster and thus the
+	// CM won't be found
+	opNamespaceName := types.NamespacedName{Name: opcontroller.OperatorSettingConfigMapName, Namespace: r.opConfig.OperatorNamespace}
+	opConfig := &v1.ConfigMap{}
+	err = r.client.Get(r.opManagerContext, opNamespaceName, opConfig)
+	if err != nil {
+		if kerrors.IsNotFound(err) {
+			logger.Debug("operator's configmap resource not found. will use default value or env var.")
+			r.opConfig.Parameters = make(map[string]string)
+		} else {
+			// Error reading the object - requeue the request.
+			return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to get operator's configmap")
+		}
+	} else {
+		// Populate the operator's config
+		r.opConfig.Parameters = opConfig.Data
+	}
+
+	csiHostNetworkEnabled, err := strconv.ParseBool(k8sutil.GetValue(r.opConfig.Parameters, "CSI_ENABLE_HOST_NETWORK", "true"))
+	if err != nil {
+		return reconcile.Result{}, errors.Wrap(err, "failed to parse value for 'CSI_ENABLE_HOST_NETWORK'")
+	}
 
 	for i, cluster := range cephClusters.Items {
 		if !cluster.DeletionTimestamp.IsZero() {
@@ -164,10 +188,10 @@ func (r *ReconcileCSI) reconcile(request reconcile.Request) (reconcile.Result, e
 			logger.Debugf("ceph cluster %q has cleanup policy, the cluster will soon go away, no need to reconcile the csi driver", cluster.Name)
 			return reconcile.Result{}, nil
 		}
-
-		// Do we have a multus cluster?
+		holderEnabled := !csiHostNetworkEnabled || cluster.Spec.Network.IsMultus()
+		// Do we have a multus cluster or csi host network disabled?
 		// If so deploy the plugin holder with the fsid attached
-		if cluster.Spec.Network.IsMultus() {
+		if holderEnabled {
 			// Load cluster info for later use in updating the ceph-csi configmap
 			clusterInfo, _, _, err := opcontroller.LoadClusterInfo(r.context, r.opManagerContext, cluster.Namespace)
 			if err != nil {
@@ -181,30 +205,13 @@ func (r *ReconcileCSI) reconcile(request reconcile.Request) (reconcile.Result, e
 				return opcontroller.ImmediateRetryResult, errors.Wrapf(err, "failed to load cluster info for cluster %q", cluster.Name)
 			}
 
-			logger.Debugf("cluster %q is running on multus, deploying the ceph-csi plugin holder", cluster.Name)
-			r.multusClusters = append(r.multusClusters, ClusterDetail{cluster: &cephClusters.Items[i], clusterInfo: clusterInfo})
-		} else {
-			logger.Debugf("not a multus cluster %q, not deploying the ceph-csi plugin holder", request.NamespacedName)
-		}
-	}
+			logger.Debugf("cluster %q is running on multus or CSI_ENABLE_HOST_NETWORK is false, deploying the ceph-csi plugin holder", cluster.Name)
+
+			r.clustersWithHolder = append(r.clustersWithHolder, ClusterDetail{cluster: &cephClusters.Items[i], clusterInfo: clusterInfo})
 
-	// Fetch the operator's configmap. We force the NamespaceName to the operator since the request
-	// could be a CephCluster. If so the NamespaceName will be the one from the cluster and thus the
-	// CM won't be found
-	opNamespaceName := types.NamespacedName{Name: opcontroller.OperatorSettingConfigMapName, Namespace: r.opConfig.OperatorNamespace}
-	opConfig := &v1.ConfigMap{}
-	err = r.client.Get(r.opManagerContext, opNamespaceName, opConfig)
-	if err != nil {
-		if kerrors.IsNotFound(err) {
-			logger.Debug("operator's configmap resource not found. will use default value or env var.")
-			r.opConfig.Parameters = make(map[string]string)
 		} else {
-			// Error reading the object - requeue the request.
-			return opcontroller.ImmediateRetryResult, errors.Wrap(err, "failed to get operator's configmap")
+			logger.Debugf("not a multus cluster %q or CSI_ENABLE_HOST_NETWORK is true, not deploying the ceph-csi plugin holder", request.NamespacedName)
 		}
-	} else {
-		// Populate the operator's config
-		r.opConfig.Parameters = opConfig.Data
 	}
 
 	ownerRef, err := k8sutil.GetDeploymentOwnerReference(r.opManagerContext, r.context.Clientset, os.Getenv(k8sutil.PodNameEnvVar), r.opConfig.OperatorNamespace)
diff --git a/pkg/operator/ceph/csi/spec.go b/pkg/operator/ceph/csi/spec.go
index 059fddfc5..6d57a61dd 100644
--- a/pkg/operator/ceph/csi/spec.go
+++ b/pkg/operator/ceph/csi/spec.go
@@ -370,8 +370,15 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 			return errors.Wrap(err, "failed to load nfs provisioner deployment template")
 		}
 	}
-	multusApplied := len(r.multusClusters) > 0
 
+	holderEnabled := !CSIParam.EnableCSIHostNetwork
+
+	for i := range r.clustersWithHolder {
+		if r.clustersWithHolder[i].cluster.Spec.Network.IsMultus() {
+			holderEnabled = true
+			break
+		}
+	}
 	// get common provisioner tolerations and node affinity
 	provisionerTolerations := getToleration(r.opConfig.Parameters, provisionerTolerationsEnv, []corev1.Toleration{})
 	provisionerNodeAffinity := getNodeAffinity(r.opConfig.Parameters, provisionerNodeAffinityEnv, &corev1.NodeAffinity{})
@@ -380,11 +387,12 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 	pluginTolerations := getToleration(r.opConfig.Parameters, pluginTolerationsEnv, []corev1.Toleration{})
 	pluginNodeAffinity := getNodeAffinity(r.opConfig.Parameters, pluginNodeAffinityEnv, &corev1.NodeAffinity{})
 
-	if multusApplied && !v.SupportsMultus() {
-		return errors.Errorf("multus is applied but the csi version %q does not support it, need at least %q", v.String(), multusSupportedVersion.String())
+	if holderEnabled && !v.SupportsNsenter() {
+		return errors.Errorf("multus/csi pod networking is applied but the csi version %q does not support it, need at least %q", v.String(), nsenterSupportedVersion.String())
 	}
 
-	// Deploy the CSI Holder DaemonSet if Multus is enabled
+	// Deploy the CSI Holder DaemonSet if Multus is enabled or
+	// EnableCSIHostNetwork is disabled.
 	err = r.configureHolders(enabledDrivers, tp, pluginTolerations, pluginNodeAffinity)
 	if err != nil {
 		return errors.Wrap(err, "failed to configure holder")
@@ -402,11 +410,11 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to rbd plugin daemonset %q", rbdPlugin.Name)
 		}
-		_, err := r.applyCephClusterNetworkConfig(r.opManagerContext, &rbdPlugin.Spec.Template.ObjectMeta)
+		err = r.applyCephClusterNetworkConfig(r.opManagerContext, &rbdPlugin.Spec.Template.ObjectMeta)
 		if err != nil {
 			return errors.Wrapf(err, "failed to apply network config to rbd plugin daemonset %q", rbdPlugin.Name)
 		}
-		if multusApplied {
+		if holderEnabled {
 			rbdPlugin.Spec.Template.Spec.HostNetwork = false
 		}
 		err = k8sutil.CreateDaemonSet(r.opManagerContext, r.opConfig.OperatorNamespace, r.context.Clientset, rbdPlugin)
@@ -434,7 +442,7 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 			Type: apps.RecreateDeploymentStrategyType,
 		}
 
-		_, err = r.applyCephClusterNetworkConfig(r.opManagerContext, &rbdProvisionerDeployment.Spec.Template.ObjectMeta)
+		err = r.applyCephClusterNetworkConfig(r.opManagerContext, &rbdProvisionerDeployment.Spec.Template.ObjectMeta)
 		if err != nil {
 			return errors.Wrapf(err, "failed to apply network config to rbd plugin provisioner deployment %q", rbdProvisionerDeployment.Name)
 		}
@@ -470,11 +478,11 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to cephfs plugin daemonset %q", cephfsPlugin.Name)
 		}
-		multusApplied, err := r.applyCephClusterNetworkConfig(r.opManagerContext, &cephfsPlugin.Spec.Template.ObjectMeta)
+		err = r.applyCephClusterNetworkConfig(r.opManagerContext, &cephfsPlugin.Spec.Template.ObjectMeta)
 		if err != nil {
 			return errors.Wrapf(err, "failed to apply network config to cephfs plugin daemonset %q", cephfsPlugin.Name)
 		}
-		if multusApplied {
+		if holderEnabled {
 			cephfsPlugin.Spec.Template.Spec.HostNetwork = false
 			// HostPID is used to communicate with the network namespace
 			cephfsPlugin.Spec.Template.Spec.HostPID = true
@@ -506,7 +514,7 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 			Type: apps.RecreateDeploymentStrategyType,
 		}
 
-		_, err = r.applyCephClusterNetworkConfig(r.opManagerContext, &cephfsProvisionerDeployment.Spec.Template.ObjectMeta)
+		err = r.applyCephClusterNetworkConfig(r.opManagerContext, &cephfsProvisionerDeployment.Spec.Template.ObjectMeta)
 		if err != nil {
 			return errors.Wrapf(err, "failed to apply network config to cephfs plugin provisioner deployment %q", cephfsProvisionerDeployment.Name)
 		}
@@ -541,11 +549,11 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 		if err != nil {
 			return errors.Wrapf(err, "failed to set owner reference to nfs plugin daemonset %q", nfsPlugin.Name)
 		}
-		multusApplied, err := r.applyCephClusterNetworkConfig(r.opManagerContext, &nfsPlugin.Spec.Template.ObjectMeta)
+		err = r.applyCephClusterNetworkConfig(r.opManagerContext, &nfsPlugin.Spec.Template.ObjectMeta)
 		if err != nil {
 			return errors.Wrapf(err, "failed to apply network config to nfs plugin daemonset %q", nfsPlugin.Name)
 		}
-		if multusApplied {
+		if holderEnabled {
 			nfsPlugin.Spec.Template.Spec.HostNetwork = false
 		}
 		err = k8sutil.CreateDaemonSet(r.opManagerContext, r.opConfig.OperatorNamespace, r.context.Clientset, nfsPlugin)
@@ -574,7 +582,7 @@ func (r *ReconcileCSI) startDrivers(ver *version.Info, ownerInfo *k8sutil.OwnerI
 			Type: apps.RecreateDeploymentStrategyType,
 		}
 
-		_, err = r.applyCephClusterNetworkConfig(r.opManagerContext, &nfsProvisionerDeployment.Spec.Template.ObjectMeta)
+		err = r.applyCephClusterNetworkConfig(r.opManagerContext, &nfsProvisionerDeployment.Spec.Template.ObjectMeta)
 		if err != nil {
 			return errors.Wrapf(err, "failed to apply network config to nfs provisioner deployment %q", nfsProvisionerDeployment.Name)
 		}
@@ -670,23 +678,21 @@ func (r *ReconcileCSI) deleteCSIDriverResources(ver *version.Info, daemonset, de
 	return nil
 }
 
-func (r *ReconcileCSI) applyCephClusterNetworkConfig(ctx context.Context, objectMeta *metav1.ObjectMeta) (bool, error) {
-	var isMultusApplied bool
+func (r *ReconcileCSI) applyCephClusterNetworkConfig(ctx context.Context, objectMeta *metav1.ObjectMeta) error {
 	cephClusters, err := r.context.RookClientset.CephV1().CephClusters(objectMeta.Namespace).List(ctx, metav1.ListOptions{})
 	if err != nil {
-		return false, errors.Wrap(err, "failed to find CephClusters")
+		return errors.Wrap(err, "failed to find CephClusters")
 	}
 	for _, cephCluster := range cephClusters.Items {
 		if cephCluster.Spec.Network.IsMultus() {
 			err = k8sutil.ApplyMultus(cephCluster.Spec.Network, objectMeta)
 			if err != nil {
-				return false, errors.Wrapf(err, "failed to apply multus configuration to CephCluster %q", cephCluster.Name)
+				return errors.Wrapf(err, "failed to apply multus configuration to CephCluster %q", cephCluster.Name)
 			}
-			isMultusApplied = true
 		}
 	}
 
-	return isMultusApplied, nil
+	return nil
 }
 
 // ValidateCSIVersion checks if the configured ceph-csi image is supported
@@ -741,11 +747,11 @@ func (r *ReconcileCSI) validateCSIVersion(ownerInfo *k8sutil.OwnerInfo) (*CephCS
 }
 
 func (r *ReconcileCSI) configureHolders(enabledDrivers []driverDetails, tp templateParam, pluginTolerations []corev1.Toleration, pluginNodeAffinity *corev1.NodeAffinity) error {
-	for _, multusCluster := range r.multusClusters {
+	for _, cluster := range r.clustersWithHolder {
 		for _, driver := range enabledDrivers {
-			err := r.configureHolder(driver, multusCluster, tp, pluginTolerations, pluginNodeAffinity)
+			err := r.configureHolder(driver, cluster, tp, pluginTolerations, pluginNodeAffinity)
 			if err != nil {
-				return errors.Wrapf(err, "failed to configure holder %q for %q/%q", driver.name, multusCluster.cluster.Name, multusCluster.cluster.Namespace)
+				return errors.Wrapf(err, "failed to configure holder %q for %q/%q", driver.name, cluster.cluster.Name, cluster.cluster.Namespace)
 			}
 		}
 	}
@@ -753,7 +759,7 @@ func (r *ReconcileCSI) configureHolders(enabledDrivers []driverDetails, tp templ
 	return nil
 }
 
-func (r *ReconcileCSI) configureHolder(driver driverDetails, multusCluster ClusterDetail, tp templateParam, pluginTolerations []corev1.Toleration, pluginNodeAffinity *corev1.NodeAffinity) error {
+func (r *ReconcileCSI) configureHolder(driver driverDetails, c ClusterDetail, tp templateParam, pluginTolerations []corev1.Toleration, pluginNodeAffinity *corev1.NodeAffinity) error {
 	cephPluginHolder, err := templateToDaemonSet("cephpluginholder", driver.holderTemplate, tp)
 	if err != nil {
 		return errors.Wrapf(err, "failed to load ceph %q plugin holder template", driver.fullName)
@@ -775,7 +781,7 @@ func (r *ReconcileCSI) configureHolder(driver driverDetails, multusCluster Clust
 		cephPluginHolder.Spec.Template.Spec.Containers[0].Env,
 		corev1.EnvVar{
 			Name:  "CEPH_CLUSTER_NAMESPACE",
-			Value: multusCluster.cluster.Namespace,
+			Value: c.cluster.Namespace,
 		},
 	)
 
@@ -790,35 +796,37 @@ func (r *ReconcileCSI) configureHolder(driver driverDetails, multusCluster Clust
 	)
 
 	// Make the DS name unique per Ceph cluster
-	cephPluginHolder.Name = fmt.Sprintf("%s-%s", cephPluginHolder.Name, multusCluster.cluster.Name)
-	cephPluginHolder.Spec.Template.Name = fmt.Sprintf("%s-%s", cephPluginHolder.Spec.Template.Name, multusCluster.cluster.Name)
-	cephPluginHolder.Spec.Template.Spec.Containers[0].Name = fmt.Sprintf("%s-%s", cephPluginHolder.Spec.Template.Spec.Containers[0].Name, multusCluster.cluster.Name)
+	cephPluginHolder.Name = fmt.Sprintf("%s-%s", cephPluginHolder.Name, c.cluster.Name)
+	cephPluginHolder.Spec.Template.Name = fmt.Sprintf("%s-%s", cephPluginHolder.Spec.Template.Name, c.cluster.Name)
+	cephPluginHolder.Spec.Template.Spec.Containers[0].Name = fmt.Sprintf("%s-%s", cephPluginHolder.Spec.Template.Spec.Containers[0].Name, c.cluster.Name)
 
 	// Add default labels
 	k8sutil.AddRookVersionLabelToDaemonSet(cephPluginHolder)
 
-	// Apply Multus annotations to daemonset spec
-	err = k8sutil.ApplyMultus(multusCluster.cluster.Spec.Network, &cephPluginHolder.Spec.Template.ObjectMeta)
-	if err != nil {
-		return errors.Wrapf(err, "failed to apply multus configuration for holder %q in cluster %q", cephPluginHolder.Name, multusCluster.cluster.Namespace)
+	// If multus is enabled, add the multus plugin label
+	if c.cluster.Spec.Network.IsMultus() {
+		// Apply Multus annotations to daemonset spec
+		err = k8sutil.ApplyMultus(c.cluster.Spec.Network, &cephPluginHolder.Spec.Template.ObjectMeta)
+		if err != nil {
+			return errors.Wrapf(err, "failed to apply multus configuration for holder %q in cluster %q", cephPluginHolder.Name, c.cluster.Namespace)
+		}
 	}
-
 	// Finally create the DaemonSet
 	_, err = r.context.Clientset.AppsV1().DaemonSets(r.opConfig.OperatorNamespace).Create(r.opManagerContext, cephPluginHolder, metav1.CreateOptions{})
 	if err != nil {
 		if kerrors.IsAlreadyExists(err) {
-			logger.Debugf("holder %q already exists for cluster %q, it should never be updated", cephPluginHolder.Name, multusCluster.cluster.Namespace)
+			logger.Debugf("holder %q already exists for cluster %q, it should never be updated", cephPluginHolder.Name, c.cluster.Namespace)
 		} else {
 			return errors.Wrapf(err, "failed to start ceph plugin holder daemonset %q", cephPluginHolder.Name)
 		}
 	}
 
 	clusterConfigEntry := &CsiClusterConfigEntry{
-		Monitors: MonEndpoints(multusCluster.clusterInfo.Monitors),
+		Monitors: MonEndpoints(c.clusterInfo.Monitors),
 		RBD:      &CsiRBDSpec{},
 		CephFS:   &CsiCephFSSpec{},
 	}
-	netNamespaceFilePath := generateNetNamespaceFilePath(CSIParam.KubeletDirPath, driver.fullName, multusCluster.cluster.Namespace)
+	netNamespaceFilePath := generateNetNamespaceFilePath(CSIParam.KubeletDirPath, driver.fullName, c.cluster.Namespace)
 	if driver.name == RBDDriverShortName {
 		clusterConfigEntry.RBD.NetNamespaceFilePath = netNamespaceFilePath
 	}
@@ -826,7 +834,7 @@ func (r *ReconcileCSI) configureHolder(driver driverDetails, multusCluster Clust
 		clusterConfigEntry.CephFS.NetNamespaceFilePath = netNamespaceFilePath
 	}
 	// Save the path of the network namespace file for ceph-csi to use
-	err = SaveClusterConfig(r.context.Clientset, multusCluster.cluster.Namespace, multusCluster.clusterInfo, clusterConfigEntry)
+	err = SaveClusterConfig(r.context.Clientset, c.cluster.Namespace, c.clusterInfo, clusterConfigEntry)
 	if err != nil {
 		return errors.Wrapf(err, "failed to save cluster config for csi holder %q", driver.fullName)
 	}
diff --git a/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-holder.yaml b/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-holder.yaml
index 686f6d1e5..e7d447ee9 100644
--- a/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-holder.yaml
+++ b/pkg/operator/ceph/csi/template/cephfs/csi-cephfsplugin-holder.yaml
@@ -1,9 +1,9 @@
-# This DaemonSet is only active when the cluster is deployed with Multus enabled. Hopefully in the
-# future it will be part of every Ceph-CSI deployment. Its role is to "hold" the Ceph Filesystem
-# mounts that are created by the CSI driver. Essentially, it exposes its network namespace into the
-# Kubelet plugin directly and Ceph-CSI picks it up. When mounting, the Ceph-CSI driver will use the
-# network namespace of the DaemonSet instead of its own (the plugin pod). This pod is not expected
-# to be updated nor restarted unless the node reboots.
+# This DaemonSet is only active when the cluster is deployed with Multus enabled or EnableCSIHostNetwork
+# is set to false. Hopefully in the future it will be part of every Ceph-CSI deployment. Its role is to
+# "hold" the Ceph Filesystem mounts that are created by the CSI driver. Essentially, it exposes its
+# network namespace into the Kubelet plugin directly and Ceph-CSI picks it up. When mounting, the Ceph-CSI
+# driver will use the network namespace of the DaemonSet instead of its own (the plugin pod). This pod
+# is not expected to be updated nor restarted unless the node reboots.
 kind: DaemonSet
 apiVersion: apps/v1
 metadata:
diff --git a/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-holder.yaml b/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-holder.yaml
index 6bf9b080f..c64250673 100644
--- a/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-holder.yaml
+++ b/pkg/operator/ceph/csi/template/rbd/csi-rbdplugin-holder.yaml
@@ -1,9 +1,9 @@
-# This DaemonSet is only active when the cluster is deployed with Multus enabled. Hopefully in the
-# future it will be part of every Ceph-CSI deployment. Its role is to "hold" the network RBD block
-# mapping that are created by the CSI driver. Essentially, it exposes its network namespace into the
-# Kubelet plugin directly and Ceph-CSI picks it up. When mapping an RBD image, the Ceph-CSI driver
-# will use the network namespace of the DaemonSet instead of its own (the plugin pod). This pod is
-# not expected to be updated nor restarted unless the node reboots.
+# This DaemonSet is only active when the cluster is deployed with Multus enabled or EnableCSIHostNetwork
+# is set to false. Hopefully in the future it will be part of every Ceph-CSI deployment. Its role is
+# to "hold" the network RBD block mapping that are created by the CSI driver. Essentially, it exposes
+# its network namespace into the Kubelet plugin directly and Ceph-CSI picks it up. When mapping an RBD
+# image, the Ceph-CSI driver will use the network namespace of the DaemonSet instead of its own (the plugin pod).
+# This pod is not expected to be updated nor restarted unless the node reboots.
 kind: DaemonSet
 apiVersion: apps/v1
 metadata:
diff --git a/pkg/operator/ceph/csi/version.go b/pkg/operator/ceph/csi/version.go
index 1a7f21b9e..5c27fbf5f 100644
--- a/pkg/operator/ceph/csi/version.go
+++ b/pkg/operator/ceph/csi/version.go
@@ -40,8 +40,8 @@ var (
 	// custom ceph.conf is supported in v3.5.0+
 	cephConfSupportedVersion = CephCSIVersion{3, 5, 0}
 
-	// multus fix with the extra holder pod is supported with at least v3.6.1
-	multusSupportedVersion = CephCSIVersion{3, 6, 1}
+	// pod networking fix with the extra holder pod is supported with at least v3.6.1
+	nsenterSupportedVersion = CephCSIVersion{3, 6, 1}
 
 	// for parsing the output of `cephcsi`
 	versionCSIPattern = regexp.MustCompile(`v(\d+)\.(\d+)\.(\d+)`)
@@ -131,13 +131,13 @@ func (v *CephCSIVersion) SupportsCustomCephConf() bool {
 	return v.isAtLeast(&cephConfSupportedVersion)
 }
 
-// SupportsMultus checks if the csi image has support for calling "nsenter" while executing
+// SupportsNsenter checks if the csi image has support for calling "nsenter" while executing
 // mount/map commands. This is needed for Multus scenarios.
-func (v *CephCSIVersion) SupportsMultus() bool {
+func (v *CephCSIVersion) SupportsNsenter() bool {
 	// if AllowUnsupported is set also a csi-image greater than the supported ones are allowed
 	if AllowUnsupported {
 		return true
 	}
 
-	return v.isAtLeast(&multusSupportedVersion)
+	return v.isAtLeast(&nsenterSupportedVersion)
 }


Test patch:
diff --git a/.github/workflows/canary-integration-test.yml b/.github/workflows/canary-integration-test.yml
index d6118720e..bf16b17d8 100644
--- a/.github/workflows/canary-integration-test.yml
+++ b/.github/workflows/canary-integration-test.yml
@@ -1191,7 +1191,7 @@ jobs:
       run: tests/scripts/github-action-helper.sh wait_for_prepare_pod
 
     - name: wait for ceph to be ready
-      run: IS_MULTUS=true tests/scripts/github-action-helper.sh wait_for_ceph_to_be_ready osd_multus 2
+      run: IS_POD_NETWORK=true IS_MULTUS=true tests/scripts/github-action-helper.sh wait_for_ceph_to_be_ready osd_multus 2
 
     - name: wait for ceph-csi configmap to be updated with network namespace
       run: tests/scripts/github-action-helper.sh wait_for_ceph_csi_configmap_to_be_updated
@@ -1212,3 +1212,52 @@ jobs:
       if: failure() && github.event_name == 'pull_request'
       uses: mxschmitt/action-tmate@v3
       timeout-minutes: 60
+
+  csi-hostnetwork-disabled:
+    runs-on: ubuntu-18.04
+    if: "!contains(github.event.pull_request.labels.*.name, 'skip-ci')"
+    steps:
+    - name: checkout
+      uses: actions/checkout@v2
+      with:
+        fetch-depth: 0
+
+    - name: setup cluster resources
+      uses: ./.github/workflows/canary-test-config
+      with:
+        github-token: ${{ secrets.GITHUB_TOKEN }}
+
+
+    - name: use local disk and create partitions for osds
+      run: |
+        tests/scripts/github-action-helper.sh use_local_disk
+        tests/scripts/github-action-helper.sh create_partitions_for_osds
+
+    - name: deploy CSI hostNetworking disabled cluster
+      run: tests/scripts/github-action-helper.sh deploy_csi_hostnetwork_disabled_cluster
+
+    - name: wait for prepare pod
+      run: tests/scripts/github-action-helper.sh wait_for_prepare_pod
+
+    - name: wait for ceph to be ready
+      run: IS_POD_NETWORK=true tests/scripts/github-action-helper.sh wait_for_ceph_to_be_ready osd 2
+
+    - name: wait for ceph-csi configmap to be updated with network namespace
+      run: tests/scripts/github-action-helper.sh wait_for_ceph_csi_configmap_to_be_updated
+
+    - name: test ceph-csi-rbd plugin restart
+      run: tests/scripts/github-action-helper.sh test_csi_rbd_workload
+
+    - name: test ceph-csi-cephfs plugin restart
+      run: tests/scripts/github-action-helper.sh test_csi_cephfs_workload
+
+    - name: collect common logs
+      if: always()
+      uses: ./.github/workflows/collect-logs
+      with:
+        name: csi-hostnetwork-disabled
+
+    - name: setup tmate session for debugging when event is PR
+      if: failure() && github.event_name == 'pull_request'
+      uses: mxschmitt/action-tmate@v3
+      timeout-minutes: 60
diff --git a/pkg/operator/ceph/csi/spec_test.go b/pkg/operator/ceph/csi/spec_test.go
index d530e25e1..bc8c74534 100644
--- a/pkg/operator/ceph/csi/spec_test.go
+++ b/pkg/operator/ceph/csi/spec_test.go
@@ -42,9 +42,9 @@ func TestReconcileCSI_configureHolders(t *testing.T) {
 			Clientset:     testop.New(t, 1),
 			RookClientset: rookclient.NewSimpleClientset(),
 		},
-		opManagerContext: context.TODO(),
-		opConfig:         opcontroller.OperatorConfig{},
-		multusClusters:   []ClusterDetail{},
+		opManagerContext:   context.TODO(),
+		opConfig:           opcontroller.OperatorConfig{},
+		clustersWithHolder: []ClusterDetail{},
 	}
 
 	t.Run("no clusters, noop", func(t *testing.T) {
@@ -68,7 +68,7 @@ func TestReconcileCSI_configureHolders(t *testing.T) {
 			Namespace: r.opConfig.OperatorNamespace,
 		}
 
-		r.multusClusters = []ClusterDetail{
+		r.clustersWithHolder = []ClusterDetail{
 			{
 				cluster: &cephv1.CephCluster{
 					ObjectMeta: metav1.ObjectMeta{Namespace: "rook-ceph", Name: "my-cluster"},
diff --git a/pkg/operator/ceph/csi/version_test.go b/pkg/operator/ceph/csi/version_test.go
index c1ef2bbcd..6ee5b8455 100644
--- a/pkg/operator/ceph/csi/version_test.go
+++ b/pkg/operator/ceph/csi/version_test.go
@@ -114,22 +114,22 @@ func TestSupportsCustomCephConf(t *testing.T) {
 	assert.True(t, ret)
 }
 
-func TestSupportsMultus(t *testing.T) {
+func TestSupportsNsenter(t *testing.T) {
 	t.Run("AllowUnsupported=true regardless of the version", func(t *testing.T) {
 		AllowUnsupported = true
-		ret := testMinVersion.SupportsMultus()
+		ret := testMinVersion.SupportsNsenter()
 		assert.True(t, ret)
 	})
 
 	t.Run("AllowUnsupported=false and version 3.5 is too old", func(t *testing.T) {
 		AllowUnsupported = false
-		ret := testMinVersion.SupportsMultus()
+		ret := testMinVersion.SupportsNsenter()
 		assert.False(t, ret)
 	})
 
 	t.Run("AllowUnsupported=false and version 3.6.1 is fine", func(t *testing.T) {
 		AllowUnsupported = false
-		ret := testReleaseV361.SupportsMultus()
+		ret := testReleaseV361.SupportsNsenter()
 		assert.True(t, ret)
 	})
 }
diff --git a/tests/scripts/github-action-helper.sh b/tests/scripts/github-action-helper.sh
index 8962e2409..7800de032 100755
--- a/tests/scripts/github-action-helper.sh
+++ b/tests/scripts/github-action-helper.sh
@@ -228,6 +228,23 @@ function deploy_cluster() {
   deploy_manifest_with_local_build toolbox.yaml
 }
 
+function deploy_csi_hostnetwork_disabled_cluster() {
+  create_cluster_prerequisites
+  cd deploy/examples
+  sed -i 's/.*CSI_ENABLE_HOST_NETWORK:.*/  CSI_ENABLE_HOST_NETWORK: \"false\"/g' operator.yaml
+  deploy_manifest_with_local_build operator.yaml
+  if [ $# == 0 ]; then
+    sed -i "s|#deviceFilter:|deviceFilter: ${BLOCK/\/dev\/}|g" cluster-test.yaml
+  elif [ "$1" = "two_osds_in_device" ] ; then
+    sed -i "s|#deviceFilter:|deviceFilter: ${BLOCK/\/dev\/}\n    config:\n      osdsPerDevice: \"2\"|g" cluster-test.yaml
+  elif [ "$1" = "osd_with_metadata_device" ] ; then
+    sed -i "s|#deviceFilter:|deviceFilter: ${BLOCK/\/dev\/}\n    config:\n      metadataDevice: /dev/test-rook-vg/test-rook-lv|g" cluster-test.yaml
+  fi
+  kubectl create -f cluster-test.yaml
+  kubectl create -f filesystem-test.yaml
+  deploy_manifest_with_local_build toolbox.yaml
+}
+
 function wait_for_prepare_pod() {
   get_pod_cmd=(kubectl --namespace rook-ceph get pod --no-headers)
   timeout=450
diff --git a/tests/scripts/validate_cluster.sh b/tests/scripts/validate_cluster.sh
index ac170130d..6ff47c635 100755
--- a/tests/scripts/validate_cluster.sh
+++ b/tests/scripts/validate_cluster.sh
@@ -89,17 +89,20 @@ function test_demo_pool {
 
 function test_csi {
   timeout 360 bash -x <<-'EOF'
+    echo $IS_POD_NETWORK
     echo $IS_MULTUS
-    if [ -z $IS_MULTUS ]; then
+    if [ -z "$IS_POD_NETWORK" ]; then
       until [[ "$(kubectl -n rook-ceph get pods --field-selector=status.phase=Running|grep -c ^csi-)" -eq 4 ]]; do
         echo "waiting for csi pods to be ready"
         sleep 5
       done
     else
       until [[ "$(kubectl -n rook-ceph get pods --field-selector=status.phase=Running|grep -c ^csi-)" -eq 6 ]]; do
-        echo "waiting for csi pods to be ready with multus"
+        echo "waiting for csi pods to be ready with multus or pod networking"
         sleep 5
       done
+    fi
+    if [ -n "$IS_MULTUS" ]; then
       echo "verifying csi holder interfaces (multus ones must be present)"
       kubectl -n rook-ceph exec -t ds/csi-rbdplugin-holder-my-cluster -- grep net /proc/net/dev
       kubectl -n rook-ceph exec -t ds/csi-cephfsplugin-holder-my-cluster -- grep net /proc/net/dev