diff --git a/pkg/scripts/os.go b/pkg/scripts/os.go index 5ccd45ce7..d1a6c208f 100644 --- a/pkg/scripts/os.go +++ b/pkg/scripts/os.go @@ -30,7 +30,9 @@ var migrateToContainerdScriptTemplate = heredoc.Doc(` sudo docker ps -q | xargs sudo docker stop || true sudo docker ps -qa | xargs sudo docker rm || true + {{ if .GENERATE_CONTAINERD_CONFIG -}} {{ template "containerd-config" . }} + {{- end }} {{- /* /var/lib/kubelet/kubeadm-flags.env should be modified by the caller of @@ -42,8 +44,9 @@ var migrateToContainerdScriptTemplate = heredoc.Doc(` sudo systemctl restart kubelet `) -func MigrateToContainerd(insecureRegistry string) (string, error) { +func MigrateToContainerd(insecureRegistry string, generateContainerdConfig bool) (string, error) { return Render(migrateToContainerdScriptTemplate, Data{ - "INSECURE_REGISTRY": insecureRegistry, + "INSECURE_REGISTRY": insecureRegistry, + "GENERATE_CONTAINERD_CONFIG": generateContainerdConfig, }) } diff --git a/pkg/scripts/os_test.go b/pkg/scripts/os_test.go index b73f4376b..c8f24013e 100644 --- a/pkg/scripts/os_test.go +++ b/pkg/scripts/os_test.go @@ -165,23 +165,30 @@ func TestMigrateToContainerd(t *testing.T) { t.Parallel() tests := []struct { - name string - insecureRegistry string - err error + name string + insecureRegistry string + generateContainerdConfig bool + err error }{ { - name: "simple", + name: "simple", + generateContainerdConfig: true, + }, + { + name: "flatcat", + generateContainerdConfig: false, }, { - name: "insecureRegistry", - insecureRegistry: "some.registry", + name: "insecureRegistry", + insecureRegistry: "some.registry", + generateContainerdConfig: true, }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - got, err := MigrateToContainerd(tt.insecureRegistry) + got, err := MigrateToContainerd(tt.insecureRegistry, tt.generateContainerdConfig) if err != tt.err { t.Errorf("MigrateToContainerd() error = %v, wantErr %v", err, tt.err) return diff --git a/pkg/scripts/testdata/TestMigrateToContainerd-flatcat.golden b/pkg/scripts/testdata/TestMigrateToContainerd-flatcat.golden new file mode 100644 index 000000000..35073299b --- /dev/null +++ b/pkg/scripts/testdata/TestMigrateToContainerd-flatcat.golden @@ -0,0 +1,7 @@ +set -xeu pipefail +export "PATH=$PATH:/sbin:/usr/local/bin:/opt/bin" +sudo systemctl stop kubelet +sudo docker ps -q | xargs sudo docker stop || true +sudo docker ps -qa | xargs sudo docker rm || true + +sudo systemctl restart kubelet diff --git a/pkg/tasks/containerd.go b/pkg/tasks/containerd.go index 8965d70b5..f8b2cbbc4 100644 --- a/pkg/tasks/containerd.go +++ b/pkg/tasks/containerd.go @@ -32,6 +32,7 @@ import ( "k8c.io/kubeone/pkg/state" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/wait" ) const ( @@ -117,22 +118,20 @@ func migrateToContainerdTask(s *state.State, node *kubeone.HostConfig, conn ssh. return errors.New("file is not writable") } - err = fw.Truncate(0) - if err != nil { + if err = fw.Truncate(0); err != nil { return err } - _, err = fw.Seek(0, io.SeekStart) - if err != nil { + if _, err = fw.Seek(0, io.SeekStart); err != nil { return err } - _, err = io.Copy(fw, bytes.NewBuffer(buf)) - if err != nil { + if _, err = io.Copy(fw, bytes.NewBuffer(buf)); err != nil { return err } - migrateScript, err := scripts.MigrateToContainerd(s.Cluster.RegistryConfiguration.InsecureRegistryAddress()) + generateContainerdConfig := node.OperatingSystem != kubeone.OperatingSystemNameFlatcar + migrateScript, err := scripts.MigrateToContainerd(s.Cluster.RegistryConfiguration.InsecureRegistryAddress(), generateContainerdConfig) if err != nil { return err } @@ -142,12 +141,44 @@ func migrateToContainerdTask(s *state.State, node *kubeone.HostConfig, conn ssh. return err } - // TODO(kron4eg): replace with better waiting polling - sleepTime := 30 * time.Second - s.Logger.Infof("Waiting %s to ensure main control plane components are up...", sleepTime) - time.Sleep(sleepTime) + s.Logger.Infof("Waiting all pods on %q to became Ready...", node.Hostname) + err = wait.Poll(10*time.Second, 10*time.Minute, func() (bool, error) { + var podsList corev1.PodList - return nil + if perr := s.DynamicClient.List(s.Context, &podsList); perr != nil { + return false, err + } + + for _, pod := range podsList.Items { + if pod.Spec.NodeName != node.Hostname { + continue + } + + if pod.Status.Phase != corev1.PodRunning { + s.Logger.Debugf("Pod %s/%s is not running", pod.Namespace, pod.Name) + return false, nil + } + + for _, podcond := range pod.Status.Conditions { + if podcond.Type == corev1.PodReady && podcond.Status != corev1.ConditionTrue { + s.Logger.Debugf("Pod %s/%s is not ready", pod.Namespace, pod.Name) + return false, nil + } + } + + for _, condstatus := range pod.Status.ContainerStatuses { + if !condstatus.Ready { + s.Logger.Debugf("Container %s in pod %s/%s is not ready", condstatus.Name, pod.Namespace, pod.Name) + return false, nil + } + } + } + + s.Logger.Debugf("All pods on %s Node are ready", node.Hostname) + return true, nil + }) + + return err } func unmarshalKubeletFlags(buf []byte) (map[string]string, error) { diff --git a/pkg/tasks/tasks.go b/pkg/tasks/tasks.go index 0be03d5a9..ed26a2957 100644 --- a/pkg/tasks/tasks.go +++ b/pkg/tasks/tasks.go @@ -313,7 +313,7 @@ func WithContainerDMigration(t Tasks) Tasks { } s.Logger.Warn("Now please rolling restart your machineDeployments to get containerd") - s.Logger.Warn("see more at: https://docs.kubermatic.com/kubeone/v1.3/tutorials/rollout_machinedeployment/") + s.Logger.Warn("see more at: https://docs.kubermatic.com/kubeone/v1.3/cheat_sheets/rollout_machinedeployment/") return nil }, ErrMsg: "failed to ensure machine-controller",