mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Merge pull request #11919 from samsabed/descLaststatus
kubectl describe pod should print lastState
This commit is contained in:
commit
a0371b3985
@ -185,26 +185,30 @@ on the pod you are interested in:
|
|||||||
|
|
||||||
```console
|
```console
|
||||||
[12:54:41] $ ./cluster/kubectl.sh describe pod simmemleak-hra99
|
[12:54:41] $ ./cluster/kubectl.sh describe pod simmemleak-hra99
|
||||||
Name: simmemleak-hra99
|
Name: simmemleak-hra99
|
||||||
Namespace: default
|
Namespace: default
|
||||||
Image(s): saadali/simmemleak
|
Image(s): saadali/simmemleak
|
||||||
Node: kubernetes-minion-tf0f/10.240.216.66
|
Node: kubernetes-minion-tf0f/10.240.216.66
|
||||||
Labels: name=simmemleak
|
Labels: name=simmemleak
|
||||||
Status: Running
|
Status: Running
|
||||||
Reason:
|
Reason:
|
||||||
Message:
|
Message:
|
||||||
IP: 10.244.2.75
|
IP: 10.244.2.75
|
||||||
Replication Controllers: simmemleak (1/1 replicas created)
|
Replication Controllers: simmemleak (1/1 replicas created)
|
||||||
Containers:
|
Containers:
|
||||||
simmemleak:
|
simmemleak:
|
||||||
Image: saadali/simmemleak
|
Image: saadali/simmemleak
|
||||||
Limits:
|
Limits:
|
||||||
cpu: 100m
|
cpu: 100m
|
||||||
memory: 50Mi
|
memory: 50Mi
|
||||||
State: Running
|
State: Running
|
||||||
Started: Tue, 07 Jul 2015 12:54:41 -0700
|
Started: Tue, 07 Jul 2015 12:54:41 -0700
|
||||||
Ready: False
|
Last Termination State: Terminated
|
||||||
Restart Count: 5
|
Exit Code: 1
|
||||||
|
Started: Fri, 07 Jul 2015 12:54:30 -0700
|
||||||
|
Finished: Fri, 07 Jul 2015 12:54:33 -0700
|
||||||
|
Ready: False
|
||||||
|
Restart Count: 5
|
||||||
Conditions:
|
Conditions:
|
||||||
Type Status
|
Type Status
|
||||||
Ready False
|
Ready False
|
||||||
@ -219,9 +223,7 @@ Events:
|
|||||||
|
|
||||||
The `Restart Count: 5` indicates that the `simmemleak` container in this pod was terminated and restarted 5 times.
|
The `Restart Count: 5` indicates that the `simmemleak` container in this pod was terminated and restarted 5 times.
|
||||||
|
|
||||||
Once [#10861](http://issue.k8s.io/10861) is resolved the reason for the termination of the last container will also be printed in this output.
|
You can call `get pod` with the `-o template -t ...` option to fetch the status of previously terminated containers:
|
||||||
|
|
||||||
Until then you can call `get pod` with the `-o template -t ...` option to fetch the status of previously terminated containers:
|
|
||||||
|
|
||||||
```console
|
```console
|
||||||
[13:59:01] $ ./cluster/kubectl.sh get pod -o template -t '{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc
|
[13:59:01] $ ./cluster/kubectl.sh get pod -o template -t '{{range.status.containerStatuses}}{{"Container Name: "}}{{.name}}{{"\r\nLastState: "}}{{.lastState}}{{end}}' simmemleak-60xbc
|
||||||
|
@ -500,33 +500,10 @@ func describeContainers(pod *api.Pod, out io.Writer) {
|
|||||||
fmt.Fprintf(out, " %s:\t%s\n", name, quantity.String())
|
fmt.Fprintf(out, " %s:\t%s\n", name, quantity.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
describeStatus("State", state, out)
|
||||||
case state.Running != nil:
|
if status.LastTerminationState.Terminated != nil {
|
||||||
fmt.Fprintf(out, " State:\tRunning\n")
|
describeStatus("Last Termination State", status.LastTerminationState, out)
|
||||||
fmt.Fprintf(out, " Started:\t%v\n", state.Running.StartedAt.Time.Format(time.RFC1123Z))
|
|
||||||
case state.Waiting != nil:
|
|
||||||
fmt.Fprintf(out, " State:\tWaiting\n")
|
|
||||||
if state.Waiting.Reason != "" {
|
|
||||||
fmt.Fprintf(out, " Reason:\t%s\n", state.Waiting.Reason)
|
|
||||||
}
|
|
||||||
case state.Terminated != nil:
|
|
||||||
fmt.Fprintf(out, " State:\tTerminated\n")
|
|
||||||
if state.Terminated.Reason != "" {
|
|
||||||
fmt.Fprintf(out, " Reason:\t%s\n", state.Terminated.Reason)
|
|
||||||
}
|
|
||||||
if state.Terminated.Message != "" {
|
|
||||||
fmt.Fprintf(out, " Message:\t%s\n", state.Terminated.Message)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(out, " Exit Code:\t%d\n", state.Terminated.ExitCode)
|
|
||||||
if state.Terminated.Signal > 0 {
|
|
||||||
fmt.Fprintf(out, " Signal:\t%d\n", state.Terminated.Signal)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(out, " Started:\t%s\n", state.Terminated.StartedAt.Time.Format(time.RFC1123Z))
|
|
||||||
fmt.Fprintf(out, " Finished:\t%s\n", state.Terminated.FinishedAt.Time.Format(time.RFC1123Z))
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(out, " State:\tWaiting\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(out, " Ready:\t%v\n", printBool(status.Ready))
|
fmt.Fprintf(out, " Ready:\t%v\n", printBool(status.Ready))
|
||||||
fmt.Fprintf(out, " Restart Count:\t%d\n", status.RestartCount)
|
fmt.Fprintf(out, " Restart Count:\t%d\n", status.RestartCount)
|
||||||
fmt.Fprintf(out, " Variables:\n")
|
fmt.Fprintf(out, " Variables:\n")
|
||||||
@ -555,6 +532,35 @@ func envValueFrom(pod *api.Pod, e api.EnvVar) string {
|
|||||||
return valueFrom
|
return valueFrom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func describeStatus(stateName string, state api.ContainerState, out io.Writer) {
|
||||||
|
switch {
|
||||||
|
case state.Running != nil:
|
||||||
|
fmt.Fprintf(out, " %s:\tRunning\n", stateName)
|
||||||
|
fmt.Fprintf(out, " Started:\t%v\n", state.Running.StartedAt.Time.Format(time.RFC1123Z))
|
||||||
|
case state.Waiting != nil:
|
||||||
|
fmt.Fprintf(out, " %s:\tWaiting\n", stateName)
|
||||||
|
if state.Waiting.Reason != "" {
|
||||||
|
fmt.Fprintf(out, " Reason:\t%s\n", state.Waiting.Reason)
|
||||||
|
}
|
||||||
|
case state.Terminated != nil:
|
||||||
|
fmt.Fprintf(out, " %s:\tTerminated\n", stateName)
|
||||||
|
if state.Terminated.Reason != "" {
|
||||||
|
fmt.Fprintf(out, " Reason:\t%s\n", state.Terminated.Reason)
|
||||||
|
}
|
||||||
|
if state.Terminated.Message != "" {
|
||||||
|
fmt.Fprintf(out, " Message:\t%s\n", state.Terminated.Message)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, " Exit Code:\t%d\n", state.Terminated.ExitCode)
|
||||||
|
if state.Terminated.Signal > 0 {
|
||||||
|
fmt.Fprintf(out, " Signal:\t%d\n", state.Terminated.Signal)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(out, " Started:\t%s\n", state.Terminated.StartedAt.Time.Format(time.RFC1123Z))
|
||||||
|
fmt.Fprintf(out, " Finished:\t%s\n", state.Terminated.FinishedAt.Time.Format(time.RFC1123Z))
|
||||||
|
default:
|
||||||
|
fmt.Fprintf(out, " %s:\tWaiting\n", stateName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func printBool(value bool) string {
|
func printBool(value bool) string {
|
||||||
if value {
|
if value {
|
||||||
return "True"
|
return "True"
|
||||||
|
@ -172,6 +172,29 @@ func TestDescribeContainers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedElements: []string{"test", "State", "Terminated", "Ready", "True", "Restart Count", "7", "Image", "image", "Reason", "potato", "Started", "Finished", "Exit Code", "2"},
|
expectedElements: []string{"test", "State", "Terminated", "Ready", "True", "Restart Count", "7", "Image", "image", "Reason", "potato", "Started", "Finished", "Exit Code", "2"},
|
||||||
},
|
},
|
||||||
|
// Last Terminated
|
||||||
|
{
|
||||||
|
container: api.Container{Name: "test", Image: "image"},
|
||||||
|
status: api.ContainerStatus{
|
||||||
|
Name: "test",
|
||||||
|
State: api.ContainerState{
|
||||||
|
Running: &api.ContainerStateRunning{
|
||||||
|
StartedAt: util.NewTime(time.Now()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
LastTerminationState: api.ContainerState{
|
||||||
|
Terminated: &api.ContainerStateTerminated{
|
||||||
|
StartedAt: util.NewTime(time.Now().Add(time.Second * 3)),
|
||||||
|
FinishedAt: util.NewTime(time.Now()),
|
||||||
|
Reason: "crashing",
|
||||||
|
ExitCode: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Ready: true,
|
||||||
|
RestartCount: 7,
|
||||||
|
},
|
||||||
|
expectedElements: []string{"test", "State", "Terminated", "Ready", "True", "Restart Count", "7", "Image", "image", "Started", "Finished", "Exit Code", "2", "crashing", "3"},
|
||||||
|
},
|
||||||
// No state defaults to waiting.
|
// No state defaults to waiting.
|
||||||
{
|
{
|
||||||
container: api.Container{Name: "test", Image: "image"},
|
container: api.Container{Name: "test", Image: "image"},
|
||||||
|
Loading…
Reference in New Issue
Block a user