diff --git a/cmd/deploy.go b/cmd/deploy.go index b997fe4fec46e1fa7bb005626f25194eafe0761a..419916475821300e319e906a404e74cbed3e5332 100755 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -23,9 +23,10 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" wait "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) @@ -51,12 +52,8 @@ func runDeployCmd(cmd *cobra.Command, args []string) error { //todo:部署集群 configPath := filepath.Join(command.RootOptDir, "auth", "kubeconfig") - config, err := clientcmd.BuildConfigFromFlags("", configPath) - if err != nil { - logrus.Errorf("error to load kubeconfig: %v", err) - return err - } - if err := waitForAPIReady(context.Background(), config); err != nil { + if err := checkClusterState(configPath); err != nil { + logrus.Error("Cluster deploy timeout!") return err } return nil @@ -73,20 +70,35 @@ func runDeployCluster() error { return nil } -func waitForAPIReady(ctx context.Context, config *rest.Config) error { +func checkClusterState(kubeconfigPath string) error { + config, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) + if err != nil { + logrus.Errorf("error to load kubeconfig: %v", err) + return err + } client, err := kubernetes.NewForConfig(config) if err != nil { logrus.Errorf("failed to create a kubernetes client: %v", err) return err } - discovery := client.Discovery() + if err := waitForAPIReady(client); err != nil { + return err + } + + if err := waitForPodsRunning(client); err != nil { + return err + } +} +func waitForAPIReady(client *kubernetes.Clientset) error { apiTimeout := 10 * time.Minute + ctx := context.Background() apiContext, cancel := context.WithTimeout(ctx, apiTimeout) logrus.Infof("Waiting up to %v for the Kubernetes API at %s...", apiTimeout, config.Host) defer cancel() + discovery := client.Discovery() wait.Until(func() { version, err := discovery.ServerVersion() if err == nil { @@ -97,10 +109,45 @@ func waitForAPIReady(ctx context.Context, config *rest.Config) error { } }, 2*time.Second, apiContext.Done()) - return waitForPodsRunning(ctx, client) + err = apiContext.Err() + if err != nil && err != context.Canceled { + logrus.Errorf("Failed to waiting for kubernetes API: %v", err) + return err + } + + return nil } -func waitForPodsRunning(ctx context.Context, client *kubernetes.Clientset) error { - //todo: 等待Pods Running +func waitForPodsRunning(client *kubernetes.Clientset) error { + waitDuration := 10 * time.Minute + waitCtx, cancel := context.WithTimeout(context.Background(), waitkDuration) + logrus.Infof("Waiting up to %v for the Kubernetes Pods running ...", waitkDuration) + defer cancel() + + wait.Until(func() { + pods, err := client.CoreV1().Pods("kube-system").List(waitCtx, metav1.ListOptions{}) + if err != nil { + logrus.Errorf("Failed to list Pods: %v", err) + return err + } + allRunning := true + for _, pod := range pods.Items { + if pod.Status.Phase != corev1.PodRunning { + allRunning = false + logrus.Infof("Pod %s is not running. Current phase: %s", pod.Name, pod.Status.Phase) + break + } + } + if allRunning { + logrus.Info("All Pods are running") + cancel() + } + }, 5*time.Second, waitCtx.Done()) + + err := waitCtx.Err() + if err != nil && err != context.Canceled { + logrus.Errorf("Failed to wait for Pods to be running: %v", err) + return err + } return nil }