Change:
return nil } <del> // IsCoreDNSConfigMapMigrationRequired checks if a migration of the CoreDNS ConfigMap is required. func IsCoreDNSConfigMapMigrationRequired(corefile string) bool { </del> <ins> // isCoreDNSConfigMapMigrationRequired checks if a migration of the CoreDNS ConfigMap is required. func isCoreDNSConfigMapMigrationRequired(corefile, currentInstalledCoreDNSVersion string) (bool, error) { var isMigrationRequired bool </ins> if corefile == "" || migration.Default("", corefile) { <del> return false </del> <ins> return isMigrationRequired, nil } deprecated, err := migration.Deprecated(currentInstalledCoreDNSVersion, kubeadmconstants.CoreDNSVersion, corefile) if err != nil { return isMigrationRequired, errors.Wrap(err, "unable to get list of changes to the configuration.") </ins> } <del> return true } func migrateCoreDNSCorefile(client clientset.Interface, cm *v1.ConfigMap, corefile, currentInstalledCoreDNSVersion string) error { // Take a copy of the Corefile data as `Corefile-backup` and update the ConfigMap // Also point the CoreDNS deployment to the `Corefile-backup` data. </del> <ins> // Check if there are any plugins/options which needs to be removed or is a new default for _, dep := range deprecated { if dep.Severity == "removed" || dep.Severity == "newDefault" { isMigrationRequired = true } } </ins> <del> if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(context.TODO(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name:      kubeadmconstants.CoreDNSConfigMap, Namespace: metav1.NamespaceSystem, }, Data: map[string]string{ "Corefile":        corefile, "Corefile-backup": corefile, </del> <ins> return isMigrationRequired, nil } func isCoreDNSVersionSupported(client clientset.Interface) (bool, error) { isValidVersion := true coreDNSPodList, err := client.CoreV1().Pods(metav1.NamespaceSystem).List( context.TODO(), metav1.ListOptions{ LabelSelector: "k8s-app=kube-dns", </ins> }, <del> }, metav1.UpdateOptions{}); err != nil { return errors.Wrap(err, "unable to update the CoreDNS ConfigMap with backup Corefile") </del> <ins> ) if err != nil { return false, errors.Wrap(err, "unable to list CoreDNS pods") </ins> } <del> if err := patchCoreDNSDeployment(client, "Corefile-backup"); err != nil { return err </del> <ins> for _, pod := range coreDNSPodList.Items { imageID := strings.Split(pod.Status.ContainerStatuses[0].ImageID, ":") if !migration.Released(imageID[2]) { isValidVersion = false } </ins> } <ins> return isValidVersion, nil } func migrateCoreDNSCorefile(client clientset.Interface, cm *v1.ConfigMap, corefile, currentInstalledCoreDNSVersion string) error { </ins> // Since the current configuration present is not the default version, try and migrate it. updatedCorefile, err := migration.Migrate(currentInstalledCoreDNSVersion, kubeadmconstants.CoreDNSVersion, corefile, false) if err != nil { return errors.Wrap(err, "unable to migrate CoreDNS ConfigMap") } <ins> // Take a copy of the existing Corefile data as `Corefile-backup` and update the ConfigMap </ins> if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(context.TODO(), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name:      kubeadmconstants.CoreDNSConfigMap,

Discussion:
What happened: Coredns failed to start in 1.17 deployment when it tried to retain a backed up Corefile with error message: Caddyfile via flag: open /etc/coredns/Corefile: no such file or directory What you expected to happen: Coredns starts normally with the backed-up Corefile How to reproduce it (as minimally and precisely as possible): Deploy a k8s 1.17 cluster and trigger coredns Corefile migration and make it fail. In our case, this was triggered in a three master -setup with 'old' method of running 'kubeadm init' for each master. Also the core-dns docker image used was tagged with '1.6.7-1', apparently causing the corefile migration version check to fail Anything else we need to know?: This seems to be caused by Both 'key' and 'path' are set to 'Corefile-backup' when this function is called. Should the 'path' always stay as 'Corefile' because that is where the container expects to find the config file? Environment: Kubernetes version (use ): Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"", GitTreeState:"clean", BuildDate:"2020-02-16T17:51:57Z", GoVersion:"go1.13.6", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"", GitTreeState:"clean", BuildDate:"2020-02-16T17:47:13Z", GoVersion:"go1.13.6", Compiler:"gc", Platform:"linux/amd64"} Cloud provider or hardware configuration: Custom deployment in Openstack environment OS (e.g: ): NAME="SLES" VERSION="15-SP1" VERSIONID="15.1" PRETTYNAME="SUSE Linux Enterprise Server 15 SP1" Kernel (e.g. ): 12.14-197.29-default Install tools: kubeadm Network plugin and version (if this is a network-related bug): Others:
/sig cluster-lifecycle
/assign
/area kubeadm