mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #131036 from neolit123/1.33-fix-anonymous-auth-wait-all-cp-comp
kubeadm: fix WaitForAllControlPlaneComponents with anonymous auth
This commit is contained in:
commit
49b85354fe
@ -67,7 +67,12 @@ func runWaitControlPlanePhase(c workflow.RunData) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
waiter, err := newControlPlaneWaiter(data.DryRun(), 0, nil, data.OutputWriter())
|
client, err := data.Client()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
waiter, err := newControlPlaneWaiter(data.DryRun(), 0, client, data.OutputWriter())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "error creating waiter")
|
return errors.Wrap(err, "error creating waiter")
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,9 @@ func NewKubeWaiter(client clientset.Interface, timeout time.Duration, writer io.
|
|||||||
// controlPlaneComponent holds a component name and an URL
|
// controlPlaneComponent holds a component name and an URL
|
||||||
// on which to perform health checks.
|
// on which to perform health checks.
|
||||||
type controlPlaneComponent struct {
|
type controlPlaneComponent struct {
|
||||||
name string
|
name string
|
||||||
url string
|
addressPort string
|
||||||
|
endpoint string
|
||||||
}
|
}
|
||||||
|
|
||||||
// getControlPlaneComponentAddressAndPort parses the command in a static Pod
|
// getControlPlaneComponentAddressAndPort parses the command in a static Pod
|
||||||
@ -181,7 +182,6 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
|
|
||||||
type componentConfig struct {
|
type componentConfig struct {
|
||||||
name string
|
name string
|
||||||
podKey string
|
|
||||||
args []string
|
args []string
|
||||||
defaultAddr string
|
defaultAddr string
|
||||||
defaultPort string
|
defaultPort string
|
||||||
@ -190,24 +190,21 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
|
|
||||||
components := []componentConfig{
|
components := []componentConfig{
|
||||||
{
|
{
|
||||||
name: "kube-apiserver",
|
name: constants.KubeAPIServer,
|
||||||
podKey: constants.KubeAPIServer,
|
|
||||||
args: []string{argAdvertiseAddress, argPort},
|
args: []string{argAdvertiseAddress, argPort},
|
||||||
defaultAddr: addressAPIServer,
|
defaultAddr: addressAPIServer,
|
||||||
defaultPort: portAPIServer,
|
defaultPort: portAPIServer,
|
||||||
endpoint: endpointLivez,
|
endpoint: endpointLivez,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "kube-controller-manager",
|
name: constants.KubeControllerManager,
|
||||||
podKey: constants.KubeControllerManager,
|
|
||||||
args: []string{argBindAddress, argPort},
|
args: []string{argBindAddress, argPort},
|
||||||
defaultAddr: addressKCM,
|
defaultAddr: addressKCM,
|
||||||
defaultPort: portKCM,
|
defaultPort: portKCM,
|
||||||
endpoint: endpointHealthz,
|
endpoint: endpointHealthz,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "kube-scheduler",
|
name: constants.KubeScheduler,
|
||||||
podKey: constants.KubeScheduler,
|
|
||||||
args: []string{argBindAddress, argPort},
|
args: []string{argBindAddress, argPort},
|
||||||
defaultAddr: addressScheduler,
|
defaultAddr: addressScheduler,
|
||||||
defaultPort: portScheduler,
|
defaultPort: portScheduler,
|
||||||
@ -219,8 +216,8 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
address, port := component.defaultAddr, component.defaultPort
|
address, port := component.defaultAddr, component.defaultPort
|
||||||
|
|
||||||
values, err := getControlPlaneComponentAddressAndPort(
|
values, err := getControlPlaneComponentAddressAndPort(
|
||||||
podMap[component.podKey],
|
podMap[component.name],
|
||||||
component.podKey,
|
component.name,
|
||||||
component.args,
|
component.args,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -235,8 +232,9 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, controlPlaneComponent{
|
result = append(result, controlPlaneComponent{
|
||||||
name: component.name,
|
name: component.name,
|
||||||
url: fmt.Sprintf("https://%s/%s", net.JoinHostPort(address, port), component.endpoint),
|
addressPort: net.JoinHostPort(address, port),
|
||||||
|
endpoint: component.endpoint,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +246,7 @@ func getControlPlaneComponents(podMap map[string]*v1.Pod, addressAPIServer strin
|
|||||||
|
|
||||||
// WaitForControlPlaneComponents waits for all control plane components to report "ok".
|
// WaitForControlPlaneComponents waits for all control plane components to report "ok".
|
||||||
func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, apiSeverAddress string) error {
|
func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, apiSeverAddress string) error {
|
||||||
fmt.Printf("[control-plane-check] Waiting for healthy control plane components."+
|
_, _ = fmt.Fprintf(w.writer, "[control-plane-check] Waiting for healthy control plane components."+
|
||||||
" This can take up to %v\n", w.timeout)
|
" This can take up to %v\n", w.timeout)
|
||||||
|
|
||||||
components, err := getControlPlaneComponents(podMap, apiSeverAddress)
|
components, err := getControlPlaneComponents(podMap, apiSeverAddress)
|
||||||
@ -260,7 +258,8 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
|||||||
errChan := make(chan error, len(components))
|
errChan := make(chan error, len(components))
|
||||||
|
|
||||||
for _, comp := range components {
|
for _, comp := range components {
|
||||||
fmt.Printf("[control-plane-check] Checking %s at %s\n", comp.name, comp.url)
|
url := fmt.Sprintf("https://%s/%s", comp.addressPort, comp.endpoint)
|
||||||
|
_, _ = fmt.Fprintf(w.writer, "[control-plane-check] Checking %s at %s\n", comp.name, url)
|
||||||
|
|
||||||
go func(comp controlPlaneComponent) {
|
go func(comp controlPlaneComponent) {
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
@ -268,6 +267,7 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
|||||||
}
|
}
|
||||||
client := &http.Client{Transport: tr}
|
client := &http.Client{Transport: tr}
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
statusCode := 0
|
||||||
var lastError error
|
var lastError error
|
||||||
|
|
||||||
err := wait.PollUntilContextTimeout(
|
err := wait.PollUntilContextTimeout(
|
||||||
@ -275,29 +275,41 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
|||||||
constants.KubernetesAPICallRetryInterval,
|
constants.KubernetesAPICallRetryInterval,
|
||||||
w.timeout,
|
w.timeout,
|
||||||
true, func(ctx context.Context) (bool, error) {
|
true, func(ctx context.Context) (bool, error) {
|
||||||
resp, err := client.Get(comp.url)
|
// The kube-apiserver check should use the client defined in the waiter
|
||||||
if err != nil {
|
// or otherwise the regular http client can fail when anonymous auth is enabled.
|
||||||
lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, comp.url)
|
if comp.name == constants.KubeAPIServer {
|
||||||
return false, nil
|
result := w.client.Discovery().RESTClient().
|
||||||
|
Get().AbsPath(comp.endpoint).Do(ctx).StatusCode(&statusCode)
|
||||||
|
if err := result.Error(); err != nil {
|
||||||
|
lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, url)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resp, err := client.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
lastError = errors.WithMessagef(err, "%s check failed at %s", comp.name, url)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = resp.Body.Close()
|
||||||
|
}()
|
||||||
|
statusCode = resp.StatusCode
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
if statusCode != http.StatusOK {
|
||||||
_ = resp.Body.Close()
|
|
||||||
}()
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
lastError = errors.Errorf("%s check failed at %s with status: %d",
|
lastError = errors.Errorf("%s check failed at %s with status: %d",
|
||||||
comp.name, comp.url, resp.StatusCode)
|
comp.name, url, statusCode)
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[control-plane-check] %s is not healthy after %v\n", comp.name, time.Since(start))
|
_, _ = fmt.Fprintf(w.writer, "[control-plane-check] %s is not healthy after %v\n", comp.name, time.Since(start))
|
||||||
errChan <- lastError
|
errChan <- lastError
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("[control-plane-check] %s is healthy after %v\n", comp.name, time.Since(start))
|
_, _ = fmt.Fprintf(w.writer, "[control-plane-check] %s is healthy after %v\n", comp.name, time.Since(start))
|
||||||
errChan <- nil
|
errChan <- nil
|
||||||
}(comp)
|
}(comp)
|
||||||
}
|
}
|
||||||
@ -312,7 +324,7 @@ func (w *KubeWaiter) WaitForControlPlaneComponents(podMap map[string]*v1.Pod, ap
|
|||||||
|
|
||||||
// WaitForAPI waits for the API Server's /healthz endpoint to report "ok"
|
// WaitForAPI waits for the API Server's /healthz endpoint to report "ok"
|
||||||
func (w *KubeWaiter) WaitForAPI() error {
|
func (w *KubeWaiter) WaitForAPI() error {
|
||||||
fmt.Printf("[api-check] Waiting for a healthy API server. This can take up to %v\n", w.timeout)
|
_, _ = fmt.Fprintf(w.writer, "[api-check] Waiting for a healthy API server. This can take up to %v\n", w.timeout)
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
err := wait.PollUntilContextTimeout(
|
err := wait.PollUntilContextTimeout(
|
||||||
@ -328,11 +340,11 @@ func (w *KubeWaiter) WaitForAPI() error {
|
|||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[api-check] The API server is not healthy after %v\n", time.Since(start))
|
_, _ = fmt.Fprintf(w.writer, "[api-check] The API server is not healthy after %v\n", time.Since(start))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[api-check] The API server is healthy after %v\n", time.Since(start))
|
_, _ = fmt.Fprintf(w.writer, "[api-check] The API server is healthy after %v\n", time.Since(start))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,12 +359,12 @@ func (w *KubeWaiter) WaitForPodsWithLabel(kvLabel string) error {
|
|||||||
listOpts := metav1.ListOptions{LabelSelector: kvLabel}
|
listOpts := metav1.ListOptions{LabelSelector: kvLabel}
|
||||||
pods, err := w.client.CoreV1().Pods(metav1.NamespaceSystem).List(context.TODO(), listOpts)
|
pods, err := w.client.CoreV1().Pods(metav1.NamespaceSystem).List(context.TODO(), listOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(w.writer, "[apiclient] Error getting Pods with label selector %q [%v]\n", kvLabel, err)
|
_, _ = fmt.Fprintf(w.writer, "[apiclient] Error getting Pods with label selector %q [%v]\n", kvLabel, err)
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if lastKnownPodNumber != len(pods.Items) {
|
if lastKnownPodNumber != len(pods.Items) {
|
||||||
fmt.Fprintf(w.writer, "[apiclient] Found %d Pods for label selector %s\n", len(pods.Items), kvLabel)
|
_, _ = fmt.Fprintf(w.writer, "[apiclient] Found %d Pods for label selector %s\n", len(pods.Items), kvLabel)
|
||||||
lastKnownPodNumber = len(pods.Items)
|
lastKnownPodNumber = len(pods.Items)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,10 +391,10 @@ func (w *KubeWaiter) WaitForKubelet(healthzAddress string, healthzPort int32) er
|
|||||||
)
|
)
|
||||||
|
|
||||||
if healthzPort == 0 {
|
if healthzPort == 0 {
|
||||||
fmt.Println("[kubelet-check] Skipping the kubelet health check because the healthz port is set to 0")
|
_, _ = fmt.Fprintln(w.writer, "[kubelet-check] Skipping the kubelet health check because the healthz port is set to 0")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
fmt.Printf("[kubelet-check] Waiting for a healthy kubelet at %s. This can take up to %v\n",
|
_, _ = fmt.Fprintf(w.writer, "[kubelet-check] Waiting for a healthy kubelet at %s. This can take up to %v\n",
|
||||||
healthzEndpoint, w.timeout)
|
healthzEndpoint, w.timeout)
|
||||||
|
|
||||||
formatError := func(cause string) error {
|
formatError := func(cause string) error {
|
||||||
@ -417,11 +429,11 @@ func (w *KubeWaiter) WaitForKubelet(healthzAddress string, healthzPort int32) er
|
|||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[kubelet-check] The kubelet is not healthy after %v\n", time.Since(start))
|
_, _ = fmt.Fprintf(w.writer, "[kubelet-check] The kubelet is not healthy after %v\n", time.Since(start))
|
||||||
return lastError
|
return lastError
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[kubelet-check] The kubelet is healthy after %v\n", time.Since(start))
|
_, _ = fmt.Fprintf(w.writer, "[kubelet-check] The kubelet is healthy after %v\n", time.Since(start))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,10 +540,10 @@ func PrintControlPlaneErrorHelpScreen(outputWriter io.Writer, criSocket string)
|
|||||||
Socket: criSocket,
|
Socket: criSocket,
|
||||||
}
|
}
|
||||||
_ = controlPlaneFailTempl.Execute(outputWriter, context)
|
_ = controlPlaneFailTempl.Execute(outputWriter, context)
|
||||||
fmt.Println("")
|
_, _ = fmt.Fprintln(outputWriter, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintKubeletErrorHelpScreen prints help text on kubelet errors.
|
// PrintKubeletErrorHelpScreen prints help text on kubelet errors.
|
||||||
func PrintKubeletErrorHelpScreen(outputWriter io.Writer) {
|
func PrintKubeletErrorHelpScreen(outputWriter io.Writer) {
|
||||||
fmt.Fprintln(outputWriter, kubeletFailMsg)
|
_, _ = fmt.Fprintln(outputWriter, kubeletFailMsg)
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
|||||||
return podMap
|
return podMap
|
||||||
},
|
},
|
||||||
expected: []controlPlaneComponent{
|
expected: []controlPlaneComponent{
|
||||||
{name: "kube-apiserver", url: fmt.Sprintf("https://[fd00:1::]:1111/%s", endpointLivez)},
|
{name: "kube-apiserver", addressPort: "[fd00:1::]:1111", endpoint: endpointLivez},
|
||||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:2222/%s", endpointHealthz)},
|
{name: "kube-controller-manager", addressPort: "127.0.0.1:2222", endpoint: endpointHealthz},
|
||||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:3333/%s", endpointLivez)},
|
{name: "kube-scheduler", addressPort: "127.0.0.1:3333", endpoint: endpointLivez},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -106,9 +106,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
|||||||
return podMap
|
return podMap
|
||||||
},
|
},
|
||||||
expected: []controlPlaneComponent{
|
expected: []controlPlaneComponent{
|
||||||
{name: "kube-apiserver", url: fmt.Sprintf("https://[fd00:1::]:1111/%s", endpointLivez)},
|
{name: "kube-apiserver", addressPort: "[fd00:1::]:1111", endpoint: endpointLivez},
|
||||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:2222/%s", endpointHealthz)},
|
{name: "kube-controller-manager", addressPort: "127.0.0.1:2222", endpoint: endpointHealthz},
|
||||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:3333/%s", endpointLivez)},
|
{name: "kube-scheduler", addressPort: "127.0.0.1:3333", endpoint: endpointLivez},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -133,9 +133,9 @@ func TestGetControlPlaneComponents(t *testing.T) {
|
|||||||
return podMap
|
return podMap
|
||||||
},
|
},
|
||||||
expected: []controlPlaneComponent{
|
expected: []controlPlaneComponent{
|
||||||
{name: "kube-apiserver", url: fmt.Sprintf("https://192.168.0.1:6443/%s", endpointLivez)},
|
{name: "kube-apiserver", addressPort: "192.168.0.1:6443", endpoint: endpointLivez},
|
||||||
{name: "kube-controller-manager", url: fmt.Sprintf("https://127.0.0.1:10257/%s", endpointHealthz)},
|
{name: "kube-controller-manager", addressPort: "127.0.0.1:10257", endpoint: endpointHealthz},
|
||||||
{name: "kube-scheduler", url: fmt.Sprintf("https://127.0.0.1:10259/%s", endpointLivez)},
|
{name: "kube-scheduler", addressPort: "127.0.0.1:10259", endpoint: endpointLivez},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user