Change:
return []net.Interface{p2pIntf}, nil } <ins> // Interface with link locals and loopback interface with global addresses type linkLocalLoopbackNetworkInterface struct { } func (_ linkLocalLoopbackNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) { if intfName == LoopbackInterfaceName { return &loopbackIntf, nil } return &upIntf, nil } func (_ linkLocalLoopbackNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) { var ifat []net.Addr ifat = []net.Addr{addrStruct{val: "169.254.162.166/16"}, addrStruct{val: "fe80::200/10"}} if intf.Name == LoopbackInterfaceName { ifat = []net.Addr{addrStruct{val: "::1/128"}, addrStruct{val: "127.0.0.1/8"}, // global addresses on loopback interface addrStruct{val: "10.1.1.1/32"}, addrStruct{val: "fd00:1:1::1/128"}} } return ifat, nil } func (_ linkLocalLoopbackNetworkInterface) Interfaces() ([]net.Interface, error) { return []net.Interface{upIntf, loopbackIntf}, nil } // Interface and loopback interface with global addresses type globalsNetworkInterface struct { } func (_ globalsNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) { if intfName == LoopbackInterfaceName { return &loopbackIntf, nil } return &upIntf, nil } func (_ globalsNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) { var ifat []net.Addr ifat = []net.Addr{addrStruct{val: "169.254.162.166/16"}, addrStruct{val: "fe80::200/10"}, addrStruct{val: "192.168.1.1/31"}, addrStruct{val: "fd00::200/127"}} if intf.Name == LoopbackInterfaceName { ifat = []net.Addr{addrStruct{val: "::1/128"}, addrStruct{val: "127.0.0.1/8"}, // global addresses on loopback interface addrStruct{val: "10.1.1.1/32"}, addrStruct{val: "fd00:1:1::1/128"}} } return ifat, nil } func (_ globalsNetworkInterface) Interfaces() ([]net.Interface, error) { return []net.Interface{upIntf, loopbackIntf}, nil } </ins> // Unable to get IP addresses for interface type networkInterfaceFailGetAddrs struct { }

Discussion:
What happened: When attempting to kubeadm join a control plane node or worker on a machine with global IPv4 unicast addresses on a loopback address (router to the host w/ BGP Unnumbered), the join fails with the following output: See this issue for details : Also: What you expected to happen: The correct IPv4 address should be selected from the loopback adapter, or we should be able to specify an IPv4 address to use for egress. The IPv6 addresses on the network adapters themselves are only used to establish upstream peering. IPv4 nexthops are fake 169.254.x.x addresses artificially programmed via RFC5549 into the ARP table. How to reproduce it (as minimally and precisely as possible): On a node with the following conditions: Routing to the host with FRR IPv6 link locals on physical network interfaces No IPv4 addresses on physical network interfaces Unicast IPv4 on the loopback adapter IPv4 default route present via RFC5549 Attempt to kubeadm join a node, and it will fail. Anything else we need to know?: We've been patching kubeadm with , which works as expected. There was a fix applied to allow initing control plane nodes w/ bind address 127.0.0.1 which would then select an IPv4 from the loopback, but it doesn't appear to have fixed the joining issues. Pinging and by request on kubeadm issues. Environment: Kubernetes version (use ): 1.17.12 Cloud provider or hardware configuration: baremetal OS (e.g: ): Centos 7 Kernel (e.g. ): 3.10.0-1127.19.1.el7.x86_64 Install tools: kubeadm Network plugin and version (if this is a network-related bug): Calico Others: FRR for peering with routers on physical network interfaces
/sig api-machinery
is defined but we should note the same function is used for the --bind-address of the kube-apiserver. /sig network
/assign
/triage accepted