kubeadm: probe address for unspecified ips

kubeadm deploys the apiserver, controller-manager and the scheduler
using liveness probes.
The bind-address option is used to configure the probe address, in
case this is configured with an unspecified address, the probe
will fail. When using an unspecified address the probe host field is
left empty, otherwise the bind-address is used.
This commit is contained in:
Antonio Ojea 2019-12-20 22:42:37 +01:00
parent 7dc6c94395
commit c0bc36c12e
2 changed files with 122 additions and 3 deletions

View File

@ -244,7 +244,7 @@ func GetAPIServerProbeAddress(endpoint *kubeadmapi.APIEndpoint) string {
// probes do not support the Downward API we cannot dynamically set the advertise address to
// the node's IP. The only option then is to use localhost.
if endpoint != nil && endpoint.AdvertiseAddress != "" {
return endpoint.AdvertiseAddress
return getProbeAddress(endpoint.AdvertiseAddress)
}
return "127.0.0.1"
@ -253,7 +253,7 @@ func GetAPIServerProbeAddress(endpoint *kubeadmapi.APIEndpoint) string {
// GetControllerManagerProbeAddress returns the kubernetes controller manager probe address
func GetControllerManagerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) string {
if addr, exists := cfg.ControllerManager.ExtraArgs[kubeControllerManagerBindAddressArg]; exists {
return addr
return getProbeAddress(addr)
}
return "127.0.0.1"
}
@ -261,7 +261,7 @@ func GetControllerManagerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) stri
// GetSchedulerProbeAddress returns the kubernetes scheduler probe address
func GetSchedulerProbeAddress(cfg *kubeadmapi.ClusterConfiguration) string {
if addr, exists := cfg.Scheduler.ExtraArgs[kubeSchedulerBindAddressArg]; exists {
return addr
return getProbeAddress(addr)
}
return "127.0.0.1"
}
@ -321,3 +321,16 @@ func ManifestFilesAreEqual(path1, path2 string) (bool, error) {
return bytes.Equal(content1, content2), nil
}
// getProbeAddress returns a valid probe address.
// Kubeadm uses the bind-address to configure the probe address. It's common to use the
// unspecified address "0.0.0.0" or "::" as bind-address when we want to listen in all interfaces,
// however this address can't be used as probe #86504.
// If the address is an unspecified address getProbeAddress returns empty,
// that means that kubelet will use the PodIP as probe address.
func getProbeAddress(addr string) string {
if addr == "0.0.0.0" || addr == "::" {
return ""
}
return addr
}

View File

@ -72,6 +72,20 @@ func TestGetAPIServerProbeAddress(t *testing.T) {
},
expected: "2001:abcd:bcda::1",
},
{
desc: "filled in 0.0.0.0 AdvertiseAddress endpoint returns empty",
endpoint: &kubeadmapi.APIEndpoint{
AdvertiseAddress: "0.0.0.0",
},
expected: "",
},
{
desc: "filled in :: AdvertiseAddress endpoint returns empty",
endpoint: &kubeadmapi.APIEndpoint{
AdvertiseAddress: "::",
},
expected: "",
},
}
for _, test := range tests {
@ -121,6 +135,28 @@ func TestGetControllerManagerProbeAddress(t *testing.T) {
},
expected: "2001:abcd:bcda::1",
},
{
desc: "setting controller manager extra address arg to 0.0.0.0 returns empty",
cfg: &kubeadmapi.ClusterConfiguration{
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{
kubeControllerManagerBindAddressArg: "0.0.0.0",
},
},
},
expected: "",
},
{
desc: "setting controller manager extra ipv6 address arg to :: returns empty",
cfg: &kubeadmapi.ClusterConfiguration{
ControllerManager: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{
kubeControllerManagerBindAddressArg: "::",
},
},
},
expected: "",
},
}
for _, test := range tests {
@ -133,6 +169,76 @@ func TestGetControllerManagerProbeAddress(t *testing.T) {
}
}
func TestGetSchedulerProbeAddress(t *testing.T) {
tests := []struct {
desc string
cfg *kubeadmapi.ClusterConfiguration
expected string
}{
{
desc: "no scheduler extra args leads to 127.0.0.1 being used",
cfg: &kubeadmapi.ClusterConfiguration{
Scheduler: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{},
},
},
expected: "127.0.0.1",
},
{
desc: "setting scheduler extra address arg to something acknowledges it",
cfg: &kubeadmapi.ClusterConfiguration{
Scheduler: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{
kubeSchedulerBindAddressArg: "10.10.10.10",
},
},
},
expected: "10.10.10.10",
},
{
desc: "setting scheduler extra ipv6 address arg to something acknowledges it",
cfg: &kubeadmapi.ClusterConfiguration{
Scheduler: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{
kubeSchedulerBindAddressArg: "2001:abcd:bcda::1",
},
},
},
expected: "2001:abcd:bcda::1",
},
{
desc: "setting scheduler extra ipv6 address arg to 0.0.0.0 returns empty",
cfg: &kubeadmapi.ClusterConfiguration{
Scheduler: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{
kubeSchedulerBindAddressArg: "0.0.0.0",
},
},
},
expected: "",
},
{
desc: "setting scheduler extra ipv6 address arg to :: returns empty",
cfg: &kubeadmapi.ClusterConfiguration{
Scheduler: kubeadmapi.ControlPlaneComponent{
ExtraArgs: map[string]string{
kubeSchedulerBindAddressArg: "::",
},
},
},
expected: "",
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
actual := GetSchedulerProbeAddress(test.cfg)
if actual != test.expected {
t.Errorf("Unexpected result from GetSchedulerProbeAddress:\n\texpected: %s\n\tactual: %s", test.expected, actual)
}
})
}
}
func TestGetEtcdProbeEndpoint(t *testing.T) {
var tests = []struct {
name string