mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Ensure terminal pods maintain terminal status
This commit is contained in:
parent
5ff6c2396d
commit
3005ef34f2
@ -1447,6 +1447,20 @@ func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.Po
|
||||
allStatus := append(append([]v1.ContainerStatus{}, s.ContainerStatuses...), s.InitContainerStatuses...)
|
||||
s.Phase = getPhase(&pod.Spec, allStatus)
|
||||
klog.V(4).InfoS("Got phase for pod", "pod", klog.KObj(pod), "oldPhase", oldPodStatus.Phase, "phase", s.Phase)
|
||||
|
||||
// Perform a three-way merge between the statuses from the status manager,
|
||||
// runtime, and generated status to ensure terminal status is correctly set.
|
||||
if s.Phase != v1.PodFailed && s.Phase != v1.PodSucceeded {
|
||||
switch {
|
||||
case oldPodStatus.Phase == v1.PodFailed || oldPodStatus.Phase == v1.PodSucceeded:
|
||||
klog.V(4).InfoS("Status manager phase was terminal, updating phase to match", "pod", klog.KObj(pod), "phase", oldPodStatus.Phase)
|
||||
s.Phase = oldPodStatus.Phase
|
||||
case pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded:
|
||||
klog.V(4).InfoS("API phase was terminal, updating phase to match", "pod", klog.KObj(pod), "phase", pod.Status.Phase)
|
||||
s.Phase = pod.Status.Phase
|
||||
}
|
||||
}
|
||||
|
||||
if s.Phase == oldPodStatus.Phase {
|
||||
// preserve the reason and message which is associated with the phase
|
||||
s.Reason = oldPodStatus.Reason
|
||||
|
@ -2595,6 +2595,95 @@ func Test_generateAPIPodStatus(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "terminal phase from previous status must remain terminal, restartAlways",
|
||||
pod: &v1.Pod{
|
||||
Spec: desiredState,
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
runningState("containerA"),
|
||||
runningState("containerB"),
|
||||
},
|
||||
},
|
||||
},
|
||||
currentStatus: &kubecontainer.PodStatus{},
|
||||
previousStatus: v1.PodStatus{
|
||||
Phase: v1.PodSucceeded,
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
runningState("containerA"),
|
||||
runningState("containerB"),
|
||||
},
|
||||
// Reason and message should be preserved
|
||||
Reason: "Test",
|
||||
Message: "test",
|
||||
},
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodSucceeded,
|
||||
HostIP: "127.0.0.1",
|
||||
QOSClass: v1.PodQOSBestEffort,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodInitialized, Status: v1.ConditionTrue, Reason: "PodCompleted"},
|
||||
{Type: v1.PodReady, Status: v1.ConditionFalse, Reason: "PodCompleted"},
|
||||
{Type: v1.ContainersReady, Status: v1.ConditionFalse, Reason: "PodCompleted"},
|
||||
{Type: v1.PodScheduled, Status: v1.ConditionTrue},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
ready(waitingWithLastTerminationUnknown("containerA", 1)),
|
||||
ready(waitingWithLastTerminationUnknown("containerB", 1)),
|
||||
},
|
||||
Reason: "Test",
|
||||
Message: "test",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "terminal phase from previous status must remain terminal, restartNever",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "machine",
|
||||
Containers: []v1.Container{
|
||||
{Name: "containerA"},
|
||||
{Name: "containerB"},
|
||||
},
|
||||
RestartPolicy: v1.RestartPolicyNever,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodRunning,
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
runningState("containerA"),
|
||||
runningState("containerB"),
|
||||
},
|
||||
},
|
||||
},
|
||||
currentStatus: &kubecontainer.PodStatus{},
|
||||
previousStatus: v1.PodStatus{
|
||||
Phase: v1.PodSucceeded,
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
succeededState("containerA"),
|
||||
succeededState("containerB"),
|
||||
},
|
||||
// Reason and message should be preserved
|
||||
Reason: "Test",
|
||||
Message: "test",
|
||||
},
|
||||
expected: v1.PodStatus{
|
||||
Phase: v1.PodSucceeded,
|
||||
HostIP: "127.0.0.1",
|
||||
QOSClass: v1.PodQOSBestEffort,
|
||||
Conditions: []v1.PodCondition{
|
||||
{Type: v1.PodInitialized, Status: v1.ConditionTrue, Reason: "PodCompleted"},
|
||||
{Type: v1.PodReady, Status: v1.ConditionFalse, Reason: "PodCompleted"},
|
||||
{Type: v1.ContainersReady, Status: v1.ConditionFalse, Reason: "PodCompleted"},
|
||||
{Type: v1.PodScheduled, Status: v1.ConditionTrue},
|
||||
},
|
||||
ContainerStatuses: []v1.ContainerStatus{
|
||||
ready(succeededState("containerA")),
|
||||
ready(succeededState("containerB")),
|
||||
},
|
||||
Reason: "Test",
|
||||
Message: "test",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "running can revert to pending",
|
||||
pod: &v1.Pod{
|
||||
|
Loading…
Reference in New Issue
Block a user