Skip to content

Commit

Permalink
update PVC regardless of whether the Pod is terminating
Browse files Browse the repository at this point in the history
Signed-off-by: Abner-1 <yuanyuxing.yyx@alibaba-inc.com>
  • Loading branch information
ABNER-1 authored and furykerry committed Aug 27, 2024
1 parent 0ff70fb commit c66ed5c
Show file tree
Hide file tree
Showing 15 changed files with 1,103 additions and 163 deletions.
10 changes: 5 additions & 5 deletions apis/apps/v1beta1/statefulset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const (
)

// StatefulSetPersistentVolumeClaimRetentionPolicy describes the policy used for PVCs
// created from the StatefulSet VolumeClaimTemplates.
// created from the StatefulSet VolumeClaims.
type StatefulSetPersistentVolumeClaimRetentionPolicy struct {
// WhenDeleted specifies what happens to PVCs created from StatefulSet
// VolumeClaimTemplates when the StatefulSet is deleted. The default policy
Expand Down Expand Up @@ -365,11 +365,11 @@ type StatefulSetStatus struct {
// LabelSelector is label selectors for query over pods that should match the replica count used by HPA.
LabelSelector string `json:"labelSelector,omitempty"`

// VolumeClaimTemplates represents the status of compatibility between existing VolumeClaims
// and their respective templates. It tracks whether the VolumeClaims have been updated
// to match any changes made to the VolumeClaimTemplates, ensuring synchronization
// VolumeClaims represents the status of compatibility between existing PVCs
// and their respective templates. It tracks whether the PersistentVolumeClaims have been updated
// to match any changes made to the volumeClaimTemplates, ensuring synchronization
// between the defined templates and the actual PersistentVolumeClaims in use.
VolumeClaimTemplates []VolumeClaimStatus `json:"volumeClaimTemplates,omitempty"`
VolumeClaims []VolumeClaimStatus `json:"volumeClaims,omitempty"`
}

// These are valid conditions of a statefulset.
Expand Down
4 changes: 2 additions & 2 deletions apis/apps/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions config/crd/bases/apps.kruise.io_statefulsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1036,11 +1036,11 @@ spec:
indicated by updateRevision.
format: int32
type: integer
volumeClaimTemplates:
volumeClaims:
description: |-
VolumeClaimTemplates represents the status of compatibility between existing VolumeClaims
and their respective templates. It tracks whether the VolumeClaims have been updated
to match any changes made to the VolumeClaimTemplates, ensuring synchronization
VolumeClaims represents the status of compatibility between existing PVCs
and their respective templates. It tracks whether the PersistentVolumeClaims have been updated
to match any changes made to the volumeClaimTemplates, ensuring synchronization
between the defined templates and the actual PersistentVolumeClaims in use.
items:
description: |-
Expand Down
9 changes: 5 additions & 4 deletions pkg/controller/cloneset/core/cloneset_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ import (
"regexp"

"github.com/appscode/jsonpatch"
appspub "github.com/openkruise/kruise/apis/apps/pub"
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils"
"github.com/openkruise/kruise/pkg/util/inplaceupdate"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
kubecontroller "k8s.io/kubernetes/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

appspub "github.com/openkruise/kruise/apis/apps/pub"
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
clonesetutils "github.com/openkruise/kruise/pkg/controller/cloneset/utils"
"github.com/openkruise/kruise/pkg/util/inplaceupdate"
)

var (
Expand Down
15 changes: 8 additions & 7 deletions pkg/controller/cloneset/utils/cloneset_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ import (
"strings"
"sync"

appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
"github.com/openkruise/kruise/pkg/features"
utilclient "github.com/openkruise/kruise/pkg/util/client"
"github.com/openkruise/kruise/pkg/util/expectations"
utilfeature "github.com/openkruise/kruise/pkg/util/feature"
"github.com/openkruise/kruise/pkg/util/requeueduration"
"github.com/openkruise/kruise/pkg/util/revision"
apps "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -37,6 +30,14 @@ import (
kubecontroller "k8s.io/kubernetes/pkg/controller"
"k8s.io/utils/integer"
"sigs.k8s.io/controller-runtime/pkg/client"

appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
"github.com/openkruise/kruise/pkg/features"
utilclient "github.com/openkruise/kruise/pkg/util/client"
"github.com/openkruise/kruise/pkg/util/expectations"
utilfeature "github.com/openkruise/kruise/pkg/util/feature"
"github.com/openkruise/kruise/pkg/util/requeueduration"
"github.com/openkruise/kruise/pkg/util/revision"
)

var (
Expand Down
51 changes: 25 additions & 26 deletions pkg/controller/statefulset/stateful_set_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import (
imagejobutilfunc "github.com/openkruise/kruise/pkg/util/imagejob/utilfunction"
"github.com/openkruise/kruise/pkg/util/inplaceupdate"
"github.com/openkruise/kruise/pkg/util/lifecycle"
"github.com/openkruise/kruise/pkg/util/pvc"
)

// Realistic value for maximum in-flight requests when processing in parallel mode.
Expand Down Expand Up @@ -610,12 +609,8 @@ func (ssc *defaultStatefulSetControl) rollingUpdateStatefulsetPods(
}
} else if utilfeature.DefaultFeatureGate.Enabled(features.StatefulSetAutoResizePVCGate) &&
set.Spec.VolumeClaimUpdateStrategy.Type == appsv1beta1.OnPodRollingUpdateVolumeClaimUpdateStrategyType {
checkReadyFn := func(claim, template *v1.PersistentVolumeClaim) bool {
_, ready := pvc.IsPVCCompatibleAndReady(claim, template)
return ready
}
// check pvc resize status, if not ready, record pod to unavailablePods
ready, err := ssc.checkOwnedPVCStatus(set, replicas[target], checkReadyFn)
ready, err := ssc.podControl.IsOwnedPVCsReady(set, replicas[target])
if err == nil && ready {
continue
}
Expand Down Expand Up @@ -645,30 +640,34 @@ func (ssc *defaultStatefulSetControl) rollingUpdateStatefulsetPods(
return status, nil
}

// delete the Pod if it is not already terminating and does not match the update revision.
if !isTerminating(replicas[target]) {
if utilfeature.DefaultFeatureGate.Enabled(features.StatefulSetAutoResizePVCGate) &&
set.Spec.VolumeClaimUpdateStrategy.Type == appsv1beta1.OnPodRollingUpdateVolumeClaimUpdateStrategyType {
// resize pvc if necessary and wait for resize completed
if match, err := ssc.podControl.IsClaimsCompatible(set, replicas[target]); err != nil {
return status, err
} else if !match {
err = ssc.podControl.TryPatchPVCSize(set, replicas[target])
if err != nil {
return status, err
}
}

allCompleted, err := ssc.checkOwnedPVCStatus(set, replicas[target], pvc.IsPatchPVCCompleted)
// Kruise currently will not patch pvc size until a pod references the resized volume.
// online-file-system-expansion: if no pods referencing the volume are running, file system expansion will not happen.
// refer to https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/#online-file-system-expansion
if utilfeature.DefaultFeatureGate.Enabled(features.StatefulSetAutoResizePVCGate) &&
set.Spec.VolumeClaimUpdateStrategy.Type == appsv1beta1.OnPodRollingUpdateVolumeClaimUpdateStrategyType {
// resize pvc if necessary and wait for resize completed
if match, err := ssc.podControl.IsClaimsCompatible(set, replicas[target]); err != nil {
return status, err
} else if !match {
err = ssc.podControl.TryPatchPVC(set, replicas[target])
if err != nil {
return status, err
} else if !allCompleted {
// mark target as unavailable because pvc's updated
unavailablePods.Insert(replicas[target].Name)
// need to wait for pvc resize completed, continue to handle next pod
continue
}
}

allCompleted, err := ssc.podControl.IsOwnedPVCsCompleted(set, replicas[target])
if err != nil {
return status, err
} else if !allCompleted {
// mark target as unavailable because pvc's updated
unavailablePods.Insert(replicas[target].Name)
// need to wait for pvc resize completed, continue to handle next pod
continue
}
}

// delete the Pod if it is not already terminating and does not match the update revision.
if !isTerminating(replicas[target]) {
// todo validate in-place for pub
inplacing, inplaceUpdateErr := ssc.inPlaceUpdatePod(set, replicas[target], updateRevision, revisions)
if inplaceUpdateErr != nil {
Expand Down
23 changes: 20 additions & 3 deletions pkg/controller/statefulset/stateful_set_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func getPodName(set *appsv1beta1.StatefulSet, ordinal int) string {
}

// getPersistentVolumeClaimName gets the name of PersistentVolumeClaim for a Pod with an ordinal index of ordinal. claim
// must be a PersistentVolumeClaim from set's VolumeClaims template.
// must be a PersistentVolumeClaim from set's VolumeClaimTemplates template.
func getPersistentVolumeClaimName(set *appsv1beta1.StatefulSet, claim *v1.PersistentVolumeClaim, ordinal int) string {
// NOTE: This name format is used by the heuristics for zone spreading in ChooseZoneForVolume
return fmt.Sprintf("%s-%s-%d", claim.Name, set.Name, ordinal)
Expand Down Expand Up @@ -623,15 +623,32 @@ func nextRevision(revisions []*apps.ControllerRevision) int64 {
// inconsistentStatus returns true if the ObservedGeneration of status is greater than set's
// Generation or if any of the status's fields do not match those of set's status.
func inconsistentStatus(set *appsv1beta1.StatefulSet, status *appsv1beta1.StatefulSetStatus) bool {
return status.ObservedGeneration > set.Status.ObservedGeneration ||
if status.ObservedGeneration > set.Status.ObservedGeneration ||
status.Replicas != set.Status.Replicas ||
status.CurrentReplicas != set.Status.CurrentReplicas ||
status.ReadyReplicas != set.Status.ReadyReplicas ||
status.AvailableReplicas != set.Status.AvailableReplicas ||
status.UpdatedReplicas != set.Status.UpdatedReplicas ||
status.CurrentRevision != set.Status.CurrentRevision ||
status.UpdateRevision != set.Status.UpdateRevision ||
status.LabelSelector != set.Status.LabelSelector
status.LabelSelector != set.Status.LabelSelector {
return true
}

volumeClaimName2StatusIdx := map[string]int{}
for i, v := range status.VolumeClaims {
volumeClaimName2StatusIdx[v.VolumeClaimName] = i
}
for _, v := range set.Status.VolumeClaims {
if idx, ok := volumeClaimName2StatusIdx[v.VolumeClaimName]; !ok {
// raw template not exist in current status => inconsistent
return true
} else if status.VolumeClaims[idx].CompatibleReplicas != v.CompatibleReplicas ||
status.VolumeClaims[idx].CompatibleReadyReplicas != v.CompatibleReadyReplicas {
return true
}
}
return false
}

// completeRollingUpdate completes a rolling update when all of set's replica Pods have been updated
Expand Down
Loading

0 comments on commit c66ed5c

Please sign in to comment.