From 379c8e83da6d89cf8ef39788294f1000e3756d27 Mon Sep 17 00:00:00 2001 From: Sandeep Rajan Date: Thu, 3 May 2018 10:53:41 -0400 Subject: [PATCH] Improve coredns upgrade path --- cmd/kubeadm/app/phases/addons/dns/dns.go | 4 +- cmd/kubeadm/app/phases/upgrade/postupgrade.go | 46 ++++++++++--------- cmd/kubeadm/app/util/apiclient/idempotency.go | 15 ++++++ 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/cmd/kubeadm/app/phases/addons/dns/dns.go b/cmd/kubeadm/app/phases/addons/dns/dns.go index f7fc2cba5aa..4b8dc1c8d97 100644 --- a/cmd/kubeadm/app/phases/addons/dns/dns.go +++ b/cmd/kubeadm/app/phases/addons/dns/dns.go @@ -205,8 +205,8 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien return fmt.Errorf("unable to decode CoreDNS configmap %v", err) } - // Create the ConfigMap for CoreDNS or update it in case it already exists - if err := apiclient.CreateOrUpdateConfigMap(client, coreDNSConfigMap); err != nil { + // Create the ConfigMap for CoreDNS or retain it in case it already exists + if err := apiclient.CreateOrRetainConfigMap(client, coreDNSConfigMap, kubeadmconstants.CoreDNS); err != nil { return err } diff --git a/cmd/kubeadm/app/phases/upgrade/postupgrade.go b/cmd/kubeadm/app/phases/upgrade/postupgrade.go index fcfab59b0fa..15bb8ff1228 100644 --- a/cmd/kubeadm/app/phases/upgrade/postupgrade.go +++ b/cmd/kubeadm/app/phases/upgrade/postupgrade.go @@ -103,13 +103,13 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.MasterC } } - // Upgrade kube-dns and kube-proxy + // Upgrade kube-dns/CoreDNS and kube-proxy if err := dns.EnsureDNSAddon(cfg, client); err != nil { errs = append(errs, err) } - // Remove the old kube-dns deployment if coredns is now used + // Remove the old DNS deployment if a new DNS service is now used (kube-dns to CoreDNS or vice versa) if !dryRun { - if err := removeOldKubeDNSDeploymentIfCoreDNSIsUsed(cfg, client); err != nil { + if err := removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg, client); err != nil { errs = append(errs, err) } } @@ -120,24 +120,28 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.MasterC return errors.NewAggregate(errs) } -func removeOldKubeDNSDeploymentIfCoreDNSIsUsed(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error { - if features.Enabled(cfg.FeatureGates, features.CoreDNS) { - return apiclient.TryRunCommand(func() error { - coreDNSDeployment, err := client.AppsV1().Deployments(metav1.NamespaceSystem).Get(kubeadmconstants.CoreDNS, metav1.GetOptions{}) - if err != nil { - return err - } - if coreDNSDeployment.Status.ReadyReplicas == 0 { - return fmt.Errorf("the CoreDNS deployment isn't ready yet") - } - err = apiclient.DeleteDeploymentForeground(client, metav1.NamespaceSystem, kubeadmconstants.KubeDNS) - if err != nil && !apierrors.IsNotFound(err) { - return err - } - return nil - }, 10) - } - return nil +func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error { + return apiclient.TryRunCommand(func() error { + installedDeploymentName := kubeadmconstants.KubeDNS + deploymentToDelete := kubeadmconstants.CoreDNS + + if features.Enabled(cfg.FeatureGates, features.CoreDNS) { + installedDeploymentName = kubeadmconstants.CoreDNS + deploymentToDelete = kubeadmconstants.KubeDNS + } + dnsDeployment, err := client.AppsV1().Deployments(metav1.NamespaceSystem).Get(installedDeploymentName, metav1.GetOptions{}) + if err != nil { + return err + } + if dnsDeployment.Status.ReadyReplicas == 0 { + return fmt.Errorf("the DNS deployment isn't ready yet") + } + err = apiclient.DeleteDeploymentForeground(client, metav1.NamespaceSystem, deploymentToDelete) + if err != nil && !apierrors.IsNotFound(err) { + return err + } + return nil + }, 10) } func upgradeToSelfHosting(client clientset.Interface, cfg *kubeadmapi.MasterConfiguration, newK8sVer *version.Version, dryRun bool) error { diff --git a/cmd/kubeadm/app/util/apiclient/idempotency.go b/cmd/kubeadm/app/util/apiclient/idempotency.go index 03f60be77cd..ffe42df077a 100644 --- a/cmd/kubeadm/app/util/apiclient/idempotency.go +++ b/cmd/kubeadm/app/util/apiclient/idempotency.go @@ -44,6 +44,21 @@ func CreateOrUpdateConfigMap(client clientset.Interface, cm *v1.ConfigMap) error return nil } +// CreateOrRetainConfigMap creates a ConfigMap if the target resource doesn't exist. If the resource exists already, this function will retain the resource instead. +func CreateOrRetainConfigMap(client clientset.Interface, cm *v1.ConfigMap, configMapName string) error { + if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Get(configMapName, metav1.GetOptions{}); err != nil { + if !apierrors.IsNotFound(err) { + return nil + } + if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(cm); err != nil { + if !apierrors.IsAlreadyExists(err) { + return fmt.Errorf("unable to create configmap: %v", err) + } + } + } + return nil +} + // CreateOrUpdateSecret creates a Secret if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. func CreateOrUpdateSecret(client clientset.Interface, secret *v1.Secret) error { if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Create(secret); err != nil {