From ab02cda16830a8eb0c9f43eca0334bb79f4ed6f4 Mon Sep 17 00:00:00 2001 From: HirazawaUi <695097494plus@gmail.com> Date: Fri, 7 Feb 2025 20:51:52 +0800 Subject: [PATCH] make error consistent --- .../app/cmd/phases/init/waitcontrolplane.go | 43 ++----------------- cmd/kubeadm/app/cmd/phases/join/kubelet.go | 24 ++--------- .../app/cmd/phases/join/waitcontrolplane.go | 3 +- cmd/kubeadm/app/phases/kubelet/kubelet.go | 1 - cmd/kubeadm/app/util/apiclient/wait.go | 39 +++++++++++++++++ 5 files changed, 49 insertions(+), 61 deletions(-) diff --git a/cmd/kubeadm/app/cmd/phases/init/waitcontrolplane.go b/cmd/kubeadm/app/cmd/phases/init/waitcontrolplane.go index f6dad0ce0cb..1957a0e58ad 100644 --- a/cmd/kubeadm/app/cmd/phases/init/waitcontrolplane.go +++ b/cmd/kubeadm/app/cmd/phases/init/waitcontrolplane.go @@ -19,10 +19,8 @@ package phases import ( "fmt" "io" - "text/template" "time" - "github.com/lithammer/dedent" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" @@ -38,28 +36,6 @@ import ( staticpodutil "k8s.io/kubernetes/cmd/kubeadm/app/util/staticpod" ) -var ( - kubeletFailTempl = template.Must(template.New("init").Parse(dedent.Dedent(` - Unfortunately, an error has occurred: - {{ .Error }} - - This error is likely caused by: - - The kubelet is not running - - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled) - - If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands: - - 'systemctl status kubelet' - - 'journalctl -xeu kubelet' - - Additionally, a control plane component may have crashed or exited when started by the container runtime. - To troubleshoot, list all containers using your preferred container runtimes CLI. - Here is one example how you may list all running Kubernetes containers by using crictl: - - 'crictl --runtime-endpoint {{ .Socket }} ps -a | grep kube | grep -v pause' - Once you have found the failing container, you can inspect its logs with: - - 'crictl --runtime-endpoint {{ .Socket }} logs CONTAINERID' - `))) -) - // NewWaitControlPlanePhase is a hidden phase that runs after the control-plane and etcd phases func NewWaitControlPlanePhase() workflow.Phase { phase := workflow.Phase{ @@ -102,19 +78,6 @@ func runWaitControlPlanePhase(c workflow.RunData) error { " from directory %q\n", data.ManifestDir()) - handleError := func(err error) error { - context := struct { - Error string - Socket string - }{ - Error: fmt.Sprintf("%v", err), - Socket: data.Cfg().NodeRegistration.CRISocket, - } - - kubeletFailTempl.Execute(data.OutputWriter(), context) - return errors.New("could not initialize a Kubernetes cluster") - } - waiter.SetTimeout(data.Cfg().Timeouts.KubeletHealthCheck.Duration) kubeletConfig := data.Cfg().ClusterConfiguration.ComponentConfigs[componentconfigs.KubeletGroup].Get() kubeletConfigTyped, ok := kubeletConfig.(*kubeletconfig.KubeletConfiguration) @@ -122,7 +85,8 @@ func runWaitControlPlanePhase(c workflow.RunData) error { return errors.New("could not convert the KubeletConfiguration to a typed object") } if err := waiter.WaitForKubelet(kubeletConfigTyped.HealthzBindAddress, *kubeletConfigTyped.HealthzPort); err != nil { - return handleError(err) + apiclient.PrintKubeletErrorHelpScreen(data.OutputWriter()) + return errors.Wrap(err, "failed while waiting for the kubelet to start") } var podMap map[string]*v1.Pod @@ -138,7 +102,8 @@ func runWaitControlPlanePhase(c workflow.RunData) error { err = waiter.WaitForAPI() } if err != nil { - return handleError(err) + apiclient.PrintControlPlaneErrorHelpScreen(data.OutputWriter(), data.Cfg().NodeRegistration.CRISocket) + return errors.Wrap(err, "failed while waiting for the control plane to start") } return nil diff --git a/cmd/kubeadm/app/cmd/phases/join/kubelet.go b/cmd/kubeadm/app/cmd/phases/join/kubelet.go index d34129ac98c..46934aebac0 100644 --- a/cmd/kubeadm/app/cmd/phases/join/kubelet.go +++ b/cmd/kubeadm/app/cmd/phases/join/kubelet.go @@ -23,7 +23,6 @@ import ( "path/filepath" "time" - "github.com/lithammer/dedent" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" @@ -50,21 +49,6 @@ import ( kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig" ) -var ( - kubeadmJoinFailMsg = dedent.Dedent(` - Unfortunately, an error has occurred: - %v - - This error is likely caused by: - - The kubelet is not running - - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled) - - If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands: - - 'systemctl status kubelet' - - 'journalctl -xeu kubelet' - `) -) - // NewKubeletStartPhase creates a kubeadm workflow phase that start kubelet on a node. func NewKubeletStartPhase() workflow.Phase { return workflow.Phase{ @@ -328,13 +312,13 @@ func runKubeletWaitBootstrapPhase(c workflow.RunData) (returnErr error) { return errors.New("could not convert the KubeletConfiguration to a typed object") } if err := waiter.WaitForKubelet(kubeletConfigTyped.HealthzBindAddress, *kubeletConfigTyped.HealthzPort); err != nil { - fmt.Printf(kubeadmJoinFailMsg, err) - return err + apiclient.PrintKubeletErrorHelpScreen(data.OutputWriter()) + return errors.Wrap(err, "failed while waiting for the kubelet to start") } if err := waitForTLSBootstrappedClient(cfg.Timeouts.TLSBootstrap.Duration); err != nil { - fmt.Printf(kubeadmJoinFailMsg, err) - return err + apiclient.PrintKubeletErrorHelpScreen(data.OutputWriter()) + return errors.Wrap(err, "failed while waiting for TLS bootstrap") } // When we know the /etc/kubernetes/kubelet.conf file is available, get the client diff --git a/cmd/kubeadm/app/cmd/phases/join/waitcontrolplane.go b/cmd/kubeadm/app/cmd/phases/join/waitcontrolplane.go index d3ae5bfacf2..e126aa6c8ff 100644 --- a/cmd/kubeadm/app/cmd/phases/join/waitcontrolplane.go +++ b/cmd/kubeadm/app/cmd/phases/join/waitcontrolplane.go @@ -80,7 +80,8 @@ func runWaitControlPlanePhase(c workflow.RunData) error { } if err = waiter.WaitForControlPlaneComponents(pods, data.Cfg().ControlPlane.LocalAPIEndpoint.AdvertiseAddress); err != nil { - return err + apiclient.PrintControlPlaneErrorHelpScreen(data.OutputWriter(), data.Cfg().NodeRegistration.CRISocket) + return errors.Wrap(err, "failed while waiting for the control plane to start") } return nil diff --git a/cmd/kubeadm/app/phases/kubelet/kubelet.go b/cmd/kubeadm/app/phases/kubelet/kubelet.go index 18c4f612b91..791c43a269b 100644 --- a/cmd/kubeadm/app/phases/kubelet/kubelet.go +++ b/cmd/kubeadm/app/phases/kubelet/kubelet.go @@ -18,7 +18,6 @@ package kubelet import ( "fmt" - "k8s.io/klog/v2" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" diff --git a/cmd/kubeadm/app/util/apiclient/wait.go b/cmd/kubeadm/app/util/apiclient/wait.go index dd8c77f1b8c..3b312fc122a 100644 --- a/cmd/kubeadm/app/util/apiclient/wait.go +++ b/cmd/kubeadm/app/util/apiclient/wait.go @@ -24,8 +24,10 @@ import ( "net" "net/http" "strings" + "text/template" "time" + "github.com/lithammer/dedent" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" @@ -52,6 +54,27 @@ const ( argAdvertiseAddress = "advertise-address" ) +var ( + controlPlaneFailTempl = template.Must(template.New("init").Parse(dedent.Dedent(` + A control plane component may have crashed or exited when started by the container runtime. + To troubleshoot, list all containers using your preferred container runtimes CLI. + Here is one example how you may list all running Kubernetes containers by using crictl: + - 'crictl --runtime-endpoint {{ .Socket }} ps -a | grep kube | grep -v pause' + Once you have found the failing container, you can inspect its logs with: + - 'crictl --runtime-endpoint {{ .Socket }} logs CONTAINERID' +`))) + + kubeletFailMsg = dedent.Dedent(` + Unfortunately, an error has occurred, likely caused by: + - The kubelet is not running + - The kubelet is unhealthy due to a misconfiguration of the node in some way (required cgroups disabled) + + If you are on a systemd-powered system, you can try to troubleshoot the error with the following commands: + - 'systemctl status kubelet' + - 'journalctl -xeu kubelet' +`) +) + // Waiter is an interface for waiting for criteria in Kubernetes to happen type Waiter interface { // WaitForControlPlaneComponents waits for all control plane components to be ready. @@ -496,3 +519,19 @@ func getStaticPodSingleHash(client clientset.Interface, nodeName string, compone staticPodHash := staticPod.Annotations["kubernetes.io/config.hash"] return staticPodHash, nil } + +// PrintControlPlaneErrorHelpScreen prints help text on wait ControlPlane components errors. +func PrintControlPlaneErrorHelpScreen(outputWriter io.Writer, criSocket string) { + context := struct { + Socket string + }{ + Socket: criSocket, + } + _ = controlPlaneFailTempl.Execute(outputWriter, context) + fmt.Println("") +} + +// PrintKubeletErrorHelpScreen prints help text on kubelet errors. +func PrintKubeletErrorHelpScreen(outputWriter io.Writer) { + fmt.Fprintln(outputWriter, kubeletFailMsg) +}