Skip to content

Commit

Permalink
support fix containerrecreaterequest
Browse files Browse the repository at this point in the history
  • Loading branch information
BH4AWS committed Mar 14, 2023
1 parent 53fb7e1 commit 7a252af
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
4 changes: 4 additions & 0 deletions apis/apps/v1alpha1/containerrecreaterequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ type ContainerRecreateRequestStrategy struct {
FailurePolicy ContainerRecreateRequestFailurePolicyType `json:"failurePolicy,omitempty"`
// OrderedRecreate indicates whether to recreate the next container only if the previous one has recreated completely.
OrderedRecreate bool `json:"orderedRecreate,omitempty"`
// ForceRecreate indicates whether to force kill the container even if the previous container is starting.
ForceRecreate bool `json:"forceRecreate,omitempty"`
// TerminationGracePeriodSeconds is the optional duration in seconds to wait the container terminating gracefully.
// Value must be non-negative integer. The value zero indicates delete immediately.
// If this value is nil, we will use pod.Spec.TerminationGracePeriodSeconds as default value.
Expand Down Expand Up @@ -158,6 +160,8 @@ type ContainerRecreateRequestContainerRecreateState struct {
Phase ContainerRecreateRequestPhase `json:"phase"`
// A human readable message indicating details about this state.
Message string `json:"message,omitempty"`
// Containers are killed by kruise daemon
IsKilled bool `json:"isKilled,omitempty"`
}

// ContainerRecreateRequestSyncContainerStatus only uses in the annotation `crr.apps.kruise.io/sync-container-statuses`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ spec:
description: FailurePolicy decides whether to continue if one
container fails to recreate
type: string
forceRecreate:
description: ForceRecreate indicates whether to force kill the
container even if the previous container is starting.
type: boolean
minStartedSeconds:
description: Minimum number of seconds for which a newly created
container should be started and ready without any of its container
Expand Down Expand Up @@ -289,6 +293,9 @@ spec:
description: ContainerRecreateRequestContainerRecreateState contains
the recreation state of the container.
properties:
isKilled:
description: Containers are killed by kruise daemon
type: boolean
message:
description: A human readable message indicating details about
this state.
Expand Down
1 change: 1 addition & 0 deletions pkg/daemon/containerrecreate/crr_daemon_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ func (c *Controller) manage(crr *appsv1alpha1.ContainerRecreateRequest) error {
}
return c.patchCRRContainerRecreateStates(crr, newCRRContainerRecreateStates)
}
state.IsKilled = true
state.Phase = appsv1alpha1.ContainerRecreateRequestRecreating
break
}
Expand Down
45 changes: 34 additions & 11 deletions pkg/daemon/containerrecreate/crr_daemon_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,40 +85,56 @@ func getCurrentCRRContainersRecreateStates(
kubeContainerStatus := podStatus.FindContainerStatusByName(c.Name)

var currentState appsv1alpha1.ContainerRecreateRequestContainerRecreateState

if crr.Spec.Strategy.ForceRecreate {
if previousContainerRecreateState == nil || !previousContainerRecreateState.IsKilled {
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestPending,
}
statuses = append(statuses, currentState)
continue
}
}

// current: previousContainerRecreateState.IsRealKilled = true
// already continue to execute the logic function
if kubeContainerStatus == nil {
// not found the real container
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestPending,
Message: "not found container on Node",
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestPending,
IsKilled: getPreviousContainerKillState(previousContainerRecreateState),
Message: "not found container on Node",
}

} else if kubeContainerStatus.State != kubeletcontainer.ContainerStateRunning {
// for no-running state, we consider it will be recreated or restarted soon
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestRecreating,
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestRecreating,
IsKilled: getPreviousContainerKillState(previousContainerRecreateState),
}

} else if kubeContainerStatus.ID.String() != c.StatusContext.ContainerID ||
kubeContainerStatus.RestartCount > int(c.StatusContext.RestartCount) ||
kubeContainerStatus.StartedAt.After(crr.CreationTimestamp.Time) {
// already recreated or restarted
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestRecreating,
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestRecreating,
IsKilled: getPreviousContainerKillState(previousContainerRecreateState),
}
if syncContainerStatus != nil &&
syncContainerStatus.ContainerID == kubeContainerStatus.ID.String() &&
time.Since(kubeContainerStatus.StartedAt) > minStartedDuration &&
syncContainerStatus.Ready {
currentState.Phase = appsv1alpha1.ContainerRecreateRequestSucceeded
}

} else {
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestPending,
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestPending,
IsKilled: getPreviousContainerKillState(previousContainerRecreateState),
}
}

Expand All @@ -128,6 +144,13 @@ func getCurrentCRRContainersRecreateStates(
return statuses
}

func getPreviousContainerKillState(previousContainerRecreateState *appsv1alpha1.ContainerRecreateRequestContainerRecreateState) bool {
if previousContainerRecreateState == nil {
return false
}
return previousContainerRecreateState.IsKilled
}

func getCRRContainerRecreateState(crr *appsv1alpha1.ContainerRecreateRequest, name string) *appsv1alpha1.ContainerRecreateRequestContainerRecreateState {
for i := range crr.Status.ContainerRecreateStates {
c := &crr.Status.ContainerRecreateStates[i]
Expand Down

0 comments on commit 7a252af

Please sign in to comment.