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 10, 2023
1 parent 53fb7e1 commit d367244
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 2 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"`
// Container has been killed by force
IsForceKilled bool `json:"isForceKilled,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:
isForceKilled:
description: Container has been killed by force
type: boolean
message:
description: A human readable message indicating details about
this state.
Expand Down
44 changes: 42 additions & 2 deletions pkg/daemon/containerrecreate/crr_daemon_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func getCurrentCRRContainersRecreateStates(
}

syncContainerStatuses := getCRRSyncContainerStatuses(crr)
// the statuses of force killed containers for this crr resource
forceKillContainerStatuses := getKilledContainersStatuses(crr)
var statuses []appsv1alpha1.ContainerRecreateRequestContainerRecreateState

for i := range crr.Spec.Containers {
Expand All @@ -84,6 +86,8 @@ func getCurrentCRRContainersRecreateStates(
syncContainerStatus := syncContainerStatuses[c.Name]
kubeContainerStatus := podStatus.FindContainerStatusByName(c.Name)

killedContainerStatus := forceKillContainerStatuses[c.Name]

var currentState appsv1alpha1.ContainerRecreateRequestContainerRecreateState
if kubeContainerStatus == nil {
// not found the real container
Expand All @@ -93,13 +97,21 @@ func getCurrentCRRContainersRecreateStates(
Message: "not found container on Node",
}

} else if crr.Spec.Strategy.ForceRecreate && containerIsNotForceKilled(killedContainerStatus) {
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
IsForceKilled: true,
Phase: appsv1alpha1.ContainerRecreateRequestPending,
}
} 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,
}

if crr.Spec.Strategy.ForceRecreate {
currentState.IsForceKilled = true
}
} else if kubeContainerStatus.ID.String() != c.StatusContext.ContainerID ||
kubeContainerStatus.RestartCount > int(c.StatusContext.RestartCount) ||
kubeContainerStatus.StartedAt.After(crr.CreationTimestamp.Time) {
Expand All @@ -114,12 +126,17 @@ func getCurrentCRRContainersRecreateStates(
syncContainerStatus.Ready {
currentState.Phase = appsv1alpha1.ContainerRecreateRequestSucceeded
}

if crr.Spec.Strategy.ForceRecreate {
currentState.IsForceKilled = true
}
} else {
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
Phase: appsv1alpha1.ContainerRecreateRequestPending,
}
if crr.Spec.Strategy.ForceRecreate {
currentState.IsForceKilled = true
}
}

statuses = append(statuses, currentState)
Expand All @@ -128,6 +145,16 @@ func getCurrentCRRContainersRecreateStates(
return statuses
}

func containerIsNotForceKilled(recreateState *appsv1alpha1.ContainerRecreateRequestContainerRecreateState) bool {
if recreateState == nil {
return true
}
if !recreateState.IsForceKilled {
return true
}
return false
}

func getCRRContainerRecreateState(crr *appsv1alpha1.ContainerRecreateRequest, name string) *appsv1alpha1.ContainerRecreateRequestContainerRecreateState {
for i := range crr.Status.ContainerRecreateStates {
c := &crr.Status.ContainerRecreateStates[i]
Expand Down Expand Up @@ -157,6 +184,19 @@ func getCRRSyncContainerStatuses(crr *appsv1alpha1.ContainerRecreateRequest) map
return statuses
}

func getKilledContainersStatuses(crr *appsv1alpha1.ContainerRecreateRequest) map[string]*appsv1alpha1.ContainerRecreateRequestContainerRecreateState {
crrContainerRecreateStatus := crr.Status.ContainerRecreateStates
forceKillStatuses := make(map[string]*appsv1alpha1.ContainerRecreateRequestContainerRecreateState, len(crrContainerRecreateStatus))
for i := range crrContainerRecreateStatus {
c := &crrContainerRecreateStatus[i]
if !c.IsForceKilled {
continue
}
forceKillStatuses[c.Name] = c
}
return forceKillStatuses
}

func convertCRRToPod(crr *appsv1alpha1.ContainerRecreateRequest) *v1.Pod {
podName := crr.Spec.PodName
podUID := types.UID(crr.Labels[appsv1alpha1.ContainerRecreateRequestPodUIDKey])
Expand Down

0 comments on commit d367244

Please sign in to comment.