Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add pod graceful termination to pod lifecycle #27153

Merged
merged 2 commits into from May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions e2echart/e2e-chart-template.html
Expand Up @@ -81,7 +81,7 @@ <h5 class="modal-title">Resource</h5>
}

function isPodLifecycle(eventInterval) {
if (eventInterval.locator.includes("pod/") && (eventInterval.message.includes("reason/Created") || eventInterval.message.includes("reason/Scheduled"))) {
if (eventInterval.locator.includes("pod/") && (eventInterval.message.includes("reason/Created") || eventInterval.message.includes("reason/Scheduled") || eventInterval.message.includes("reason/GracefulDelete"))) {
return true
}
return false
Expand Down Expand Up @@ -164,6 +164,9 @@ <h5 class="modal-title">Resource</h5>
if (m[2] == "Scheduled") {
return [item.locator, ` (pod lifecycle)`, "PodScheduled"];
}
if (m[2] == "GracefulDelete") {
return [item.locator, ` (pod lifecycle)`, "PodTerminating"];
}
}
if (m && isContainerLifecycle(item)){
if (m[2] == "ContainerWait") {
Expand Down Expand Up @@ -369,14 +372,14 @@ <h5 class="modal-title">Resource</h5>
'OperatorUnavailable', 'OperatorDegraded', 'OperatorProgressing', // operators
'Update', 'Drain', 'Reboot', 'OperatingSystemUpdate', 'NodeNotReady', // nodes
'Passed', 'Skipped', 'Flaked', 'Failed', // tests
'PodCreated', 'PodScheduled', 'ContainerWait', 'ContainerStart', 'ContainerNotReady', 'ContainerReady', // pods
'PodCreated', 'PodScheduled', 'PodTerminating','ContainerWait', 'ContainerStart', 'ContainerNotReady', 'ContainerReady', // pods
'Degraded', 'Upgradeable', 'False', 'Unknown'])
.range([
'#fada5e','#fada5e','#ffa500','#d0312d', // alerts
'#d0312d', '#ffa500', '#fada5e', // operators
'#1e7bd9', '#4294e6', '#6aaef2', '#96cbff', '#fada5e', // nodes
'#3cb043', '#ceba76', '#ffa500', '#d0312d', // tests
'#96cbff', '#1e7bd9', '#ca8dfd', '#9300ff', '#fada5e','#3cb043', // pods
'#96cbff', '#1e7bd9', '#ffa500', '#ca8dfd', '#9300ff', '#fada5e','#3cb043', // pods
'#b65049', '#32b8b6', '#ffffff', '#bbbbbb']);
myChart.
data(timelineGroups).
Expand Down
20 changes: 13 additions & 7 deletions pkg/monitor/intervalcreation/pod.go
Expand Up @@ -151,17 +151,20 @@ func (t podLifecycleTimeBounder) getEndTime(inLocator string) time.Time {
return *runOnceContainerTermination
}

// for other pod types, use the deletion time if we have it
if objDelete := t.getPodDeletionTime(inLocator); objDelete != nil {
return *objDelete
}
// pods will logically be gone once the pod deletion + grace period is over. Or at least they should be
lastPossiblePodDelete := t.getPodDeletionPlusGraceTime(inLocator)

podEvents, ok := t.podToStateTransitions[locator]
if !ok {
return t.delegate.getEndTime(locator)
}
for _, event := range podEvents {
if monitorapi.ReasonFrom(event.Message) == monitorapi.PodReasonDeleted {
// if the last possible pod delete is before the delete from teh watch stream, it just means our watch was delayed.
// use the pod time instead.
if lastPossiblePodDelete != nil && lastPossiblePodDelete.Before(event.From) {
return *lastPossiblePodDelete
}
return event.From
}
}
Expand Down Expand Up @@ -206,7 +209,7 @@ func (t podLifecycleTimeBounder) getPodCreationTime(inLocator string) *time.Time
return &temp.Time
}

func (t podLifecycleTimeBounder) getPodDeletionTime(inLocator string) *time.Time {
func (t podLifecycleTimeBounder) getPodDeletionPlusGraceTime(inLocator string) *time.Time {
podCoordinates := monitorapi.PodFrom(inLocator)
instanceKey := monitorapi.InstanceKey{
Namespace: podCoordinates.Namespace,
Expand All @@ -228,8 +231,11 @@ func (t podLifecycleTimeBounder) getPodDeletionTime(inLocator string) *time.Time
return nil
}

temp := pod.DeletionTimestamp
return &temp.Time
deletionTime := pod.DeletionTimestamp.Time
if pod.Spec.TerminationGracePeriodSeconds != nil {
deletionTime = deletionTime.Add(time.Duration(*pod.Spec.TerminationGracePeriodSeconds * int64(time.Second)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we assuming that no one does oc delete pod --grace-period=0?

}
return &deletionTime
}

func (t podLifecycleTimeBounder) getRunOnceContainerEnd(inLocator string) *time.Time {
Expand Down
8 changes: 5 additions & 3 deletions pkg/monitor/monitorapi/identification_pod.go
Expand Up @@ -98,9 +98,10 @@ const (
// PodIPReused means the same pod IP is in use by two pods at the same time.
PodIPReused = "ReusedPodIP"

PodReasonCreated = "Created"
PodReasonDeleted = "Deleted"
PodReasonScheduled = "Scheduled"
PodReasonCreated = "Created"
PodReasonGracefulDeleteStarted = "GracefulDelete"
PodReasonDeleted = "Deleted"
PodReasonScheduled = "Scheduled"

ContainerReasonContainerExit = "ContainerExit"
ContainerReasonContainerStart = "ContainerStart"
Expand All @@ -121,6 +122,7 @@ var (
PodLifecycleTransitionReasons = sets.NewString(
PodReasonCreated,
PodReasonScheduled,
PodReasonGracefulDeleteStarted,
PodReasonDeleted,
)

Expand Down
2 changes: 1 addition & 1 deletion pkg/monitor/pod.go
Expand Up @@ -434,7 +434,7 @@ func startPodMonitoring(ctx context.Context, m Recorder, client kubernetes.Inter
conditions = append(conditions, monitorapi.Condition{
Level: monitorapi.Info,
Locator: monitorapi.LocatePod(pod),
Message: fmt.Sprintf("reason/GracefulDelete duration/%ds", *pod.DeletionGracePeriodSeconds),
Message: monitorapi.ReasonedMessagef(monitorapi.PodReasonGracefulDeleteStarted, "duration/%ds", *pod.DeletionGracePeriodSeconds),
})
}
}
Expand Down
9 changes: 6 additions & 3 deletions test/extended/testdata/bindata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.