diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index a0e6196138..c0aeb13c0b 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -469,7 +469,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont systemd.SdNotify(true, "READY=1\n") }() - url := fmt.Sprintf("https://%s:%d", serverConfig.ControlConfig.BindAddressOrLoopback(false), serverConfig.ControlConfig.SupervisorPort) + url := fmt.Sprintf("https://%s:%d", serverConfig.ControlConfig.BindAddressOrLoopback(false, true), serverConfig.ControlConfig.SupervisorPort) token, err := clientaccess.FormatToken(serverConfig.ControlConfig.Runtime.AgentToken, serverConfig.ControlConfig.Runtime.ServerCA) if err != nil { return err diff --git a/pkg/daemons/config/types.go b/pkg/daemons/config/types.go index b7cf18b9e2..0fefef0491 100644 --- a/pkg/daemons/config/types.go +++ b/pkg/daemons/config/types.go @@ -215,32 +215,36 @@ type Control struct { Runtime *ControlRuntime `json:"-"` } -// BindAddressOrLoopback returns an IPv4 or IPv6 address suitable for embedding in server -// URLs. If a bind address was configured, that is returned. If the chooseHostInterface -// parameter is true, and a suitable default interface can be found, that interface's -// address is returned. If neither of the previous were used, the loopback address is -// returned. IPv6 addresses are enclosed in square brackets, as per RFC2732. -func (c *Control) BindAddressOrLoopback(chooseHostInterface bool) string { +// BindAddressOrLoopback returns an IPv4 or IPv6 address suitable for embedding in +// server URLs. If a bind address was configured, that is returned. If the +// chooseHostInterface parameter is true, and a suitable default interface can be +// found, that interface's address is returned. If neither of the previous were used, +// the loopback address is returned. If the urlSafe parameter is true, IPv6 addresses +// are enclosed in square brackets, as per RFC2732. +func (c *Control) BindAddressOrLoopback(chooseHostInterface, urlSafe bool) string { ip := c.BindAddress if ip == "" && chooseHostInterface { if hostIP, _ := utilnet.ChooseHostInterface(); len(hostIP) > 0 { ip = hostIP.String() } } - if utilsnet.IsIPv6String(ip) { + if urlSafe && utilsnet.IsIPv6String(ip) { return fmt.Sprintf("[%s]", ip) } else if ip != "" { return ip } - return c.Loopback() + return c.Loopback(urlSafe) } // Loopback returns an IPv4 or IPv6 loopback address, depending on whether the cluster -// service CIDRs indicate an IPv4/Dual-Stack or IPv6 only cluster. IPv6 addresses are -// enclosed in square brackets, as per RFC2732. -func (c *Control) Loopback() string { +// service CIDRs indicate an IPv4/Dual-Stack or IPv6 only cluster. If the urlSafe +// parameter is true, IPv6 addresses are enclosed in square brackets, as per RFC2732. +func (c *Control) Loopback(urlSafe bool) string { if IPv6OnlyService, _ := util.IsIPv6OnlyCIDRs(c.ServiceIPRanges); IPv6OnlyService { - return "[::1]" + if urlSafe { + return "[::1]" + } + return "::1" } return "127.0.0.1" } diff --git a/pkg/daemons/control/deps/deps.go b/pkg/daemons/control/deps/deps.go index 8c9ea2e192..d5afef4582 100644 --- a/pkg/daemons/control/deps/deps.go +++ b/pkg/daemons/control/deps/deps.go @@ -314,7 +314,7 @@ func genClientCerts(config *config.Control) error { var certGen bool - apiEndpoint := fmt.Sprintf("https://%s:%d", config.Loopback(), config.APIServerPort) + apiEndpoint := fmt.Sprintf("https://%s:%d", config.Loopback(true), config.APIServerPort) certGen, err = factory("system:admin", []string{user.SystemPrivilegedGroup}, runtime.ClientAdminCert, runtime.ClientAdminKey) if err != nil { @@ -734,7 +734,7 @@ func genEgressSelectorConfig(controlConfig *config.Control) error { ProxyProtocol: apiserver.ProtocolHTTPConnect, Transport: &apiserver.Transport{ TCP: &apiserver.TCPTransport{ - URL: fmt.Sprintf("https://%s:%d", controlConfig.BindAddressOrLoopback(false), controlConfig.SupervisorPort), + URL: fmt.Sprintf("https://%s:%d", controlConfig.BindAddressOrLoopback(false, true), controlConfig.SupervisorPort), TLSConfig: &apiserver.TLSConfig{ CABundle: controlConfig.Runtime.ServerCA, ClientKey: controlConfig.Runtime.ClientKubeAPIKey, diff --git a/pkg/daemons/control/server.go b/pkg/daemons/control/server.go index 0d4466fa37..079872042b 100644 --- a/pkg/daemons/control/server.go +++ b/pkg/daemons/control/server.go @@ -31,14 +31,6 @@ import ( _ "k8s.io/component-base/metrics/prometheus/restclient" ) -func getLocalhostIP(serviceCIDR []*net.IPNet) net.IP { - IPv6OnlyService, _ := util.IsIPv6OnlyCIDRs(serviceCIDR) - if IPv6OnlyService { - return net.ParseIP("::1") - } - return net.ParseIP("127.0.0.1") -} - func Server(ctx context.Context, cfg *config.Control) error { rand.Seed(time.Now().UTC().UnixNano()) @@ -111,7 +103,7 @@ func controllerManager(ctx context.Context, cfg *config.Control) error { "cluster-cidr": util.JoinIPNets(cfg.ClusterIPRanges), "root-ca-file": runtime.ServerCA, "profiling": "false", - "bind-address": getLocalhostIP(cfg.ServiceIPRanges).String(), + "bind-address": cfg.Loopback(false), "secure-port": "10257", "use-service-account-credentials": "true", "cluster-signing-kube-apiserver-client-cert-file": runtime.ClientCA, @@ -143,7 +135,7 @@ func scheduler(ctx context.Context, cfg *config.Control) error { "kubeconfig": runtime.KubeConfigScheduler, "authorization-kubeconfig": runtime.KubeConfigScheduler, "authentication-kubeconfig": runtime.KubeConfigScheduler, - "bind-address": getLocalhostIP(cfg.ServiceIPRanges).String(), + "bind-address": cfg.Loopback(false), "secure-port": "10259", "profiling": "false", } @@ -179,7 +171,7 @@ func apiServer(ctx context.Context, cfg *config.Control) error { } argsMap["secure-port"] = strconv.Itoa(cfg.APIServerPort) if cfg.APIServerBindAddress == "" { - argsMap["bind-address"] = getLocalhostIP(cfg.ServiceIPRanges).String() + argsMap["bind-address"] = cfg.Loopback(false) } else { argsMap["bind-address"] = cfg.APIServerBindAddress } @@ -316,7 +308,7 @@ func cloudControllerManager(ctx context.Context, cfg *config.Control) error { "authorization-kubeconfig": runtime.KubeConfigCloudController, "authentication-kubeconfig": runtime.KubeConfigCloudController, "node-status-update-frequency": "1m0s", - "bind-address": getLocalhostIP(cfg.ServiceIPRanges).String(), + "bind-address": cfg.Loopback(false), } if cfg.NoLeaderElect { argsMap["leader-elect"] = "false" diff --git a/pkg/daemons/control/tunnel.go b/pkg/daemons/control/tunnel.go index 816901c69f..aafb908ded 100644 --- a/pkg/daemons/control/tunnel.go +++ b/pkg/daemons/control/tunnel.go @@ -210,7 +210,7 @@ func (t *TunnelServer) dialBackend(ctx context.Context, addr string) (net.Conn, if err != nil { return nil, err } - loopback := t.config.Loopback() + loopback := t.config.Loopback(true) var nodeName string var toKubelet, useTunnel bool diff --git a/pkg/etcd/etcd.go b/pkg/etcd/etcd.go index b4430ff5c8..7cc7c78724 100644 --- a/pkg/etcd/etcd.go +++ b/pkg/etcd/etcd.go @@ -653,7 +653,7 @@ func getEndpoints(control *config.Control) []string { if len(runtime.EtcdConfig.Endpoints) > 0 { return runtime.EtcdConfig.Endpoints } - return []string{fmt.Sprintf("https://%s:2379", control.Loopback())} + return []string{fmt.Sprintf("https://%s:2379", control.Loopback(true))} } // toTLSConfig converts the ControlRuntime configuration to TLS configuration suitable @@ -769,7 +769,7 @@ func (e *ETCD) peerURL() string { // During cluster reset/restore, we only listen on loopback to avoid having peers // connect mid-process. func (e *ETCD) listenPeerURLs(reset bool) string { - peerURLs := fmt.Sprintf("https://%s:2380", e.config.Loopback()) + peerURLs := fmt.Sprintf("https://%s:2380", e.config.Loopback(true)) if !reset { peerURLs += "," + e.peerURL() } @@ -785,7 +785,7 @@ func (e *ETCD) clientURL() string { // During cluster reset/restore, we only listen on loopback to avoid having the apiserver // connect mid-process. func (e *ETCD) listenClientURLs(reset bool) string { - clientURLs := fmt.Sprintf("https://%s:2379", e.config.Loopback()) + clientURLs := fmt.Sprintf("https://%s:2379", e.config.Loopback(true)) if !reset { clientURLs += "," + e.clientURL() } @@ -794,7 +794,7 @@ func (e *ETCD) listenClientURLs(reset bool) string { // listenMetricsURLs returns a list of URLs to bind to for metrics connections. func (e *ETCD) listenMetricsURLs(reset bool) string { - metricsURLs := fmt.Sprintf("http://%s:2381", e.config.Loopback()) + metricsURLs := fmt.Sprintf("http://%s:2381", e.config.Loopback(true)) if !reset && e.config.EtcdExposeMetrics { metricsURLs += "," + fmt.Sprintf("http://%s", net.JoinHostPort(e.address, "2381")) } diff --git a/pkg/server/server.go b/pkg/server/server.go index 97f639ba20..31f0c8c82c 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -337,18 +337,18 @@ func printTokens(config *config.Control) error { } if len(nodeFile) > 0 { - printToken(config.SupervisorPort, config.BindAddressOrLoopback(true), "To join node to cluster:", "agent") + printToken(config.SupervisorPort, config.BindAddressOrLoopback(true, true), "To join node to cluster:", "agent") } return nil } func writeKubeConfig(certs string, config *Config) error { - ip := config.ControlConfig.BindAddressOrLoopback(false) + ip := config.ControlConfig.BindAddressOrLoopback(false, true) port := config.ControlConfig.HTTPSPort // on servers without a local apiserver, tunnel access via the loadbalancer if config.ControlConfig.DisableAPIServer { - ip = config.ControlConfig.Loopback() + ip = config.ControlConfig.Loopback(true) port = config.ControlConfig.APIServerPort } url := fmt.Sprintf("https://%s:%d", ip, port)