Skip to content

Commit 870ce7c

Browse files
authored
Merge pull request #575 from uthark/oatamanenko/kube-proxy-check
Check kube-proxy health on linux
2 parents 7c5e138 + c8629ce commit 870ce7c

File tree

4 files changed

+102
-90
lines changed

4 files changed

+102
-90
lines changed

pkg/healthchecker/health_checker.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ limitations under the License.
1717
package healthchecker
1818

1919
import (
20+
"context"
21+
"net/http"
22+
"os/exec"
23+
"strings"
2024
"time"
2125

2226
"github.com/golang/glog"
@@ -110,3 +114,57 @@ func logPatternHealthCheck(service, logStartTime string, logPatternsToCheck map[
110114
}
111115
return true, nil
112116
}
117+
118+
// healthCheckEndpointOKFunc returns a function to check the status of an http endpoint
119+
func healthCheckEndpointOKFunc(endpoint string, timeout time.Duration) func() (bool, error) {
120+
return func() (bool, error) {
121+
httpClient := http.Client{Timeout: timeout}
122+
response, err := httpClient.Get(endpoint)
123+
if err != nil || response.StatusCode != http.StatusOK {
124+
return false, nil
125+
}
126+
return true, nil
127+
}
128+
}
129+
130+
131+
// getHealthCheckFunc returns the health check function based on the component.
132+
func getHealthCheckFunc(hco *options.HealthCheckerOptions) func() (bool, error) {
133+
switch hco.Component {
134+
case types.KubeletComponent:
135+
return healthCheckEndpointOKFunc(types.KubeletHealthCheckEndpoint, hco.HealthCheckTimeout)
136+
case types.KubeProxyComponent:
137+
return healthCheckEndpointOKFunc(types.KubeProxyHealthCheckEndpoint, hco.HealthCheckTimeout)
138+
case types.DockerComponent:
139+
return func() (bool, error) {
140+
if _, err := execCommand(hco.HealthCheckTimeout, getDockerPath(), "ps"); err != nil {
141+
return false, nil
142+
}
143+
return true, nil
144+
}
145+
case types.CRIComponent:
146+
return func() (bool, error) {
147+
if _, err := execCommand(hco.HealthCheckTimeout, hco.CriCtlPath, "--runtime-endpoint="+hco.CriSocketPath, "--image-endpoint="+hco.CriSocketPath, "pods"); err != nil {
148+
return false, nil
149+
}
150+
return true, nil
151+
}
152+
default:
153+
glog.Warningf("Unsupported component: %v", hco.Component)
154+
}
155+
156+
return nil
157+
}
158+
159+
// execCommand executes the bash command and returns the (output, error) from command, error if timeout occurs.
160+
func execCommand(timeout time.Duration, command string, args ...string) (string, error) {
161+
ctx, cancel := context.WithTimeout(context.Background(), timeout)
162+
defer cancel()
163+
cmd := exec.CommandContext(ctx, command, args...)
164+
out, err := cmd.Output()
165+
if err != nil {
166+
glog.Infof("command %v failed: %v, %v\n", cmd, err, out)
167+
return "", err
168+
}
169+
return strings.TrimSuffix(string(out), "\n"), nil
170+
}

pkg/healthchecker/health_checker_linux.go

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ limitations under the License.
1717
package healthchecker
1818

1919
import (
20-
"context"
2120
"errors"
22-
"net/http"
23-
"os/exec"
2421
"strconv"
2522
"strings"
2623
"time"
@@ -75,49 +72,6 @@ func getRepairFunc(hco *options.HealthCheckerOptions) func() {
7572
}
7673
}
7774

78-
// getHealthCheckFunc returns the health check function based on the component.
79-
func getHealthCheckFunc(hco *options.HealthCheckerOptions) func() (bool, error) {
80-
switch hco.Component {
81-
case types.KubeletComponent:
82-
return func() (bool, error) {
83-
httpClient := http.Client{Timeout: hco.HealthCheckTimeout}
84-
response, err := httpClient.Get(types.KubeletHealthCheckEndpoint)
85-
if err != nil || response.StatusCode != http.StatusOK {
86-
return false, nil
87-
}
88-
return true, nil
89-
}
90-
case types.DockerComponent:
91-
return func() (bool, error) {
92-
if _, err := execCommand(hco.HealthCheckTimeout, "docker", "ps"); err != nil {
93-
return false, nil
94-
}
95-
return true, nil
96-
}
97-
case types.CRIComponent:
98-
return func() (bool, error) {
99-
if _, err := execCommand(hco.HealthCheckTimeout, hco.CriCtlPath, "--runtime-endpoint="+hco.CriSocketPath, "--image-endpoint="+hco.CriSocketPath, "pods"); err != nil {
100-
return false, nil
101-
}
102-
return true, nil
103-
}
104-
}
105-
return nil
106-
}
107-
108-
// execCommand executes the bash command and returns the (output, error) from command, error if timeout occurs.
109-
func execCommand(timeout time.Duration, command string, args ...string) (string, error) {
110-
ctx, cancel := context.WithTimeout(context.Background(), timeout)
111-
defer cancel()
112-
cmd := exec.CommandContext(ctx, command, args...)
113-
out, err := cmd.Output()
114-
if err != nil {
115-
glog.Infof("command %v failed: %v, %v\n", cmd, err, out)
116-
return "", err
117-
}
118-
return strings.TrimSuffix(string(out), "\n"), nil
119-
}
120-
12175
// checkForPattern returns (true, nil) if logPattern occurs less than logCountThreshold number of times since last
12276
// service restart. (false, nil) otherwise.
12377
func checkForPattern(service, logStartTime, logPattern string, logCountThreshold int) (bool, error) {
@@ -141,3 +95,7 @@ func checkForPattern(service, logStartTime, logPattern string, logCountThreshold
14195
}
14296
return true, nil
14397
}
98+
99+
func getDockerPath() string {
100+
return "docker"
101+
}

pkg/healthchecker/health_checker_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121
"time"
2222

23+
"k8s.io/node-problem-detector/cmd/healthchecker/options"
2324
"k8s.io/node-problem-detector/pkg/healthchecker/types"
2425
)
2526

@@ -119,3 +120,38 @@ func TestHealthCheck(t *testing.T) {
119120
})
120121
}
121122
}
123+
124+
func TestComponentsSupported(t *testing.T) {
125+
for _, tc := range []struct {
126+
description string
127+
component string
128+
}{
129+
{
130+
description: "Kube Proxy should be supported",
131+
component: types.KubeProxyComponent,
132+
},
133+
{
134+
description: "Kubelet should be supported",
135+
component: types.KubeletComponent,
136+
},
137+
{
138+
description: "Docker should be supported",
139+
component: types.DockerComponent,
140+
},
141+
{
142+
description: "CRI should be supported",
143+
component: types.CRIComponent,
144+
},
145+
} {
146+
t.Run(tc.description, func(t *testing.T) {
147+
checkFunc := getHealthCheckFunc(&options.HealthCheckerOptions{
148+
Component: tc.component,
149+
})
150+
if checkFunc == nil {
151+
t.Errorf("component %v should be supported", tc.component)
152+
}
153+
154+
})
155+
}
156+
157+
}

pkg/healthchecker/health_checker_windows.go

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package healthchecker
1818

1919
import (
2020
"fmt"
21-
"net/http"
2221
"os/exec"
2322
"strconv"
2423
"strings"
@@ -64,49 +63,6 @@ func getRepairFunc(hco *options.HealthCheckerOptions) func() {
6463
}
6564
}
6665

67-
// getHealthCheckFunc returns the health check function based on the component.
68-
func getHealthCheckFunc(hco *options.HealthCheckerOptions) func() (bool, error) {
69-
switch hco.Component {
70-
case types.KubeletComponent:
71-
return healthCheckEndpointOKFunc(types.KubeletHealthCheckEndpoint, hco.HealthCheckTimeout)
72-
case types.KubeProxyComponent:
73-
return healthCheckEndpointOKFunc(types.KubeProxyHealthCheckEndpoint, hco.HealthCheckTimeout)
74-
case types.DockerComponent:
75-
return func() (bool, error) {
76-
if _, err := execCommand("docker.exe", "ps"); err != nil {
77-
return false, nil
78-
}
79-
return true, nil
80-
}
81-
case types.CRIComponent:
82-
return func() (bool, error) {
83-
if _, err := execCommand(hco.CriCtlPath, "--runtime-endpoint="+hco.CriSocketPath, "--image-endpoint="+hco.CriSocketPath, "pods"); err != nil {
84-
return false, nil
85-
}
86-
return true, nil
87-
}
88-
}
89-
return nil
90-
}
91-
92-
// healthCheckEndpointOKFunc returns a function to check the status of an http endpoint
93-
func healthCheckEndpointOKFunc(endpoint string, timeout time.Duration) func() (bool, error) {
94-
return func() (bool, error) {
95-
httpClient := http.Client{Timeout: timeout}
96-
response, err := httpClient.Get(endpoint)
97-
if err != nil || response.StatusCode != http.StatusOK {
98-
return false, nil
99-
}
100-
return true, nil
101-
}
102-
}
103-
104-
// execCommand creates a new process, executes the command, and returns the (output, error) from command.
105-
func execCommand(command string, args ...string) (string, error) {
106-
cmd := util.Exec(command, args...)
107-
return extractCommandOutput(cmd)
108-
}
109-
11066
// powershell executes the arguments in powershell process and returns (output, error) from command.
11167
func powershell(args ...string) (string, error) {
11268
cmd := util.Powershell(args...)
@@ -143,3 +99,7 @@ func checkForPattern(service, logStartTime, logPattern string, logCountThreshold
14399
}
144100
return true, nil
145101
}
102+
103+
func getDockerPath() string {
104+
return "docker.exe"
105+
}

0 commit comments

Comments
 (0)