@@ -52,6 +52,9 @@ const (
5252 oldKubernetesImageRepository = "k8s.gcr.io"
5353 oldCoreDNSImageName = "coredns"
5454 coreDNSImageName = "coredns/coredns"
55+
56+ oldControlPlaneTaint = "node-role.kubernetes.io/master" // Deprecated: https://github.com/kubernetes/kubeadm/issues/2200
57+ controlPlaneTaint = "node-role.kubernetes.io/control-plane"
5558)
5659
5760var (
@@ -151,7 +154,7 @@ func (w *Workload) UpdateCoreDNS(ctx context.Context, kcp *controlplanev1.Kubead
151154 return err
152155 }
153156
154- if err := w .updateCoreDNSDeployment (ctx , info ); err != nil {
157+ if err := w .updateCoreDNSDeployment (ctx , info , version ); err != nil {
155158 return errors .Wrap (err , "unable to update coredns deployment" )
156159 }
157160 return nil
@@ -250,15 +253,19 @@ func (w *Workload) getCoreDNSInfo(ctx context.Context, clusterConfig *bootstrapv
250253// updateCoreDNSDeployment will patch the deployment image to the
251254// imageRepo:imageTag in the KCP dns. It will also ensure the volume of the
252255// deployment uses the Corefile key of the coredns configmap.
253- func (w * Workload ) updateCoreDNSDeployment (ctx context.Context , info * coreDNSInfo ) error {
256+ func (w * Workload ) updateCoreDNSDeployment (ctx context.Context , info * coreDNSInfo , kubernetesVersion semver. Version ) error {
254257 helper , err := patch .NewHelper (info .Deployment , w .Client )
255258 if err != nil {
256259 return err
257260 }
258261 // Form the final image before issuing the patch.
259262 patchCoreDNSDeploymentImage (info .Deployment , info .ToImage )
263+
260264 // Flip the deployment volume back to Corefile (from the backup key).
261265 patchCoreDNSDeploymentVolume (info .Deployment , corefileBackupKey , corefileKey )
266+
267+ // Patch the tolerations according to the Kubernetes Version.
268+ patchCoreDNSDeploymentTolerations (info .Deployment , kubernetesVersion )
262269 return helper .Patch (ctx , info .Deployment )
263270}
264271
@@ -421,6 +428,54 @@ func patchCoreDNSDeploymentImage(deployment *appsv1.Deployment, image string) {
421428 }
422429}
423430
431+ // patchCoreDNSDeploymentTolerations patches the CoreDNS Deployment to make sure
432+ // it has the right control plane tolerations.
433+ // Kubernetes nodes created with kubeadm have the following taints depending on version:
434+ // * -v1.23: only old taint is set
435+ // * v1.24: both taints are set
436+ // * v1.25+: only new taint is set
437+ // To be absolutely safe this func will ensure that both tolerations are present
438+ // for Kubernetes < v1.26.0. Starting with v1.26.0 we will only set the new toleration.
439+ func patchCoreDNSDeploymentTolerations (deployment * appsv1.Deployment , kubernetesVersion semver.Version ) {
440+ // We always add the toleration for the new control plane taint.
441+ tolerations := []corev1.Toleration {
442+ {
443+ Key : controlPlaneTaint ,
444+ Effect : corev1 .TaintEffectNoSchedule ,
445+ },
446+ }
447+
448+ // We add the toleration for the old control plane taint for Kubernetes < v1.26.0.
449+ if kubernetesVersion .LT (semver.Version {Major : 1 , Minor : 26 , Patch : 0 }) {
450+ tolerations = append (tolerations , corev1.Toleration {
451+ Key : oldControlPlaneTaint ,
452+ Effect : corev1 .TaintEffectNoSchedule ,
453+ })
454+ }
455+
456+ // Add all other already existing tolerations.
457+ for _ , currentToleration := range deployment .Spec .Template .Spec .Tolerations {
458+ // Skip the old control plane toleration as it has been already added above,
459+ // for Kubernetes < v1.26.0.
460+ if currentToleration .Key == oldControlPlaneTaint &&
461+ currentToleration .Effect == corev1 .TaintEffectNoSchedule &&
462+ currentToleration .Value == "" {
463+ continue
464+ }
465+
466+ // Skip the new control plane toleration as it has been already added above.
467+ if currentToleration .Key == controlPlaneTaint &&
468+ currentToleration .Effect == corev1 .TaintEffectNoSchedule &&
469+ currentToleration .Value == "" {
470+ continue
471+ }
472+
473+ tolerations = append (tolerations , currentToleration )
474+ }
475+
476+ deployment .Spec .Template .Spec .Tolerations = tolerations
477+ }
478+
424479func extractImageVersion (tag string ) (semver.Version , error ) {
425480 ver , err := version .ParseMajorMinorPatchTolerant (tag )
426481 if err != nil {
0 commit comments