Skip to content

Commit

Permalink
chore: refine containers ready condition during image rolling update (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
free6om authored Nov 8, 2024
1 parent 928f3f2 commit 0d4a0b5
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
13 changes: 12 additions & 1 deletion pkg/controller/instanceset/instance_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ func isRunningAndAvailable(pod *corev1.Pod, minReadySeconds int32) bool {
return podutils.IsPodAvailable(pod, minReadySeconds, metav1.Now())
}

func isContainersRunning(pod *corev1.Pod) bool {
for _, status := range pod.Status.ContainerStatuses {
if status.State.Running == nil {
return false
}
}
return true
}

// isCreated returns true if pod has been created and is maintained by the API server
func isCreated(pod *corev1.Pod) bool {
return pod.Status.Phase != ""
Expand Down Expand Up @@ -207,7 +216,9 @@ func isImageMatched(pod *corev1.Pod) bool {
return false
}
// otherwise, statusName should be same as or has suffix of specName
if !strings.HasSuffix(statusName, specName) {
// remove registry and repository in specName (if presents)
names := strings.Split(specName, "/")
if !strings.HasSuffix(statusName, "/"+names[len(names)-1]) {
return false
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/instanceset/instance_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1419,7 +1419,7 @@ var _ = Describe("instance util test", func() {
Name: name,
Image: "apecloud.com/nginx",
}}
Expect(isImageMatched(pod)).Should(BeFalse())
Expect(isImageMatched(pod)).Should(BeTrue())
})
})

Expand Down
11 changes: 11 additions & 0 deletions pkg/controller/instanceset/reconciler_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package instanceset

import (
"fmt"
"time"

apps "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -126,6 +127,7 @@ func (r *updateReconciler) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilder
updatedPods := 0
priorities := ComposeRolePriorityMap(its.Spec.Roles)
isBlocked := false
needRetry := false
sortObjects(oldPodList, priorities, false)
for _, pod := range oldPodList {
if updatingPods >= updateCount || updatingPods >= unavailable {
Expand All @@ -139,6 +141,12 @@ func (r *updateReconciler) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilder
tree.Logger.Info(fmt.Sprintf("InstanceSet %s/%s blocks on update as the image(s) of pod %s is not matched", its.Namespace, its.Name, pod.Name))
break
}
if !isContainersRunning(pod) {
tree.Logger.Info(fmt.Sprintf("InstanceSet %s/%s blocks on update as some the container(s) of pod %s are not started at least for %d seconds", its.Namespace, its.Name, pod.Name, its.Spec.MinReadySeconds))
// as no further event triggers the next reconciliation, we need a retry
needRetry = true
break
}
if !isHealthy(pod) {
tree.Logger.Info(fmt.Sprintf("InstanceSet %s/%s blocks on update as the pod %s is not healthy", its.Namespace, its.Name, pod.Name))
break
Expand Down Expand Up @@ -189,6 +197,9 @@ func (r *updateReconciler) Reconcile(tree *kubebuilderx.ObjectTree) (kubebuilder
if !isBlocked {
meta.RemoveStatusCondition(&its.Status.Conditions, string(workloads.InstanceUpdateRestricted))
}
if needRetry {
return kubebuilderx.RetryAfter(2 * time.Second), nil
}
return kubebuilderx.Continue, nil
}

Expand Down
9 changes: 7 additions & 2 deletions pkg/controller/instanceset/reconciler_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,20 @@ var _ = Describe("update reconciler test", func() {

By("update all pods to ready with outdated revision")
pods := tree.List(&corev1.Pod{})
condition := corev1.PodCondition{
containersReadyCondition := corev1.PodCondition{
Type: corev1.ContainersReady,
Status: corev1.ConditionTrue,
LastTransitionTime: metav1.NewTime(time.Now().Add(-1 * minReadySeconds * time.Second)),
}
readyCondition := corev1.PodCondition{
Type: corev1.PodReady,
Status: corev1.ConditionTrue,
LastTransitionTime: metav1.NewTime(time.Now().Add(-1 * minReadySeconds * time.Second)),
}
makePodAvailableWithOldRevision := func(pod *corev1.Pod) {
pod.Labels[appsv1.ControllerRevisionHashLabelKey] = "old-revision"
pod.Status.Phase = corev1.PodRunning
pod.Status.Conditions = append(pod.Status.Conditions, condition)
pod.Status.Conditions = append(pod.Status.Conditions, readyCondition, containersReadyCondition)
}
for _, object := range pods {
pod, ok := object.(*corev1.Pod)
Expand Down

0 comments on commit 0d4a0b5

Please sign in to comment.