mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Merge pull request #95541 from cofyc/fix95538
volume binding: report UnschedulableAndUnresolvable status instead of an error when bound PVs not found
This commit is contained in:
commit
2d6cd683bd
@ -68,6 +68,8 @@ const (
|
||||
ErrReasonNodeConflict ConflictReason = "node(s) had volume node affinity conflict"
|
||||
// ErrReasonNotEnoughSpace is used when a pod cannot start on a node because not enough storage space is available.
|
||||
ErrReasonNotEnoughSpace = "node(s) did not have enough free storage"
|
||||
// ErrReasonPVNotExist is used when a PVC can't find the bound persistent volumes"
|
||||
ErrReasonPVNotExist = "pvc(s) bound to non-existent pv(s)"
|
||||
)
|
||||
|
||||
// BindingInfo holds a binding between PV and PVC.
|
||||
@ -246,6 +248,7 @@ func (b *volumeBinder) FindPodVolumes(pod *v1.Pod, boundClaims, claimsToBind []*
|
||||
unboundVolumesSatisfied := true
|
||||
boundVolumesSatisfied := true
|
||||
sufficientStorage := true
|
||||
boundPVsFound := true
|
||||
defer func() {
|
||||
if err != nil {
|
||||
return
|
||||
@ -259,6 +262,9 @@ func (b *volumeBinder) FindPodVolumes(pod *v1.Pod, boundClaims, claimsToBind []*
|
||||
if !sufficientStorage {
|
||||
reasons = append(reasons, ErrReasonNotEnoughSpace)
|
||||
}
|
||||
if !boundPVsFound {
|
||||
reasons = append(reasons, ErrReasonPVNotExist)
|
||||
}
|
||||
}()
|
||||
|
||||
start := time.Now()
|
||||
@ -288,7 +294,7 @@ func (b *volumeBinder) FindPodVolumes(pod *v1.Pod, boundClaims, claimsToBind []*
|
||||
|
||||
// Check PV node affinity on bound volumes
|
||||
if len(boundClaims) > 0 {
|
||||
boundVolumesSatisfied, err = b.checkBoundClaims(boundClaims, node, podName)
|
||||
boundVolumesSatisfied, boundPVsFound, err = b.checkBoundClaims(boundClaims, node, podName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -762,7 +768,7 @@ func (b *volumeBinder) GetPodVolumes(pod *v1.Pod) (boundClaims []*v1.PersistentV
|
||||
return boundClaims, unboundClaimsDelayBinding, unboundClaimsImmediate, nil
|
||||
}
|
||||
|
||||
func (b *volumeBinder) checkBoundClaims(claims []*v1.PersistentVolumeClaim, node *v1.Node, podName string) (bool, error) {
|
||||
func (b *volumeBinder) checkBoundClaims(claims []*v1.PersistentVolumeClaim, node *v1.Node, podName string) (bool, bool, error) {
|
||||
csiNode, err := b.csiNodeLister.Get(node.Name)
|
||||
if err != nil {
|
||||
// TODO: return the error once CSINode is created by default
|
||||
@ -773,24 +779,27 @@ func (b *volumeBinder) checkBoundClaims(claims []*v1.PersistentVolumeClaim, node
|
||||
pvName := pvc.Spec.VolumeName
|
||||
pv, err := b.pvCache.GetPV(pvName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
if _, ok := err.(*errNotFound); ok {
|
||||
err = nil
|
||||
}
|
||||
return true, false, err
|
||||
}
|
||||
|
||||
pv, err = b.tryTranslatePVToCSI(pv, csiNode)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, true, err
|
||||
}
|
||||
|
||||
err = volumeutil.CheckNodeAffinity(pv, node.Labels)
|
||||
if err != nil {
|
||||
klog.V(4).Infof("PersistentVolume %q, Node %q mismatch for Pod %q: %v", pvName, node.Name, podName, err)
|
||||
return false, nil
|
||||
return false, true, nil
|
||||
}
|
||||
klog.V(5).Infof("PersistentVolume %q, Node %q matches for Pod %q", pvName, node.Name, podName)
|
||||
}
|
||||
|
||||
klog.V(4).Infof("All bound volumes for Pod %q match with Node %q", podName, node.Name)
|
||||
return true, nil
|
||||
return true, true, nil
|
||||
}
|
||||
|
||||
// findMatchingVolumes tries to find matching volumes for given claims,
|
||||
|
@ -880,7 +880,8 @@ func TestFindPodVolumesWithoutProvisioning(t *testing.T) {
|
||||
},
|
||||
"bound-pvc,pv-not-exists": {
|
||||
podPVCs: []*v1.PersistentVolumeClaim{boundPVC},
|
||||
shouldFail: true,
|
||||
shouldFail: false,
|
||||
reasons: ConflictReasons{ErrReasonPVNotExist},
|
||||
},
|
||||
"prebound-pvc": {
|
||||
podPVCs: []*v1.PersistentVolumeClaim{preboundPVC},
|
||||
|
@ -138,6 +138,22 @@ func TestVolumeBinding(t *testing.T) {
|
||||
podVolumesByNode: map[string]*scheduling.PodVolumes{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "PVC does not exist",
|
||||
pod: makePod("pod-a", []string{"pvc-a"}),
|
||||
node: &v1.Node{},
|
||||
pvcs: []*v1.PersistentVolumeClaim{},
|
||||
wantPreFilterStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, `persistentvolumeclaim "pvc-a" not found`),
|
||||
},
|
||||
{
|
||||
name: "Part of PVCs do not exist",
|
||||
pod: makePod("pod-a", []string{"pvc-a", "pvc-b"}),
|
||||
node: &v1.Node{},
|
||||
pvcs: []*v1.PersistentVolumeClaim{
|
||||
makePVC("pvc-a", "pv-a", waitSC.Name),
|
||||
},
|
||||
wantPreFilterStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, `persistentvolumeclaim "pvc-b" not found`),
|
||||
},
|
||||
{
|
||||
name: "immediate claims not bound",
|
||||
pod: makePod("pod-a", []string{"pvc-a"}),
|
||||
@ -227,7 +243,7 @@ func TestVolumeBinding(t *testing.T) {
|
||||
claimsToBind: []*v1.PersistentVolumeClaim{},
|
||||
podVolumesByNode: map[string]*scheduling.PodVolumes{},
|
||||
},
|
||||
wantFilterStatus: framework.NewStatus(framework.Error, `could not find v1.PersistentVolume "pv-a"`),
|
||||
wantFilterStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, `pvc(s) bound to non-existent pv(s)`),
|
||||
},
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user