mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
127.0.0.1-as-advertise-address
This commit is contained in:
parent
90f487190a
commit
fd2c678b1c
@ -123,6 +123,14 @@ func VerifyAPIServerBindAddress(address string) error {
|
||||
if ip == nil {
|
||||
return errors.Errorf("cannot parse IP address: %s", address)
|
||||
}
|
||||
// There are users with network setups where default routes are present, but network interfaces
|
||||
// use only link-local addresses (e.g. as described in RFC5549).
|
||||
// In many cases that matching global unicast IP address can be found on loopback interface,
|
||||
// so kubeadm allows users to specify address=Loopback for handling supporting the scenario above.
|
||||
// Nb. SetAPIEndpointDynamicDefaults will try to translate loopback to a valid address afterwards
|
||||
if ip.IsLoopback() {
|
||||
return nil
|
||||
}
|
||||
if !ip.IsGlobalUnicast() {
|
||||
return errors.Errorf("cannot use %q as the bind address for the API Server", address)
|
||||
}
|
||||
|
@ -161,13 +161,13 @@ func TestVerifyAPIServerBindAddress(t *testing.T) {
|
||||
address: "2001:db8:85a3::8a2e:370:7334",
|
||||
},
|
||||
{
|
||||
name: "invalid address: not a global unicast 0.0.0.0",
|
||||
address: "0.0.0.0",
|
||||
expectedError: true,
|
||||
name: "valid address 127.0.0.1",
|
||||
address: "127.0.0.1",
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "invalid address: not a global unicast 127.0.0.1",
|
||||
address: "127.0.0.1",
|
||||
name: "invalid address: not a global unicast 0.0.0.0",
|
||||
address: "0.0.0.0",
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
|
@ -26,9 +26,10 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||
bootstraputil "k8s.io/cluster-bootstrap/token/util"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
|
||||
@ -112,6 +113,22 @@ func SetAPIEndpointDynamicDefaults(cfg *kubeadmapi.APIEndpoint) error {
|
||||
if addressIP == nil && cfg.AdvertiseAddress != "" {
|
||||
return errors.Errorf("couldn't use \"%s\" as \"apiserver-advertise-address\", must be ipv4 or ipv6 address", cfg.AdvertiseAddress)
|
||||
}
|
||||
|
||||
// kubeadm allows users to specify address=Loopback as a selector for global unicast IP address that can be found on loopback interface.
|
||||
// e.g. This is required for network setups where default routes are present, but network interfaces use only link-local addresses (e.g. as described in RFC5549).
|
||||
if addressIP.IsLoopback() {
|
||||
loopbackIP, err := netutil.ChooseBindAddressForInterface(netutil.LoopbackInterfaceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if loopbackIP != nil {
|
||||
klog.V(4).Infof("Found active IP %v on loopback interface", loopbackIP.String())
|
||||
cfg.AdvertiseAddress = loopbackIP.String()
|
||||
return nil
|
||||
}
|
||||
return errors.New("unable to resolve link-local addresses")
|
||||
}
|
||||
|
||||
// This is the same logic as the API Server uses, except that if no interface is found the address is set to 0.0.0.0, which is invalid and cannot be used
|
||||
// for bootstrapping a cluster.
|
||||
ip, err := ChooseAPIServerBindAddress(addressIP)
|
||||
|
@ -36,6 +36,11 @@ const (
|
||||
familyIPv6 AddressFamily = 6
|
||||
)
|
||||
|
||||
const (
|
||||
// LoopbackInterfaceName is the default name of the loopback interface
|
||||
LoopbackInterfaceName = "lo"
|
||||
)
|
||||
|
||||
const (
|
||||
ipv4RouteFile = "/proc/net/route"
|
||||
ipv6RouteFile = "/proc/net/ipv6_route"
|
||||
@ -414,3 +419,21 @@ func ChooseBindAddress(bindAddress net.IP) (net.IP, error) {
|
||||
}
|
||||
return bindAddress, nil
|
||||
}
|
||||
|
||||
// ChooseBindAddressForInterface choose a global IP for a specific interface, with priority given to IPv4.
|
||||
// This is required in case of network setups where default routes are present, but network
|
||||
// interfaces use only link-local addresses (e.g. as described in RFC5549).
|
||||
// e.g when using BGP to announce a host IP over link-local ip addresses and this ip address is attached to the lo interface.
|
||||
func ChooseBindAddressForInterface(intfName string) (net.IP, error) {
|
||||
var nw networkInterfacer = networkInterface{}
|
||||
for _, family := range []AddressFamily{familyIPv4, familyIPv6} {
|
||||
ip, err := getIPFromInterface(intfName, family, nw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ip != nil {
|
||||
return ip, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("unable to select an IP from %s network interface", intfName)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user