diff --git a/pkg/health/health.go b/pkg/health/health.go index 9d986d36771..7ea0faf1b25 100644 --- a/pkg/health/health.go +++ b/pkg/health/health.go @@ -24,16 +24,22 @@ import ( type Status int +// Status takes only one of values of these constants. const ( Healthy Status = iota Unhealthy Unknown ) +// HTTPGetInterface is an abstract interface for testability. It abstracts the interface of http.Client.Get. type HTTPGetInterface interface { Get(url string) (*http.Response, error) } +// Check checks if a GET request to the url succeeds. +// If the HTTP response code is successful (i.e. 400 > code >= 200), it returns Healthy. +// If the HTTP response code is unsuccessful, it returns Unhealthy. +// It returns Unknown and err if the HTTP communication itself fails. func Check(url string, client HTTPGetInterface) (Status, error) { res, err := client.Get(url) if res.Body != nil { @@ -44,8 +50,7 @@ func Check(url string, client HTTPGetInterface) (Status, error) { } if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest { return Healthy, nil - } else { - glog.V(1).Infof("Health check failed for %s, Response: %v", url, *res) - return Unhealthy, nil } + glog.V(1).Infof("Health check failed for %s, Response: %v", url, *res) + return Unhealthy, nil } diff --git a/pkg/health/health_check.go b/pkg/health/health_check.go index 695559e755c..8820b92c5fd 100644 --- a/pkg/health/health_check.go +++ b/pkg/health/health_check.go @@ -25,12 +25,13 @@ import ( "github.com/golang/glog" ) +// HealthChecker defines an abstract interface for checking container health. type HealthChecker interface { HealthCheck(container api.Container) (Status, error) } -// MakeHealthChecker creates a new HealthChecker. -func MakeHealthChecker() HealthChecker { +// NewHealthChecker creates a new HealthChecker which supports multiple types of liveness probes. +func NewHealthChecker() HealthChecker { return &MuxHealthChecker{ checkers: map[string]HealthChecker{ "http": &HTTPHealthChecker{ @@ -45,6 +46,9 @@ type MuxHealthChecker struct { checkers map[string]HealthChecker } +// HealthCheck delegates the health-checking of the container to one of the bundled implementations. +// It chooses an implementation according to container.LivenessProbe.Type. +// If there is no matching health checker it returns Unknown, nil. func (m *MuxHealthChecker) HealthCheck(container api.Container) (Status, error) { checker, ok := m.checkers[container.LivenessProbe.Type] if !ok || checker == nil { @@ -69,6 +73,7 @@ func (h *HTTPHealthChecker) findPort(container api.Container, portName string) i return -1 } +// HealthCheck checks if the container is healthy by trying sending HTTP Get requests to the container. func (h *HTTPHealthChecker) HealthCheck(container api.Container) (Status, error) { params := container.LivenessProbe.HTTPGet if params == nil { diff --git a/pkg/health/health_check_test.go b/pkg/health/health_check_test.go index 17dc3612466..4f4be7293c7 100644 --- a/pkg/health/health_check_test.go +++ b/pkg/health/health_check_test.go @@ -23,6 +23,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" ) +// fakeHTTPClient is a fake implementation of HTTPGetInterface. type fakeHTTPClient struct { req string res http.Response diff --git a/pkg/healthz/healthz.go b/pkg/healthz/healthz.go index 1f71bb88579..7671fed52c9 100644 --- a/pkg/healthz/healthz.go +++ b/pkg/healthz/healthz.go @@ -30,6 +30,7 @@ func handleHealthz(w http.ResponseWriter, r *http.Request) { w.Write([]byte("ok")) } +// InstallHandler registers a handler for health checking on the path "/healthz" to mux. func InstallHandler(mux *http.ServeMux) { mux.HandleFunc("/healthz", handleHealthz) } diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index d6936d4cc9b..8c40152ad80 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -138,7 +138,7 @@ func (kl *Kubelet) RunKubelet(dockerEndpoint, configPath, manifestURL, etcdServe } go util.Forever(func() { s.ListenAndServe() }, 0) } - kl.HealthChecker = health.MakeHealthChecker() + kl.HealthChecker = health.NewHealthChecker() kl.syncLoop(updateChannel, kl) }