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 7, 2023
1 parent 53fb7e1 commit 5e15dc1
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
21 changes: 21 additions & 0 deletions apis/apps/v1alpha1/containerrecreaterequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const (
// ContainerRecreateRequestUnreadyAcquiredKey indicates the Pod has been forced to not-ready.
// It is required if the unreadyGracePeriodSeconds is set in ContainerRecreateRequests.
ContainerRecreateRequestUnreadyAcquiredKey = "crr.apps.kruise.io/unready-acquired"

// It is a status key for containers which are be killed by crr
ContainerRecreateRequestForceKilledContainerStatusesKey = "crr.apps.kruise.io/force-killed-container-statuses"
)

// ContainerRecreateRequestSpec defines the desired state of ContainerRecreateRequest
Expand Down Expand Up @@ -106,6 +109,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 not running.
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 +163,12 @@ type ContainerRecreateRequestContainerRecreateState struct {
Phase ContainerRecreateRequestPhase `json:"phase"`
// A human readable message indicating details about this state.
Message string `json:"message,omitempty"`
// Container should be killed by force
ShouldBeKilledByForce bool `json:"shouldBeKilledByForce"`
// Container has been killed by force
IsForceKilled bool `json:"isForceKilled"`
// Container's ID in the format 'docker://<container_id>'.
ContainerID string `json:"containerID,omitempty"`
}

// ContainerRecreateRequestSyncContainerStatus only uses in the annotation `crr.apps.kruise.io/sync-container-statuses`.
Expand All @@ -172,6 +183,16 @@ type ContainerRecreateRequestSyncContainerStatus struct {
ContainerID string `json:"containerID,omitempty"`
}

// ContainerRecreateRequestKilledContainerStatus contains the state of the last killed container.
type ContainerRecreateRequestForceKilledContainerStatus struct {
// Name of the container.
Name string `json:"name"`
// Container is killed by force
IsForceKilled bool `json:"restartCount"`
// Container's ID in the format 'docker://<container_id>'.
ContainerID string `json:"containerID,omitempty"`
}

// +genclient
// +k8s:openapi-gen=true
// +kubebuilder:object:root=true
Expand Down
5 changes: 5 additions & 0 deletions pkg/daemon/containerrecreate/crr_daemon_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,11 @@ func (c *Controller) manage(crr *appsv1alpha1.ContainerRecreateRequest) error {
}
return c.patchCRRContainerRecreateStates(crr, newCRRContainerRecreateStates)
}

if crr.Spec.Strategy.ForceRecreate && state.ShouldBeKilledByForce {
state.IsForceKilled = true
state.ContainerID = kubeContainerStatus.ID.String()
}
state.Phase = appsv1alpha1.ContainerRecreateRequestRecreating
break
}
Expand Down
33 changes: 32 additions & 1 deletion 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 := getCRRForceKillContainersStatuses(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 Down Expand Up @@ -114,7 +118,11 @@ func getCurrentCRRContainersRecreateStates(
syncContainerStatus.Ready {
currentState.Phase = appsv1alpha1.ContainerRecreateRequestSucceeded
}

if crr.Spec.Strategy.ForceRecreate && (len(forceKillContainerStatuses) == 0 ||
containerIsNotForceKilled(killedContainerStatus)) {
currentState.ShouldBeKilledByForce = true
currentState.Phase = appsv1alpha1.ContainerRecreateRequestPending
}
} else {
currentState = appsv1alpha1.ContainerRecreateRequestContainerRecreateState{
Name: c.Name,
Expand All @@ -128,6 +136,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 +175,19 @@ func getCRRSyncContainerStatuses(crr *appsv1alpha1.ContainerRecreateRequest) map
return statuses
}

func getCRRForceKillContainersStatuses(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 5e15dc1

Please sign in to comment.