Fix issue #63183 that pods on different nodes mount Ceph RBD PVC stuck on ContainerCreating.

This commit is contained in:
Tardis Xu 2018-05-03 15:47:32 +08:00
parent 456b56a2fb
commit 6d3b41cd85
3 changed files with 42 additions and 7 deletions

View File

@ -232,6 +232,10 @@ func (plugin *rbdPlugin) createMounterFromVolumeSpecAndPod(spec *volume.Spec, po
if err != nil {
return nil, err
}
ams, err := getVolumeAccessModes(spec)
if err != nil {
return nil, err
}
secretName, secretNs, err := getSecretNameAndNamespace(spec, pod.Namespace)
if err != nil {
@ -255,12 +259,13 @@ func (plugin *rbdPlugin) createMounterFromVolumeSpecAndPod(spec *volume.Spec, po
}
return &rbdMounter{
rbd: newRBD("", spec.Name(), img, pool, ro, plugin, &RBDUtil{}),
Mon: mon,
Id: id,
Keyring: keyring,
Secret: secret,
fsType: fstype,
rbd: newRBD("", spec.Name(), img, pool, ro, plugin, &RBDUtil{}),
Mon: mon,
Id: id,
Keyring: keyring,
Secret: secret,
fsType: fstype,
accessModes: ams,
}, nil
}
@ -319,6 +324,10 @@ func (plugin *rbdPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID,
if err != nil {
return nil, err
}
ams, err := getVolumeAccessModes(spec)
if err != nil {
return nil, err
}
return &rbdMounter{
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,
fsType: fstype,
mountOptions: volutil.MountOptionFromSpec(spec),
accessModes: ams,
}, nil
}
@ -764,6 +774,7 @@ type rbdMounter struct {
mountOptions []string
imageFormat string
imageFeatures []string
accessModes []v1.PersistentVolumeAccessMode
}
var _ volume.Mounter = &rbdMounter{}
@ -1039,6 +1050,19 @@ func getVolumeSourceReadOnly(spec *volume.Spec) (bool, error) {
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) {
secret, err := volutil.GetSecretForPod(pod, secretName, kubeClient)
if err != nil {

View File

@ -358,6 +358,7 @@ func TestPlugin(t *testing.T) {
FSType: "ext4",
},
},
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadOnlyMany},
},
}, false),
root: tmpDir,

View File

@ -390,12 +390,22 @@ func (util *RBDUtil) AttachDisk(b rbdMounter) (string, error) {
Factor: rbdImageWatcherFactor,
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) {
used, rbdOutput, err := util.rbdStatus(&b)
if err != nil {
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.
if err == wait.ErrWaitTimeout {