diff --git a/pkg/controllermanager/controller/shoot/maintenance/reconciler.go b/pkg/controllermanager/controller/shoot/maintenance/reconciler.go index e3d4b5cc37a..eed4b92334a 100644 --- a/pkg/controllermanager/controller/shoot/maintenance/reconciler.go +++ b/pkg/controllermanager/controller/shoot/maintenance/reconciler.go @@ -143,6 +143,16 @@ func (r *Reconciler) reconcile(ctx context.Context, log logr.Logger, shoot *gard return err } + // Force containerd when shoot cluster is updated to k8s version >= 1.23 + if versionutils.ConstraintK8sLess123.Check(oldShootKubernetesVersion) && versionutils.ConstraintK8sGreaterEqual123.Check(shootKubernetesVersion) { + reasonsForContainerdUpdate, err := updateToContainerd(maintainedShoot, fmt.Sprintf("Updating Kubernetes to %q", shootKubernetesVersion.String())) + if err != nil { + // continue execution to allow other updates + log.Error(err, "Failed updating worker pools' CRI to containerd") + } + operations = append(operations, reasonsForContainerdUpdate...) + } + // Reset the `EnableStaticTokenKubeconfig` value to false, when shoot cluster is updated to k8s version >= 1.27. if versionutils.ConstraintK8sLess127.Check(oldShootKubernetesVersion) && pointer.BoolDeref(maintainedShoot.Spec.Kubernetes.EnableStaticTokenKubeconfig, false) && versionutils.ConstraintK8sGreaterEqual127.Check(shootKubernetesVersion) { maintainedShoot.Spec.Kubernetes.EnableStaticTokenKubeconfig = pointer.Bool(false) @@ -621,3 +631,18 @@ func ExpirationDateExpired(timestamp *metav1.Time) bool { } return time.Now().UTC().After(timestamp.Time) || time.Now().UTC().Equal(timestamp.Time) } + +// updateToContainerd updates the CRI of a Shoot's worker pools to containerd +func updateToContainerd(shoot *gardencorev1beta1.Shoot, reason string) ([]string, error) { + var reasonsForUpdate []string + + for i, worker := range shoot.Spec.Provider.Workers { + if worker.CRI == nil || worker.CRI.Name != gardencorev1beta1.CRINameDocker { + continue + } + shoot.Spec.Provider.Workers[i].CRI.Name = gardencorev1beta1.CRINameContainerD + reasonsForUpdate = append(reasonsForUpdate, fmt.Sprintf("CRI of worker-pool %q upgraded from %q to %q. Reason: %s", worker.Name, gardencorev1beta1.CRINameDocker, gardencorev1beta1.CRINameContainerD, reason)) + } + + return reasonsForUpdate, nil +} diff --git a/pkg/controllermanager/controller/shoot/maintenance/reconciler_test.go b/pkg/controllermanager/controller/shoot/maintenance/reconciler_test.go index 2c36091d00a..9a98e4c4b38 100644 --- a/pkg/controllermanager/controller/shoot/maintenance/reconciler_test.go +++ b/pkg/controllermanager/controller/shoot/maintenance/reconciler_test.go @@ -699,6 +699,61 @@ var _ = Describe("Shoot Maintenance", func() { Expect(shoot.Spec.Kubernetes.Version).To(Equal("1.1.2")) }) }) + + Describe("#UpdateToContainerd", func() { + var ( + shoot *gardencorev1beta1.Shoot + ) + + BeforeEach(func() { + shoot = &gardencorev1beta1.Shoot{ + ObjectMeta: metav1.ObjectMeta{ + Name: "shoot", + }, + Spec: gardencorev1beta1.ShootSpec{ + Kubernetes: gardencorev1beta1.Kubernetes{ + Version: "1.23.16", + }, + Maintenance: &gardencorev1beta1.Maintenance{ + AutoUpdate: &gardencorev1beta1.MaintenanceAutoUpdate{ + MachineImageVersion: pointer.Bool(true), + }, + }, + Provider: gardencorev1beta1.Provider{Workers: []gardencorev1beta1.Worker{ + { + Name: "cpu-worker", + }, + { + Name: "cpu-worker2", + }, + }}, + }, + } + }) + + It("should not change anything if CRI is not set", func() { + _, err := updateToContainerd(shoot, "foobar") + Expect(err).NotTo(HaveOccurred()) + Expect(shoot.Spec.Provider.Workers[0].CRI).To(BeNil()) + Expect(shoot.Spec.Provider.Workers[1].CRI).To(BeNil()) + }) + + It("should change docker to containerd", func() { + shoot.Spec.Provider.Workers[1].CRI = &gardencorev1beta1.CRI{Name: "docker"} + _, err := updateToContainerd(shoot, "foobar") + Expect(err).NotTo(HaveOccurred()) + Expect(shoot.Spec.Provider.Workers[1].CRI.Name).To(Equal(gardencorev1beta1.CRINameContainerD)) + Expect(shoot.Spec.Provider.Workers[0].CRI).To(BeNil()) + }) + + It("should keep containerd if it is already set", func() { + shoot.Spec.Provider.Workers[0].CRI = &gardencorev1beta1.CRI{Name: "containerd"} + _, err := updateToContainerd(shoot, "foobar") + Expect(err).NotTo(HaveOccurred()) + Expect(shoot.Spec.Provider.Workers[0].CRI.Name).To(Equal(gardencorev1beta1.CRINameContainerD)) + Expect(shoot.Spec.Provider.Workers[1].CRI).To(BeNil()) + }) + }) }) func assertWorkerMachineImageVersion(worker *gardencorev1beta1.Worker, imageName string, imageVersion string) {