diff --git a/staging/src/k8s.io/apiserver/pkg/server/BUILD b/staging/src/k8s.io/apiserver/pkg/server/BUILD index c0e960d6bec..84d5a3e58b0 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/server/BUILD @@ -40,6 +40,7 @@ go_test( "//vendor/github.com/go-openapi/spec:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/common:go_default_library", + "//vendor/k8s.io/utils/net:go_default_library", ], ) @@ -120,6 +121,7 @@ go_library( "//vendor/k8s.io/kube-openapi/pkg/handler:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", + "//vendor/k8s.io/utils/net:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiserver/pkg/server/config_selfclient.go b/staging/src/k8s.io/apiserver/pkg/server/config_selfclient.go index 5bd503610ef..f2c2de9b324 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/config_selfclient.go +++ b/staging/src/k8s.io/apiserver/pkg/server/config_selfclient.go @@ -21,6 +21,7 @@ import ( "net" restclient "k8s.io/client-go/rest" + netutils "k8s.io/utils/net" ) // LoopbackClientServerNameOverride is passed to the apiserver from the loopback client in order to @@ -70,23 +71,27 @@ func LoopbackHostPort(bindAddress string) (string, string, error) { return "", "", fmt.Errorf("invalid server bind address: %q", bindAddress) } - isIPv6 := net.ParseIP(host).To4() == nil + isIPv6 := netutils.IsIPv6String(host) // Value is expected to be an IP or DNS name, not "0.0.0.0". if host == "0.0.0.0" || host == "::" { - host = "localhost" // Get ip of local interface, but fall back to "localhost". // Note that "localhost" is resolved with the external nameserver first with Go's stdlib. // So if localhost. resolves, we don't get a 127.0.0.1 as expected. - addrs, err := net.InterfaceAddrs() - if err == nil { - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && ipnet.IP.IsLoopback() && isIPv6 == (ipnet.IP.To4() == nil) { - host = ipnet.IP.String() - break - } - } - } + host = getLoopbackAddress(isIPv6) } return host, port, nil } + +// getLoopbackAddress returns the ip address of local loopback interface. If any error occurs or loopback interface is not found, will fall back to "localhost" +func getLoopbackAddress(wantIPv6 bool) string { + addrs, err := net.InterfaceAddrs() + if err == nil { + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && ipnet.IP.IsLoopback() && wantIPv6 == netutils.IsIPv6(ipnet.IP) { + return ipnet.IP.String() + } + } + } + return "localhost" +} diff --git a/staging/src/k8s.io/apiserver/pkg/server/config_selfclient_test.go b/staging/src/k8s.io/apiserver/pkg/server/config_selfclient_test.go index f8b53537e98..19e975ffb6a 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/config_selfclient_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/config_selfclient_test.go @@ -19,6 +19,8 @@ package server import ( "net" "testing" + + netutils "k8s.io/utils/net" ) func TestLoopbackHostPortIPv4(t *testing.T) { @@ -95,7 +97,7 @@ func isIPv6LoopbackSupported() (ipv6 bool, ipv6only bool, err error) { if !ok || !ipnet.IP.IsLoopback() { continue } - if ipnet.IP.To4() == nil { + if netutils.IsIPv6(ipnet.IP) { ipv6 = true continue }