Skip to content

Commit

Permalink
Sidecar terminator ignore the exit code of the sidecar container
Browse files Browse the repository at this point in the history
Signed-off-by: liuzhenwei <[email protected]>

add ut

Signed-off-by: liuzhenwei <[email protected]>

add some comments and simplified some code

Signed-off-by: liuzhenwei <[email protected]>

remove unnecessary pod status operations

Signed-off-by: liuzhenwei <[email protected]>

change pod to terminal phase before create crr

Signed-off-by: liuzhenwei <[email protected]>

reverse the checking to reduce code indentation

Signed-off-by: liuzhenwei <[email protected]>

simplified some logic

Signed-off-by: liuzhenwei <[email protected]>
  • Loading branch information
diannaowa committed Mar 12, 2024
1 parent 209d476 commit a1465b5
Show file tree
Hide file tree
Showing 7 changed files with 360 additions and 41 deletions.
83 changes: 66 additions & 17 deletions pkg/controller/sidecarterminator/sidecar_terminator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,18 @@ package sidecarterminator

import (
"context"
"encoding/json"
"flag"
"fmt"
"strings"
"time"

appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
"github.com/openkruise/kruise/pkg/features"
"github.com/openkruise/kruise/pkg/util"
utilclient "github.com/openkruise/kruise/pkg/util/client"
utilfeature "github.com/openkruise/kruise/pkg/util/feature"
"github.com/openkruise/kruise/pkg/util/ratelimiter"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/clock"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/record"
"k8s.io/klog/v2"
Expand All @@ -39,14 +38,22 @@ import (
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"

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

func init() {
flag.IntVar(&concurrentReconciles, "sidecarterminator-workers", concurrentReconciles, "Max concurrent workers for SidecarTerminator controller.")
}

var (
concurrentReconciles = 3
concurrentReconciles = 3
SidecarTerminated corev1.PodConditionType = "SidecarTerminated"
)

/**
Expand All @@ -71,6 +78,7 @@ func newReconciler(mgr manager.Manager) reconcile.Reconciler {
Client: cli,
recorder: recorder,
scheme: mgr.GetScheme(),
clock: clock.RealClock{},

Check warning on line 81 in pkg/controller/sidecarterminator/sidecar_terminator_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/sidecarterminator/sidecar_terminator_controller.go#L81

Added line #L81 was not covered by tests
}
}

Expand Down Expand Up @@ -101,6 +109,7 @@ type ReconcileSidecarTerminator struct {
client.Client
recorder record.EventRecorder
scheme *runtime.Scheme
clock clock.Clock
}

// Reconcile get the pod whose sidecar containers should be stopped, and stop them.
Expand Down Expand Up @@ -131,17 +140,8 @@ func (r *ReconcileSidecarTerminator) doReconcile(pod *corev1.Pod) (reconcile.Res
return reconcile.Result{}, nil
}

if containersCompleted(pod, getSidecar(pod)) {
klog.V(3).Infof("SidecarTerminator -- all sidecars of pod(%v/%v) have been completed, no need to process", pod.Namespace, pod.Name)
return reconcile.Result{}, nil
}

if pod.Spec.RestartPolicy == corev1.RestartPolicyOnFailure && !containersSucceeded(pod, getMain(pod)) {
klog.V(3).Infof("SidecarTerminator -- pod(%v/%v) is trying to restart, no need to process", pod.Namespace, pod.Name)
return reconcile.Result{}, nil
}

sidecarNeedToExecuteKillContainer, sidecarNeedToExecuteInPlaceUpdate, err := r.groupSidecars(pod)

if err != nil {
return reconcile.Result{}, err
}
Expand All @@ -150,13 +150,62 @@ func (r *ReconcileSidecarTerminator) doReconcile(pod *corev1.Pod) (reconcile.Res
return reconcile.Result{}, err
}

if err := r.terminateJobPod(pod); err != nil {
return reconcile.Result{}, err
}

Check warning on line 155 in pkg/controller/sidecarterminator/sidecar_terminator_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/sidecarterminator/sidecar_terminator_controller.go#L154-L155

Added lines #L154 - L155 were not covered by tests

if err := r.executeKillContainerAction(pod, sidecarNeedToExecuteKillContainer); err != nil {
return reconcile.Result{}, err
}

return reconcile.Result{}, nil
}

// terminateJobPod terminate the job pod and skip the state of the sidecar containers
// This method should only be called before the executeKillContainerAction
func (r *ReconcileSidecarTerminator) terminateJobPod(pod *corev1.Pod) error {
if pod.Status.Phase == corev1.PodFailed || pod.Status.Phase == corev1.PodSucceeded {
return nil
}

Check warning on line 169 in pkg/controller/sidecarterminator/sidecar_terminator_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/sidecarterminator/sidecar_terminator_controller.go#L168-L169

Added lines #L168 - L169 were not covered by tests

// after the pod is terminated by the sidecar terminator, kubelet will kill the containers that are not in the terminal phase
// 1. sidecar container terminate with non-zero exit code
// 2. sidecar container is not in a terminal phase (still running or waiting)
klog.V(3).Infof("all of the main containers are completed, will terminate the job pod %s/%s", pod.Namespace, pod.Name)
// terminate the pod, ignore the status of the sidecar containers.
// in kubelet,pods are not allowed to transition out of terminal phases.

// patch pod condition
status := corev1.PodStatus{
Conditions: []corev1.PodCondition{
{
Type: SidecarTerminated,
Status: corev1.ConditionTrue,
LastTransitionTime: metav1.Now(),
Message: "Terminated by Sidecar Terminator",
},
},
}

// patch pod phase
if containersSucceeded(pod, getMain(pod)) {
status.Phase = corev1.PodSucceeded
} else {
status.Phase = corev1.PodFailed
}
klog.V(3).Infof("terminate the job pod %s/%s phase=%s", pod.Namespace, pod.Name, status.Phase)

by, _ := json.Marshal(status)
patchCondition := fmt.Sprintf(`{"status":%s}`, string(by))
rcvObject := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: pod.Namespace, Name: pod.Name}}

if err := r.Status().Patch(context.TODO(), rcvObject, client.RawPatch(types.StrategicMergePatchType, []byte(patchCondition))); err != nil {
return fmt.Errorf("failed to patch pod status: %v", err)
}

Check warning on line 204 in pkg/controller/sidecarterminator/sidecar_terminator_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/sidecarterminator/sidecar_terminator_controller.go#L203-L204

Added lines #L203 - L204 were not covered by tests

return nil
}

func (r *ReconcileSidecarTerminator) groupSidecars(pod *corev1.Pod) (sets.String, sets.String, error) {
runningOnVK, err := IsPodRunningOnVirtualKubelet(pod, r.Client)
if err != nil {
Expand Down
Loading

0 comments on commit a1465b5

Please sign in to comment.