Merge pull request #63424 from xiaoxubeii/issue-63183-master
Automatic merge from submit-queue (batch tested with PRs 63424, 63657). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Fix #63183 Pods on different nodes mount Ceph RBD PVC stuck on ContainerCreating **What this PR does / why we need it**: Ceph/RBD pvc can be attached on different nodes when use ReadOnlyMany. **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes #63183 **Special notes for your reviewer**: **Release note**: ```release-note None ```
This commit is contained in:
		| @@ -232,6 +232,10 @@ func (plugin *rbdPlugin) createMounterFromVolumeSpecAndPod(spec *volume.Spec, po | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	ams, err := getVolumeAccessModes(spec) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	secretName, secretNs, err := getSecretNameAndNamespace(spec, pod.Namespace) | 	secretName, secretNs, err := getSecretNameAndNamespace(spec, pod.Namespace) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -255,12 +259,13 @@ func (plugin *rbdPlugin) createMounterFromVolumeSpecAndPod(spec *volume.Spec, po | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return &rbdMounter{ | 	return &rbdMounter{ | ||||||
| 		rbd:     newRBD("", spec.Name(), img, pool, ro, plugin, &RBDUtil{}), | 		rbd:         newRBD("", spec.Name(), img, pool, ro, plugin, &RBDUtil{}), | ||||||
| 		Mon:     mon, | 		Mon:         mon, | ||||||
| 		Id:      id, | 		Id:          id, | ||||||
| 		Keyring: keyring, | 		Keyring:     keyring, | ||||||
| 		Secret:  secret, | 		Secret:      secret, | ||||||
| 		fsType:  fstype, | 		fsType:      fstype, | ||||||
|  | 		accessModes: ams, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -319,6 +324,10 @@ func (plugin *rbdPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	ams, err := getVolumeAccessModes(spec) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return &rbdMounter{ | 	return &rbdMounter{ | ||||||
| 		rbd:          newRBD(podUID, spec.Name(), img, pool, ro, plugin, manager), | 		rbd:          newRBD(podUID, spec.Name(), img, pool, ro, plugin, manager), | ||||||
| @@ -328,6 +337,7 @@ func (plugin *rbdPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, | |||||||
| 		Secret:       secret, | 		Secret:       secret, | ||||||
| 		fsType:       fstype, | 		fsType:       fstype, | ||||||
| 		mountOptions: volutil.MountOptionFromSpec(spec), | 		mountOptions: volutil.MountOptionFromSpec(spec), | ||||||
|  | 		accessModes:  ams, | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -764,6 +774,7 @@ type rbdMounter struct { | |||||||
| 	mountOptions  []string | 	mountOptions  []string | ||||||
| 	imageFormat   string | 	imageFormat   string | ||||||
| 	imageFeatures []string | 	imageFeatures []string | ||||||
|  | 	accessModes   []v1.PersistentVolumeAccessMode | ||||||
| } | } | ||||||
|  |  | ||||||
| var _ volume.Mounter = &rbdMounter{} | var _ volume.Mounter = &rbdMounter{} | ||||||
| @@ -1045,6 +1056,19 @@ func getVolumeSourceReadOnly(spec *volume.Spec) (bool, error) { | |||||||
| 	return false, fmt.Errorf("Spec does not reference a RBD volume type") | 	return false, fmt.Errorf("Spec does not reference a RBD volume type") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func getVolumeAccessModes(spec *volume.Spec) ([]v1.PersistentVolumeAccessMode, error) { | ||||||
|  | 	// Only PersistentVolumeSpec has AccessModes | ||||||
|  | 	if spec.PersistentVolume != nil { | ||||||
|  | 		if spec.PersistentVolume.Spec.RBD != nil { | ||||||
|  | 			return spec.PersistentVolume.Spec.AccessModes, nil | ||||||
|  | 		} else { | ||||||
|  | 			return nil, fmt.Errorf("Spec does not reference a RBD volume type") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil, nil | ||||||
|  | } | ||||||
|  |  | ||||||
| func parsePodSecret(pod *v1.Pod, secretName string, kubeClient clientset.Interface) (string, error) { | func parsePodSecret(pod *v1.Pod, secretName string, kubeClient clientset.Interface) (string, error) { | ||||||
| 	secret, err := volutil.GetSecretForPod(pod, secretName, kubeClient) | 	secret, err := volutil.GetSecretForPod(pod, secretName, kubeClient) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
| @@ -358,6 +358,7 @@ func TestPlugin(t *testing.T) { | |||||||
| 						FSType:       "ext4", | 						FSType:       "ext4", | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
|  | 				AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadOnlyMany}, | ||||||
| 			}, | 			}, | ||||||
| 		}, false), | 		}, false), | ||||||
| 		root: tmpDir, | 		root: tmpDir, | ||||||
|   | |||||||
| @@ -390,12 +390,22 @@ func (util *RBDUtil) AttachDisk(b rbdMounter) (string, error) { | |||||||
| 			Factor:   rbdImageWatcherFactor, | 			Factor:   rbdImageWatcherFactor, | ||||||
| 			Steps:    rbdImageWatcherSteps, | 			Steps:    rbdImageWatcherSteps, | ||||||
| 		} | 		} | ||||||
|  | 		needValidUsed := true | ||||||
|  | 		// If accessModes contain ReadOnlyMany, we don't need check rbd status of being used. | ||||||
|  | 		if b.accessModes != nil { | ||||||
|  | 			for _, v := range b.accessModes { | ||||||
|  | 				if v != v1.ReadWriteOnce { | ||||||
|  | 					needValidUsed = false | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		err := wait.ExponentialBackoff(backoff, func() (bool, error) { | 		err := wait.ExponentialBackoff(backoff, func() (bool, error) { | ||||||
| 			used, rbdOutput, err := util.rbdStatus(&b) | 			used, rbdOutput, err := util.rbdStatus(&b) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return false, fmt.Errorf("fail to check rbd image status with: (%v), rbd output: (%s)", err, rbdOutput) | 				return false, fmt.Errorf("fail to check rbd image status with: (%v), rbd output: (%s)", err, rbdOutput) | ||||||
| 			} | 			} | ||||||
| 			return !used, nil | 			return !needValidUsed || !used, nil | ||||||
| 		}) | 		}) | ||||||
| 		// Return error if rbd image has not become available for the specified timeout. | 		// Return error if rbd image has not become available for the specified timeout. | ||||||
| 		if err == wait.ErrWaitTimeout { | 		if err == wait.ErrWaitTimeout { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Kubernetes Submit Queue
					Kubernetes Submit Queue