Skip to content

Commit 83038f6

Browse files
authored
Merge pull request #7368 from sbueringer/pr-coredns-tolerations
🐛 KCP: adjust CoreDNS tolerations according to Kubernetes version
2 parents 850c2a6 + 5bd840c commit 83038f6

File tree

2 files changed

+155
-3
lines changed

2 files changed

+155
-3
lines changed

controlplane/kubeadm/internal/workload_cluster_coredns.go

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5760
var (
@@ -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+
424479
func extractImageVersion(tag string) (semver.Version, error) {
425480
ver, err := version.ParseMajorMinorPatchTolerant(tag)
426481
if err != nil {

controlplane/kubeadm/internal/workload_cluster_coredns_test.go

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1505,7 +1505,7 @@ func TestUpdateCoreDNSDeployment(t *testing.T) {
15051505
Client: fakeClient,
15061506
}
15071507

1508-
err := w.updateCoreDNSDeployment(ctx, tt.info)
1508+
err := w.updateCoreDNSDeployment(ctx, tt.info, semver.Version{Major: 1, Minor: 26, Patch: 0})
15091509
if tt.expectErr {
15101510
g.Expect(err).To(HaveOccurred())
15111511
return
@@ -1536,6 +1536,103 @@ func TestUpdateCoreDNSDeployment(t *testing.T) {
15361536
}
15371537
}
15381538

1539+
func TestPatchCoreDNSDeploymentTolerations(t *testing.T) {
1540+
oldControlPlaneToleration := corev1.Toleration{
1541+
Key: oldControlPlaneTaint,
1542+
Effect: corev1.TaintEffectNoSchedule,
1543+
}
1544+
controlPlaneToleration := corev1.Toleration{
1545+
Key: controlPlaneTaint,
1546+
Effect: corev1.TaintEffectNoSchedule,
1547+
}
1548+
1549+
tests := []struct {
1550+
name string
1551+
currentTolerations []corev1.Toleration
1552+
kubernetesVersion semver.Version
1553+
expectedTolerations []corev1.Toleration
1554+
}{
1555+
{
1556+
name: "adds both tolerations for Kubernetes v1.25",
1557+
currentTolerations: []corev1.Toleration{},
1558+
kubernetesVersion: semver.Version{Major: 1, Minor: 25, Patch: 0},
1559+
expectedTolerations: []corev1.Toleration{
1560+
controlPlaneToleration,
1561+
oldControlPlaneToleration,
1562+
},
1563+
},
1564+
{
1565+
name: "adds only new toleration for Kubernetes v1.26",
1566+
currentTolerations: []corev1.Toleration{},
1567+
kubernetesVersion: semver.Version{Major: 1, Minor: 26, Patch: 0},
1568+
expectedTolerations: []corev1.Toleration{
1569+
controlPlaneToleration,
1570+
},
1571+
},
1572+
{
1573+
name: "adds both tolerations for Kubernetes v1.25 and preserves additional tolerations",
1574+
currentTolerations: []corev1.Toleration{
1575+
{
1576+
Key: "my-special.custom/taint",
1577+
Effect: corev1.TaintEffectNoExecute,
1578+
Value: "aValue",
1579+
},
1580+
},
1581+
kubernetesVersion: semver.Version{Major: 1, Minor: 25, Patch: 0},
1582+
expectedTolerations: []corev1.Toleration{
1583+
controlPlaneToleration,
1584+
oldControlPlaneToleration,
1585+
{
1586+
Key: "my-special.custom/taint",
1587+
Effect: corev1.TaintEffectNoExecute,
1588+
Value: "aValue",
1589+
},
1590+
},
1591+
},
1592+
{
1593+
name: "ensures only new toleration is set for Kubernetes v1.26, drops old toleration and preserves additional tolerations",
1594+
currentTolerations: []corev1.Toleration{
1595+
oldControlPlaneToleration,
1596+
{
1597+
Key: "my-special.custom/taint",
1598+
Effect: corev1.TaintEffectNoExecute,
1599+
Value: "aValue",
1600+
},
1601+
},
1602+
kubernetesVersion: semver.Version{Major: 1, Minor: 25, Patch: 0},
1603+
expectedTolerations: []corev1.Toleration{
1604+
controlPlaneToleration,
1605+
oldControlPlaneToleration,
1606+
{
1607+
Key: "my-special.custom/taint",
1608+
Effect: corev1.TaintEffectNoExecute,
1609+
Value: "aValue",
1610+
},
1611+
},
1612+
},
1613+
}
1614+
1615+
for _, tt := range tests {
1616+
t.Run(tt.name, func(t *testing.T) {
1617+
g := NewWithT(t)
1618+
1619+
d := &appsv1.Deployment{
1620+
Spec: appsv1.DeploymentSpec{
1621+
Template: corev1.PodTemplateSpec{
1622+
Spec: corev1.PodSpec{
1623+
Tolerations: tt.currentTolerations,
1624+
},
1625+
},
1626+
},
1627+
}
1628+
1629+
patchCoreDNSDeploymentTolerations(d, tt.kubernetesVersion)
1630+
1631+
g.Expect(d.Spec.Template.Spec.Tolerations).To(Equal(tt.expectedTolerations))
1632+
})
1633+
}
1634+
}
1635+
15391636
type fakeMigrator struct {
15401637
migrateCalled bool
15411638
migrateErr error

0 commit comments

Comments
 (0)