diff --git a/cmd/kubeadm/app/util/apiclient/wait.go b/cmd/kubeadm/app/util/apiclient/wait.go index a2ed1f2b03d..eef5e1985db 100644 --- a/cmd/kubeadm/app/util/apiclient/wait.go +++ b/cmd/kubeadm/app/util/apiclient/wait.go @@ -39,7 +39,7 @@ import ( // Waiter is an interface for waiting for criteria in Kubernetes to happen type Waiter interface { - // WaitForControlPlaneComponents waits for all control plane components to report "ok" on /healthz + // WaitForControlPlaneComponents waits for all control plane components to be ready. WaitForControlPlaneComponents(cfg *kubeadmapi.ClusterConfiguration) error // WaitForAPI waits for the API Server's /healthz endpoint to become "ok" // TODO: remove WaitForAPI once WaitForAllControlPlaneComponents goes GA: @@ -81,31 +81,58 @@ type controlPlaneComponent struct { url string } +const ( + // TODO: switch to /livez once all components support it + // and delete the endpointHealthz constant. + // https://github.com/kubernetes/kubernetes/issues/118158 + endpointHealthz = "healthz" + endpointLivez = "livez" +) + // getControlPlaneComponents takes a ClusterConfiguration and returns a slice of -// control plane components and their secure ports. +// control plane components and their health check URLs. func getControlPlaneComponents(cfg *kubeadmapi.ClusterConfiguration) []controlPlaneComponent { - portArg := "secure-port" + const ( + portArg = "secure-port" + addressArg = "bind-address" + defaultAddress = "127.0.0.1" + ) + portAPIServer, idx := kubeadmapi.GetArgValue(cfg.APIServer.ExtraArgs, portArg, -1) if idx == -1 { - portAPIServer = "6443" + portAPIServer = fmt.Sprintf("%d", constants.KubeAPIServerPort) } portKCM, idx := kubeadmapi.GetArgValue(cfg.ControllerManager.ExtraArgs, portArg, -1) if idx == -1 { - portKCM = "10257" + portKCM = fmt.Sprintf("%d", constants.KubeControllerManagerPort) } portScheduler, idx := kubeadmapi.GetArgValue(cfg.Scheduler.ExtraArgs, portArg, -1) if idx == -1 { - portScheduler = "10259" + portScheduler = fmt.Sprintf("%d", constants.KubeSchedulerPort) } - urlFormat := "https://127.0.0.1:%s/healthz" + + addressAPIServer, idx := kubeadmapi.GetArgValue(cfg.APIServer.ExtraArgs, addressArg, -1) + if idx == -1 { + addressAPIServer = defaultAddress + } + addressKCM, idx := kubeadmapi.GetArgValue(cfg.ControllerManager.ExtraArgs, addressArg, -1) + if idx == -1 { + addressKCM = defaultAddress + } + addressScheduler, idx := kubeadmapi.GetArgValue(cfg.Scheduler.ExtraArgs, addressArg, -1) + if idx == -1 { + addressScheduler = defaultAddress + } + + urlFormat := "https://%s:%s/%s" return []controlPlaneComponent{ - {name: "kube-apiserver", url: fmt.Sprintf(urlFormat, portAPIServer)}, - {name: "kube-controller-manager", url: fmt.Sprintf(urlFormat, portKCM)}, - {name: "kube-scheduler", url: fmt.Sprintf(urlFormat, portScheduler)}, + {name: "kube-apiserver", url: fmt.Sprintf(urlFormat, addressAPIServer, portAPIServer, endpointLivez)}, + {name: "kube-controller-manager", url: fmt.Sprintf(urlFormat, addressKCM, portKCM, endpointHealthz)}, + {name: "kube-scheduler", url: fmt.Sprintf(urlFormat, addressScheduler, portScheduler, endpointLivez)}, } } -// WaitForControlPlaneComponents waits for all control plane components to report "ok" on /healthz +// WaitForControlPlaneComponents waits for all control plane components to report "ok". func (w *KubeWaiter) WaitForControlPlaneComponents(cfg *kubeadmapi.ClusterConfiguration) error { fmt.Printf("[control-plane-check] Waiting for healthy control plane components."+ " This can take up to %v\n", w.timeout) @@ -133,7 +160,7 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(cfg *kubeadmapi.ClusterConfig true, func(ctx context.Context) (bool, error) { resp, err := client.Get(comp.url) if err != nil { - lastError = errors.WithMessagef(err, "%s /healthz check failed", comp.name) + lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, comp.url) return false, nil } @@ -141,7 +168,8 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(cfg *kubeadmapi.ClusterConfig _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { - lastError = errors.Errorf("%s /healthz check failed with status: %d", comp.name, resp.StatusCode) + lastError = errors.Errorf("%s check failed at %s with status: %d", + comp.name, comp.url, resp.StatusCode) return false, nil } diff --git a/cmd/kubeadm/app/util/apiclient/wait_test.go b/cmd/kubeadm/app/util/apiclient/wait_test.go index a5e50c41af0..2d6441d11cd 100644 --- a/cmd/kubeadm/app/util/apiclient/wait_test.go +++ b/cmd/kubeadm/app/util/apiclient/wait_test.go @@ -17,6 +17,7 @@ limitations under the License. package apiclient import ( + "fmt" "reflect" "testing" @@ -30,39 +31,42 @@ func TestGetControlPlaneComponents(t *testing.T) { expected []controlPlaneComponent }{ { - name: "port values from config", + name: "port and addresses from config", cfg: &kubeadmapi.ClusterConfiguration{ APIServer: kubeadmapi.APIServer{ ControlPlaneComponent: kubeadmapi.ControlPlaneComponent{ ExtraArgs: []kubeadmapi.Arg{ {Name: "secure-port", Value: "1111"}, + {Name: "bind-address", Value: "0.0.0.0"}, }, }, }, ControllerManager: kubeadmapi.ControlPlaneComponent{ ExtraArgs: []kubeadmapi.Arg{ {Name: "secure-port", Value: "2222"}, + {Name: "bind-address", Value: "0.0.0.0"}, }, }, Scheduler: kubeadmapi.ControlPlaneComponent{ ExtraArgs: []kubeadmapi.Arg{ {Name: "secure-port", Value: "3333"}, + {Name: "bind-address", Value: "0.0.0.0"}, }, }, }, expected: []controlPlaneComponent{ - {name: "kube-apiserver", url: "https://127.0.0.1:1111/healthz"}, - {name: "kube-controller-manager", url: "https://127.0.0.1:2222/healthz"}, - {name: "kube-scheduler", url: "https://127.0.0.1:3333/healthz"}, + {name: "kube-apiserver", url: fmt.Sprintf("https://0.0.0.0:1111/%s", endpointLivez)}, + {name: "kube-controller-manager", url: fmt.Sprintf("https://0.0.0.0:2222/%s", endpointHealthz)}, + {name: "kube-scheduler", url: fmt.Sprintf("https://0.0.0.0:3333/%s", endpointLivez)}, }, }, { - name: "default ports", + name: "default ports and addresses", cfg: &kubeadmapi.ClusterConfiguration{}, expected: []controlPlaneComponent{ - {name: "kube-apiserver", url: "https://127.0.0.1:6443/healthz"}, - {name: "kube-controller-manager", url: "https://127.0.0.1:10257/healthz"}, - {name: "kube-scheduler", url: "https://127.0.0.1:10259/healthz"}, + {name: "kube-apiserver", url: fmt.Sprintf("https://127.0.0.1:6443/%s", endpointLivez)}, + {name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:10257/%s", endpointHealthz)}, + {name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:10259/%s", endpointLivez)}, }, }, }