Skip to content

Commit fe5dd3e

Browse files
authored
Merge pull request #554 from replicatedhq/laverya/pods-with-notready-containers-are-unhealthy
pods with containers that are not 'ready' are unhealthy
2 parents 3d7a255 + 7eb1d5a commit fe5dd3e

File tree

3 files changed

+122
-9
lines changed

3 files changed

+122
-9
lines changed

pkg/analyze/cluster_pod_statuses.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func clusterPodStatuses(analyzer *troubleshootv1beta2.ClusterPodStatuses, getChi
2222

2323
var pods []corev1.Pod
2424
for fileName, fileContent := range collected {
25-
podsNs := strings.TrimSuffix(fileName, ".json")
25+
podsNs := strings.TrimSuffix(filepath.Base(fileName), ".json")
2626
include := len(analyzer.Namespaces) == 0
2727
for _, ns := range analyzer.Namespaces {
2828
if ns == podsNs {
@@ -33,9 +33,14 @@ func clusterPodStatuses(analyzer *troubleshootv1beta2.ClusterPodStatuses, getChi
3333
if include {
3434
var nsPods corev1.PodList
3535
if err := json.Unmarshal(fileContent, &nsPods); err != nil {
36-
return nil, errors.Wrapf(err, "failed to unmarshal pods list for namespace %s", podsNs)
36+
var nsPodsArr []corev1.Pod
37+
if err := json.Unmarshal(fileContent, &nsPodsArr); err != nil {
38+
return nil, errors.Wrapf(err, "failed to unmarshal pods list for namespace %s", podsNs)
39+
}
40+
pods = append(pods, nsPodsArr...)
41+
} else {
42+
pods = append(pods, nsPods.Items...)
3743
}
38-
pods = append(pods, nsPods.Items...)
3944
}
4045
}
4146

pkg/k8sutil/pod.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,20 @@ func IsPodUnhealthy(pod *corev1.Pod) bool {
114114
}
115115

116116
reason := GetPodStatusReason(pod)
117+
if PodStatusReason(reason) == PodStatusReasonCompleted {
118+
return false // completed pods are healthy pods
119+
}
120+
121+
if PodStatusReason(reason) != PodStatusReasonRunning {
122+
return true // pods that are not completed or running are unhealthy
123+
}
117124

118-
switch PodStatusReason(reason) {
119-
case PodStatusReasonRunning:
120-
fallthrough
121-
case PodStatusReasonCompleted:
122-
return false
125+
// running pods with unready containers are not healthy
126+
for _, containerStatus := range pod.Status.ContainerStatuses {
127+
if !containerStatus.Ready {
128+
return true
129+
}
123130
}
124131

125-
return true
132+
return false
126133
}

pkg/k8sutil/pod_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package k8sutil
2+
3+
import (
4+
"github.com/stretchr/testify/require"
5+
corev1 "k8s.io/api/core/v1"
6+
"testing"
7+
)
8+
9+
func TestIsPodUnhealthy(t *testing.T) {
10+
andTrue := true
11+
tests := []struct {
12+
name string
13+
pod *corev1.Pod
14+
want bool
15+
}{
16+
{
17+
name: "healthy pod with init containers",
18+
want: false,
19+
pod: &corev1.Pod{
20+
Status: corev1.PodStatus{
21+
Phase: "Running",
22+
Conditions: []corev1.PodCondition{
23+
// ignored here
24+
},
25+
InitContainerStatuses: []corev1.ContainerStatus{
26+
{
27+
Name: "init",
28+
State: corev1.ContainerState{
29+
Terminated: &corev1.ContainerStateTerminated{
30+
ExitCode: 0,
31+
Reason: "Completed",
32+
},
33+
},
34+
Ready: true,
35+
RestartCount: 2,
36+
Image: "projectcontour/contour:v1.11.0",
37+
ImageID: "docker://sha256:12878e02b6f969de1456b51b0093f289fd195db956837ccd75aa679e9dac24d9",
38+
ContainerID: "docker://50fc0794fa1402b1a48521e2fd380a92521a69db70ad25c9699c91fccd839d70",
39+
},
40+
},
41+
ContainerStatuses: []corev1.ContainerStatus{
42+
{
43+
Name: "contour",
44+
State: corev1.ContainerState{
45+
Running: &corev1.ContainerStateRunning{},
46+
},
47+
Ready: true,
48+
RestartCount: 5,
49+
Image: "projectcontour/contour:v1.11.0",
50+
ImageID: "docker://sha256:12878e02b6f969de1456b51b0093f289fd195db956837ccd75aa679e9dac24d9",
51+
ContainerID: "docker://50fc0794fa1402b1a48521e2fd380a92521a69db70ad25c9699c91fccd839d70",
52+
Started: &andTrue,
53+
},
54+
},
55+
QOSClass: corev1.PodQOSBestEffort,
56+
},
57+
},
58+
},
59+
{
60+
name: "running pod with one unhealthy container",
61+
want: true,
62+
pod: &corev1.Pod{
63+
Status: corev1.PodStatus{
64+
Phase: "Running",
65+
Conditions: []corev1.PodCondition{
66+
// ignored here
67+
},
68+
ContainerStatuses: []corev1.ContainerStatus{
69+
{
70+
Name: "envoy",
71+
State: corev1.ContainerState{
72+
Running: &corev1.ContainerStateRunning{},
73+
},
74+
Ready: false,
75+
RestartCount: 5,
76+
Started: &andTrue,
77+
},
78+
{
79+
Name: "shutdown-manager",
80+
State: corev1.ContainerState{
81+
Running: &corev1.ContainerStateRunning{},
82+
},
83+
Ready: true,
84+
RestartCount: 5,
85+
Started: &andTrue,
86+
},
87+
},
88+
QOSClass: corev1.PodQOSBestEffort,
89+
},
90+
},
91+
},
92+
}
93+
for _, tt := range tests {
94+
t.Run(tt.name, func(t *testing.T) {
95+
req := require.New(t)
96+
97+
got := IsPodUnhealthy(tt.pod)
98+
req.Equal(tt.want, got)
99+
})
100+
}
101+
}

0 commit comments

Comments
 (0)