Skip to content

Commit

Permalink
This adds an etcd health check endpoint to kube-apiserver
Browse files Browse the repository at this point in the history
addressing kubernetes#48215.
  • Loading branch information
bjhaid committed Aug 1, 2017
1 parent 12cc642 commit 47d748c
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 25 deletions.
3 changes: 1 addition & 2 deletions cmd/kube-apiserver/app/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ go_library(
tags = ["automanaged"],
deps = [
"//cmd/kube-apiserver/app/options:go_default_library",
"//cmd/kube-apiserver/app/preflight:go_default_library",
"//pkg/api:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/batch:go_default_library",
Expand Down Expand Up @@ -94,6 +93,7 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/options/encryptionconfig:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/etcd3/preflight:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/kube-aggregator/pkg/apis/apiregistration:go_default_library",
Expand All @@ -116,7 +116,6 @@ filegroup(
srcs = [
":package-srcs",
"//cmd/kube-apiserver/app/options:all-srcs",
"//cmd/kube-apiserver/app/preflight:all-srcs",
"//cmd/kube-apiserver/app/testing:all-srcs",
],
tags = ["automanaged"],
Expand Down
2 changes: 1 addition & 1 deletion cmd/kube-apiserver/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ import (
aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver"
//aggregatorinformers "k8s.io/kube-aggregator/pkg/client/informers/internalversion"

"k8s.io/apiserver/pkg/storage/etcd3/preflight"
clientgoinformers "k8s.io/client-go/informers"
clientgoclientset "k8s.io/client-go/kubernetes"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/cmd/kube-apiserver/app/options"
"k8s.io/kubernetes/cmd/kube-apiserver/app/preflight"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
Expand Down
2 changes: 2 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/server/options/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ go_library(
"//vendor/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//vendor/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/storage:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/etcd3/preflight:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
Expand Down
18 changes: 18 additions & 0 deletions staging/src/k8s.io/apiserver/pkg/server/options/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package options

import (
"fmt"
"net/http"

"github.com/spf13/pflag"

Expand All @@ -26,7 +27,9 @@ import (
"k8s.io/apiserver/pkg/registry/generic"
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
"k8s.io/apiserver/pkg/server"
"k8s.io/apiserver/pkg/server/healthz"
serverstorage "k8s.io/apiserver/pkg/server/storage"
"k8s.io/apiserver/pkg/storage/etcd3/preflight"
"k8s.io/apiserver/pkg/storage/storagebackend"
)

Expand Down Expand Up @@ -127,15 +130,30 @@ func (s *EtcdOptions) AddFlags(fs *pflag.FlagSet) {
}

func (s *EtcdOptions) ApplyTo(c *server.Config) error {
s.addEtcdHealthEndpoint(c)
c.RESTOptionsGetter = &SimpleRestOptionsFactory{Options: *s}
return nil
}

func (s *EtcdOptions) ApplyWithStorageFactoryTo(factory serverstorage.StorageFactory, c *server.Config) error {
s.addEtcdHealthEndpoint(c)
c.RESTOptionsGetter = &storageFactoryRestOptionsFactory{Options: *s, StorageFactory: factory}
return nil
}

func (s *EtcdOptions) addEtcdHealthEndpoint(c *server.Config) {
c.HealthzChecks = append(c.HealthzChecks, healthz.NamedCheck("etcd", func(r *http.Request) error {
done, err := preflight.EtcdConnection{ServerList: s.StorageConfig.ServerList}.CheckEtcdServers()
if !done {
return fmt.Errorf("etcd failed")
}
if err != nil {
return err
}
return nil
}))
}

type SimpleRestOptionsFactory struct {
Options EtcdOptions
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,3 @@ go_test(
tags = ["automanaged"],
deps = ["//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library"],
)

filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)

filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,24 @@ type EtcdConnection struct {
ServerList []string
}

func (EtcdConnection) serverReachable(address string) bool {
if conn, err := net.DialTimeout("tcp", address, connectionTimeout); err == nil {
func (EtcdConnection) serverReachable(connURL *url.URL) bool {
scheme := connURL.Scheme
if scheme == "http" || scheme == "https" || scheme == "tcp" {
scheme = "tcp"
}
if conn, err := net.DialTimeout(scheme, connURL.Host, connectionTimeout); err == nil {
defer conn.Close()
return true
}
return false
}

func parseServerURI(serverURI string) (string, error) {
func parseServerURI(serverURI string) (*url.URL, error) {
connURL, err := url.Parse(serverURI)
if err != nil {
return "", fmt.Errorf("unable to parse etcd url: %v", err)
return &url.URL{}, fmt.Errorf("unable to parse etcd url: %v", err)
}
return connURL.Host, nil
return connURL, nil
}

// CheckEtcdServers will attempt to reach all etcd servers once. If any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,34 @@ limitations under the License.
package preflight

import (
"net/url"
"testing"
"time"

utilwait "k8s.io/apimachinery/pkg/util/wait"
)

func TestParseServerURIGood(t *testing.T) {
host, err := parseServerURI("https://127.0.0.1:2379")
connURL, err := parseServerURI("https://127.0.0.1:2379")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

reference := "127.0.0.1:2379"
if host != reference {
t.Fatalf("server uri was not parsed correctly, host %s was invalid", host)
if connURL.Host != reference {
t.Fatalf("server uri was not parsed correctly, host %s was invalid", connURL.Host)
}
}

func TestParseServerURIGoodUnix(t *testing.T) {
connURL, err := parseServerURI("unix://127.0.0.1:21002112605")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

reference := "127.0.0.1:21002112605"
if connURL.Host != reference {
t.Fatalf("server uri was not parsed correctly, host %s was invalid", connURL.Host)
}
}

Expand All @@ -45,7 +58,7 @@ func TestParseServerURIBad(t *testing.T) {
func TestEtcdConnection(t *testing.T) {
etcd := new(EtcdConnection)

result := etcd.serverReachable("-not a real network address-")
result := etcd.serverReachable(&url.URL{Host: "-not a real network address-", Scheme: "tcp"})
if result {
t.Fatal("checkConnection should not have succeeded")
}
Expand Down

0 comments on commit 47d748c

Please sign in to comment.