Replace getLocalhostIP with Loopback helper method

Requires tweaking existing method signature to allow specifying whether or not IPv6 addresses should be return URL-safe.

Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
(cherry picked from commit 5eaa0a9422)
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
pull/5966/head
Brad Davidson 2022-07-21 14:40:09 -07:00 committed by Brad Davidson
parent 15100b5081
commit 4afe65bff5
7 changed files with 31 additions and 35 deletions

View File

@ -469,7 +469,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
systemd.SdNotify(true, "READY=1\n") 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) token, err := clientaccess.FormatToken(serverConfig.ControlConfig.Runtime.AgentToken, serverConfig.ControlConfig.Runtime.ServerCA)
if err != nil { if err != nil {
return err return err

View File

@ -216,33 +216,37 @@ type Control struct {
Runtime *ControlRuntime `json:"-"` Runtime *ControlRuntime `json:"-"`
} }
// BindAddressOrLoopback returns an IPv4 or IPv6 address suitable for embedding in server // BindAddressOrLoopback returns an IPv4 or IPv6 address suitable for embedding in
// URLs. If a bind address was configured, that is returned. If the chooseHostInterface // server URLs. If a bind address was configured, that is returned. If the
// parameter is true, and a suitable default interface can be found, that interface's // chooseHostInterface parameter is true, and a suitable default interface can be
// address is returned. If neither of the previous were used, the loopback address is // found, that interface's address is returned. If neither of the previous were used,
// returned. IPv6 addresses are enclosed in square brackets, as per RFC2732. // the loopback address is returned. If the urlSafe parameter is true, IPv6 addresses
func (c *Control) BindAddressOrLoopback(chooseHostInterface bool) string { // are enclosed in square brackets, as per RFC2732.
func (c *Control) BindAddressOrLoopback(chooseHostInterface, urlSafe bool) string {
ip := c.BindAddress ip := c.BindAddress
if ip == "" && chooseHostInterface { if ip == "" && chooseHostInterface {
if hostIP, _ := utilnet.ChooseHostInterface(); len(hostIP) > 0 { if hostIP, _ := utilnet.ChooseHostInterface(); len(hostIP) > 0 {
ip = hostIP.String() ip = hostIP.String()
} }
} }
if utilsnet.IsIPv6String(ip) { if urlSafe && utilsnet.IsIPv6String(ip) {
return fmt.Sprintf("[%s]", ip) return fmt.Sprintf("[%s]", ip)
} else if ip != "" { } else if ip != "" {
return ip return ip
} }
return c.Loopback() return c.Loopback(urlSafe)
} }
// Loopback returns an IPv4 or IPv6 loopback address, depending on whether the cluster // 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 // service CIDRs indicate an IPv4/Dual-Stack or IPv6 only cluster. If the urlSafe
// enclosed in square brackets, as per RFC2732. // parameter is true, IPv6 addresses are enclosed in square brackets, as per RFC2732.
func (c *Control) Loopback() string { func (c *Control) Loopback(urlSafe bool) string {
if IPv6OnlyService, _ := util.IsIPv6OnlyCIDRs(c.ServiceIPRanges); IPv6OnlyService { if IPv6OnlyService, _ := util.IsIPv6OnlyCIDRs(c.ServiceIPRanges); IPv6OnlyService {
if urlSafe {
return "[::1]" return "[::1]"
} }
return "::1"
}
return "127.0.0.1" return "127.0.0.1"
} }

View File

@ -314,7 +314,7 @@ func genClientCerts(config *config.Control) error {
var certGen bool 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) certGen, err = factory("system:admin", []string{user.SystemPrivilegedGroup}, runtime.ClientAdminCert, runtime.ClientAdminKey)
if err != nil { if err != nil {
@ -734,7 +734,7 @@ func genEgressSelectorConfig(controlConfig *config.Control) error {
ProxyProtocol: apiserver.ProtocolHTTPConnect, ProxyProtocol: apiserver.ProtocolHTTPConnect,
Transport: &apiserver.Transport{ Transport: &apiserver.Transport{
TCP: &apiserver.TCPTransport{ 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{ TLSConfig: &apiserver.TLSConfig{
CABundle: controlConfig.Runtime.ServerCA, CABundle: controlConfig.Runtime.ServerCA,
ClientKey: controlConfig.Runtime.ClientKubeAPIKey, ClientKey: controlConfig.Runtime.ClientKubeAPIKey,

View File

@ -31,14 +31,6 @@ import (
_ "k8s.io/component-base/metrics/prometheus/restclient" _ "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 { func Server(ctx context.Context, cfg *config.Control) error {
rand.Seed(time.Now().UTC().UnixNano()) 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), "cluster-cidr": util.JoinIPNets(cfg.ClusterIPRanges),
"root-ca-file": runtime.ServerCA, "root-ca-file": runtime.ServerCA,
"profiling": "false", "profiling": "false",
"bind-address": getLocalhostIP(cfg.ServiceIPRanges).String(), "bind-address": cfg.Loopback(false),
"secure-port": "10257", "secure-port": "10257",
"use-service-account-credentials": "true", "use-service-account-credentials": "true",
"cluster-signing-kube-apiserver-client-cert-file": runtime.ClientCA, "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, "kubeconfig": runtime.KubeConfigScheduler,
"authorization-kubeconfig": runtime.KubeConfigScheduler, "authorization-kubeconfig": runtime.KubeConfigScheduler,
"authentication-kubeconfig": runtime.KubeConfigScheduler, "authentication-kubeconfig": runtime.KubeConfigScheduler,
"bind-address": getLocalhostIP(cfg.ServiceIPRanges).String(), "bind-address": cfg.Loopback(false),
"secure-port": "10259", "secure-port": "10259",
"profiling": "false", "profiling": "false",
} }
@ -180,7 +172,7 @@ func apiServer(ctx context.Context, cfg *config.Control) error {
argsMap["insecure-port"] = "0" argsMap["insecure-port"] = "0"
argsMap["secure-port"] = strconv.Itoa(cfg.APIServerPort) argsMap["secure-port"] = strconv.Itoa(cfg.APIServerPort)
if cfg.APIServerBindAddress == "" { if cfg.APIServerBindAddress == "" {
argsMap["bind-address"] = getLocalhostIP(cfg.ServiceIPRanges).String() argsMap["bind-address"] = cfg.Loopback(false)
} else { } else {
argsMap["bind-address"] = cfg.APIServerBindAddress argsMap["bind-address"] = cfg.APIServerBindAddress
} }
@ -317,7 +309,7 @@ func cloudControllerManager(ctx context.Context, cfg *config.Control) error {
"authorization-kubeconfig": runtime.KubeConfigCloudController, "authorization-kubeconfig": runtime.KubeConfigCloudController,
"authentication-kubeconfig": runtime.KubeConfigCloudController, "authentication-kubeconfig": runtime.KubeConfigCloudController,
"node-status-update-frequency": "1m0s", "node-status-update-frequency": "1m0s",
"bind-address": getLocalhostIP(cfg.ServiceIPRanges).String(), "bind-address": cfg.Loopback(false),
"port": "0", "port": "0",
} }
if cfg.NoLeaderElect { if cfg.NoLeaderElect {

View File

@ -210,7 +210,7 @@ func (t *TunnelServer) dialBackend(ctx context.Context, addr string) (net.Conn,
if err != nil { if err != nil {
return nil, err return nil, err
} }
loopback := t.config.Loopback() loopback := t.config.Loopback(true)
var nodeName string var nodeName string
var toKubelet, useTunnel bool var toKubelet, useTunnel bool

View File

@ -653,7 +653,7 @@ func getEndpoints(control *config.Control) []string {
if len(runtime.EtcdConfig.Endpoints) > 0 { if len(runtime.EtcdConfig.Endpoints) > 0 {
return runtime.EtcdConfig.Endpoints 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 // 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 // During cluster reset/restore, we only listen on loopback to avoid having peers
// connect mid-process. // connect mid-process.
func (e *ETCD) listenPeerURLs(reset bool) string { 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 { if !reset {
peerURLs += "," + e.peerURL() 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 // During cluster reset/restore, we only listen on loopback to avoid having the apiserver
// connect mid-process. // connect mid-process.
func (e *ETCD) listenClientURLs(reset bool) string { 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 { if !reset {
clientURLs += "," + e.clientURL() 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. // listenMetricsURLs returns a list of URLs to bind to for metrics connections.
func (e *ETCD) listenMetricsURLs(reset bool) string { 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 { if !reset && e.config.EtcdExposeMetrics {
metricsURLs += "," + fmt.Sprintf("http://%s", net.JoinHostPort(e.address, "2381")) metricsURLs += "," + fmt.Sprintf("http://%s", net.JoinHostPort(e.address, "2381"))
} }

View File

@ -337,18 +337,18 @@ func printTokens(config *config.Control) error {
} }
if len(nodeFile) > 0 { 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 return nil
} }
func writeKubeConfig(certs string, config *Config) error { func writeKubeConfig(certs string, config *Config) error {
ip := config.ControlConfig.BindAddressOrLoopback(false) ip := config.ControlConfig.BindAddressOrLoopback(false, true)
port := config.ControlConfig.HTTPSPort port := config.ControlConfig.HTTPSPort
// on servers without a local apiserver, tunnel access via the loadbalancer // on servers without a local apiserver, tunnel access via the loadbalancer
if config.ControlConfig.DisableAPIServer { if config.ControlConfig.DisableAPIServer {
ip = config.ControlConfig.Loopback() ip = config.ControlConfig.Loopback(true)
port = config.ControlConfig.APIServerPort port = config.ControlConfig.APIServerPort
} }
url := fmt.Sprintf("https://%s:%d", ip, port) url := fmt.Sprintf("https://%s:%d", ip, port)