kubeadm - set CoreDNS FeatureGate to true by default

parent 9a868b38
......@@ -28,7 +28,6 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd"
......@@ -118,19 +117,19 @@ func RunPlan(flags *planFlags) error {
// Compute which upgrade possibilities there are
glog.V(1).Infof("[upgrade/plan] computing upgrade possibilities")
availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, flags.parent.allowExperimentalUpgrades, flags.parent.allowRCUpgrades, etcdClient, upgradeVars.cfg.FeatureGates)
availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, flags.parent.allowExperimentalUpgrades, flags.parent.allowRCUpgrades, etcdClient, upgradeVars.cfg.FeatureGates, upgradeVars.client)
if err != nil {
return fmt.Errorf("[upgrade/versions] FATAL: %v", err)
}
// Tell the user which upgrades are available
printAvailableUpgrades(availUpgrades, os.Stdout, upgradeVars.cfg.FeatureGates, isExternalEtcd)
printAvailableUpgrades(availUpgrades, os.Stdout, isExternalEtcd)
return nil
}
// printAvailableUpgrades prints a UX-friendly overview of what versions are available to upgrade to
// TODO look into columnize or some other formatter when time permits instead of using the tabwriter
func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer, featureGates map[string]bool, isExternalEtcd bool) {
func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer, isExternalEtcd bool) {
// Return quickly if no upgrades can be made
if len(upgrades) == 0 {
......@@ -182,11 +181,37 @@ func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer, featureGate
fmt.Fprintf(tabw, "Controller Manager\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion)
fmt.Fprintf(tabw, "Scheduler\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion)
fmt.Fprintf(tabw, "Kube Proxy\t%s\t%s\n", upgrade.Before.KubeVersion, upgrade.After.KubeVersion)
if features.Enabled(featureGates, features.CoreDNS) {
fmt.Fprintf(tabw, "CoreDNS\t%s\t%s\n", upgrade.Before.DNSVersion, upgrade.After.DNSVersion)
} else {
fmt.Fprintf(tabw, "Kube DNS\t%s\t%s\n", upgrade.Before.DNSVersion, upgrade.After.DNSVersion)
// TODO There is currently no way to cleanly output upgrades that involve adding, removing, or changing components
// https://github.com/kubernetes/kubeadm/issues/810 was created to track addressing this.
printCoreDNS, printKubeDNS := false, false
coreDNSBeforeVersion, coreDNSAfterVersion, kubeDNSBeforeVersion, kubeDNSAfterVersion := "", "", "", ""
switch upgrade.Before.DNSType {
case constants.CoreDNS:
printCoreDNS = true
coreDNSBeforeVersion = upgrade.Before.DNSVersion
case constants.KubeDNS:
printKubeDNS = true
kubeDNSBeforeVersion = upgrade.Before.DNSVersion
}
switch upgrade.After.DNSType {
case constants.CoreDNS:
printCoreDNS = true
coreDNSAfterVersion = upgrade.After.DNSVersion
case constants.KubeDNS:
printKubeDNS = true
kubeDNSAfterVersion = upgrade.After.DNSVersion
}
if printCoreDNS {
fmt.Fprintf(tabw, "CoreDNS\t%s\t%s\n", coreDNSBeforeVersion, coreDNSAfterVersion)
}
if printKubeDNS {
fmt.Fprintf(tabw, "Kube DNS\t%s\t%s\n", kubeDNSBeforeVersion, kubeDNSAfterVersion)
}
if !isExternalEtcd {
fmt.Fprintf(tabw, "Etcd\t%s\t%s\n", upgrade.Before.EtcdVersion, upgrade.After.EtcdVersion)
}
......
......@@ -60,7 +60,6 @@ func TestSortedSliceFromStringIntMap(t *testing.T) {
// TODO Think about modifying this test to be less verbose checking b/c it can be brittle.
func TestPrintAvailableUpgrades(t *testing.T) {
featureGates := make(map[string]bool)
var tests = []struct {
name string
upgrades []upgrade.Upgrade
......@@ -92,12 +91,14 @@ func TestPrintAvailableUpgrades(t *testing.T) {
"v1.8.1": 1,
},
KubeadmVersion: "v1.8.2",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.8.3",
KubeadmVersion: "v1.8.3",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
......@@ -138,12 +139,14 @@ _____________________________________________________________________
"v1.8.3": 1,
},
KubeadmVersion: "v1.9.0",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.9.0",
KubeadmVersion: "v1.9.0",
DNSType: "kube-dns",
DNSVersion: "1.14.10",
EtcdVersion: "3.1.12",
},
......@@ -182,12 +185,14 @@ _____________________________________________________________________
"v1.8.3": 1,
},
KubeadmVersion: "v1.8.3",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.8.5",
KubeadmVersion: "v1.8.3",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
......@@ -200,12 +205,14 @@ _____________________________________________________________________
"v1.8.3": 1,
},
KubeadmVersion: "v1.8.3",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.9.0",
KubeadmVersion: "v1.9.0",
DNSType: "kube-dns",
DNSVersion: "1.14.10",
EtcdVersion: "3.1.12",
},
......@@ -266,12 +273,14 @@ _____________________________________________________________________
"v1.8.5": 1,
},
KubeadmVersion: "v1.8.5",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.9.0-beta.1",
KubeadmVersion: "v1.9.0-beta.1",
DNSType: "kube-dns",
DNSVersion: "1.14.10",
EtcdVersion: "3.1.12",
},
......@@ -312,12 +321,14 @@ _____________________________________________________________________
"v1.8.5": 1,
},
KubeadmVersion: "v1.8.5",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.9.0-rc.1",
KubeadmVersion: "v1.9.0-rc.1",
DNSType: "kube-dns",
DNSVersion: "1.14.10",
EtcdVersion: "3.1.12",
},
......@@ -359,12 +370,14 @@ _____________________________________________________________________
"v1.9.3": 2,
},
KubeadmVersion: "v1.9.2",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.9.3",
KubeadmVersion: "v1.9.3",
DNSType: "kube-dns",
DNSVersion: "1.14.8",
EtcdVersion: "3.1.12",
},
......@@ -395,6 +408,7 @@ _____________________________________________________________________
`),
},
{
name: "external etcd upgrade available",
upgrades: []upgrade.Upgrade{
......@@ -406,12 +420,14 @@ _____________________________________________________________________
"v1.9.2": 1,
},
KubeadmVersion: "v1.9.2",
DNSType: "kube-dns",
DNSVersion: "1.14.5",
EtcdVersion: "3.0.17",
},
After: upgrade.ClusterState{
KubeVersion: "v1.9.3",
KubeadmVersion: "v1.9.3",
DNSType: "kube-dns",
DNSVersion: "1.14.8",
EtcdVersion: "3.1.12",
},
......@@ -445,11 +461,151 @@ _____________________________________________________________________
`),
},
{
name: "kubedns to coredns",
upgrades: []upgrade.Upgrade{
{
Description: "kubedns to coredns",
Before: upgrade.ClusterState{
KubeVersion: "v1.10.2",
KubeletVersions: map[string]uint16{
"v1.10.2": 1,
},
KubeadmVersion: "v1.11.0",
DNSType: "kube-dns",
DNSVersion: "1.14.7",
EtcdVersion: "3.1.11",
},
After: upgrade.ClusterState{
KubeVersion: "v1.11.0",
KubeadmVersion: "v1.11.0",
DNSType: "coredns",
DNSVersion: "1.0.6",
EtcdVersion: "3.2.18",
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.10.2 v1.11.0
Upgrade to the latest kubedns to coredns:
COMPONENT CURRENT AVAILABLE
API Server v1.10.2 v1.11.0
Controller Manager v1.10.2 v1.11.0
Scheduler v1.10.2 v1.11.0
Kube Proxy v1.10.2 v1.11.0
CoreDNS 1.0.6
Kube DNS 1.14.7
Etcd 3.1.11 3.2.18
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.11.0
_____________________________________________________________________
`),
},
{
name: "coredns",
upgrades: []upgrade.Upgrade{
{
Description: "coredns",
Before: upgrade.ClusterState{
KubeVersion: "v1.10.2",
KubeletVersions: map[string]uint16{
"v1.10.2": 1,
},
KubeadmVersion: "v1.11.0",
DNSType: "coredns",
DNSVersion: "1.0.5",
EtcdVersion: "3.1.11",
},
After: upgrade.ClusterState{
KubeVersion: "v1.11.0",
KubeadmVersion: "v1.11.0",
DNSType: "coredns",
DNSVersion: "1.0.6",
EtcdVersion: "3.2.18",
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.10.2 v1.11.0
Upgrade to the latest coredns:
COMPONENT CURRENT AVAILABLE
API Server v1.10.2 v1.11.0
Controller Manager v1.10.2 v1.11.0
Scheduler v1.10.2 v1.11.0
Kube Proxy v1.10.2 v1.11.0
CoreDNS 1.0.5 1.0.6
Etcd 3.1.11 3.2.18
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.11.0
_____________________________________________________________________
`),
},
{
name: "coredns to kubedns",
upgrades: []upgrade.Upgrade{
{
Description: "coredns to kubedns",
Before: upgrade.ClusterState{
KubeVersion: "v1.10.2",
KubeletVersions: map[string]uint16{
"v1.10.2": 1,
},
KubeadmVersion: "v1.11.0",
DNSType: "coredns",
DNSVersion: "1.0.6",
EtcdVersion: "3.1.11",
},
After: upgrade.ClusterState{
KubeVersion: "v1.11.0",
KubeadmVersion: "v1.11.0",
DNSType: "kube-dns",
DNSVersion: "1.14.9",
EtcdVersion: "3.2.18",
},
},
},
expectedBytes: []byte(`Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT CURRENT AVAILABLE
Kubelet 1 x v1.10.2 v1.11.0
Upgrade to the latest coredns to kubedns:
COMPONENT CURRENT AVAILABLE
API Server v1.10.2 v1.11.0
Controller Manager v1.10.2 v1.11.0
Scheduler v1.10.2 v1.11.0
Kube Proxy v1.10.2 v1.11.0
CoreDNS 1.0.6
Kube DNS 1.14.9
Etcd 3.1.11 3.2.18
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.11.0
_____________________________________________________________________
`),
},
}
for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) {
rt.buf = bytes.NewBufferString("")
printAvailableUpgrades(rt.upgrades, rt.buf, featureGates, rt.externalEtcd)
printAvailableUpgrades(rt.upgrades, rt.buf, rt.externalEtcd)
actualBytes := rt.buf.Bytes()
if !bytes.Equal(actualBytes, rt.expectedBytes) {
t.Errorf(
......
......@@ -30,7 +30,7 @@ const (
// HighAvailability is alpha in v1.9
HighAvailability = "HighAvailability"
// CoreDNS is alpha in v1.9
// CoreDNS is GA in v1.11
CoreDNS = "CoreDNS"
// SelfHosting is alpha in v1.8 and v1.9
......@@ -54,7 +54,7 @@ var InitFeatureGates = FeatureList{
StoreCertsInSecrets: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
// We don't want to advertise this feature gate exists in v1.9 to avoid confusion as it is not yet working
HighAvailability: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}, MinimumVersion: v190, HiddenInHelpText: true},
CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.GA}, MinimumVersion: v190},
CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.GA}, MinimumVersion: v190},
DynamicKubeletConfig: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}, MinimumVersion: v190},
Auditing: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
}
......@@ -92,7 +92,10 @@ func ValidateVersion(allFeatures FeatureList, requestedFeatures map[string]bool,
// Enabled indicates whether a feature name has been enabled
func Enabled(featureList map[string]bool, featureName string) bool {
return featureList[string(featureName)]
if enabled, ok := featureList[string(featureName)]; ok {
return enabled
}
return InitFeatureGates[string(featureName)].Default
}
// Supports indicates whether a feature name is supported on the given
......
......@@ -168,8 +168,8 @@ func TestResolveFeatureGateDependencies(t *testing.T) {
expectedFeatures: map[string]bool{},
},
{ // others flags
inputFeatures: map[string]bool{CoreDNS: true},
expectedFeatures: map[string]bool{CoreDNS: true},
inputFeatures: map[string]bool{CoreDNS: false},
expectedFeatures: map[string]bool{CoreDNS: false},
},
{ // just StoreCertsInSecrets flags
inputFeatures: map[string]bool{StoreCertsInSecrets: true},
......@@ -189,3 +189,16 @@ func TestResolveFeatureGateDependencies(t *testing.T) {
}
}
}
// TestEnabledDefaults tests that Enabled returns the default values for
// each feature gate when no feature gates are specified.
func TestEnabledDefaults(t *testing.T) {
for featureName, feature := range InitFeatureGates {
featureList := make(map[string]bool)
enabled := Enabled(featureList, featureName)
if enabled != feature.Default {
t.Errorf("Enabled returned %v instead of default value %v for feature %s", enabled, feature.Default, featureName)
}
}
}
......@@ -48,6 +48,28 @@ const (
kubeDNSFederation = "federations"
)
// DeployedDNSAddon returns the type of DNS addon currently deployed
func DeployedDNSAddon(client clientset.Interface) (string, string, error) {
deploymentsClient := client.AppsV1().Deployments(metav1.NamespaceSystem)
deployments, err := deploymentsClient.List(metav1.ListOptions{LabelSelector: "k8s-app=kube-dns"})
if err != nil {
return "", "", fmt.Errorf("couldn't retrieve DNS addon deployments: %v", err)
}
switch len(deployments.Items) {
case 0:
return "", "", nil
case 1:
addonName := deployments.Items[0].Name
addonImage := deployments.Items[0].Spec.Template.Spec.Containers[0].Image
addonImageParts := strings.Split(addonImage, ":")
addonVersion := addonImageParts[len(addonImageParts)-1]
return addonName, addonVersion, nil
default:
return "", "", fmt.Errorf("multiple DNS addon deployments found: %v", deployments.Items)
}
}
// EnsureDNSAddon creates the kube-dns or CoreDNS addon
func EnsureDNSAddon(cfg *kubeadmapi.MasterConfiguration, client clientset.Interface) error {
k8sVersion, err := version.ParseSemantic(cfg.KubernetesVersion)
......
......@@ -91,6 +91,10 @@ go_test(
"//pkg/util/version:go_default_library",
"//vendor/github.com/coreos/etcd/clientv3:go_default_library",
"//vendor/github.com/coreos/etcd/pkg/transport:go_default_library",
"//vendor/k8s.io/api/apps/v1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
],
)
......@@ -20,6 +20,7 @@ import (
"fmt"
"strings"
clientset "k8s.io/client-go/kubernetes"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
......@@ -67,6 +68,8 @@ func ActiveDNSAddon(featureGates map[string]bool) string {
type ClusterState struct {
// KubeVersion describes the version of the Kubernetes API Server, Controller Manager, Scheduler and Proxy.
KubeVersion string
// DNSType
DNSType string
// DNSVersion describes the version of the kube-dns images used and manifest version
DNSVersion string
// KubeadmVersion describes the version of the kubeadm CLI
......@@ -79,7 +82,7 @@ type ClusterState struct {
// GetAvailableUpgrades fetches all versions from the specified VersionGetter and computes which
// kinds of upgrades can be performed
func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesAllowed, rcUpgradesAllowed bool, etcdClient etcdutil.ClusterInterrogator, featureGates map[string]bool) ([]Upgrade, error) {
func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesAllowed, rcUpgradesAllowed bool, etcdClient etcdutil.ClusterInterrogator, featureGates map[string]bool, client clientset.Interface) ([]Upgrade, error) {
fmt.Println("[upgrade] Fetching available versions to upgrade to")
// Collect the upgrades kubeadm can do in this list
......@@ -117,10 +120,16 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
return upgrades, err
}
dnsType, dnsVersion, err := dns.DeployedDNSAddon(client)
if err != nil {
return nil, err
}
// Construct a descriptor for the current state of the world
beforeState := ClusterState{
KubeVersion: clusterVersionStr,
DNSVersion: dns.GetDNSVersion(clusterVersion, ActiveDNSAddon(featureGates)),
DNSType: dnsType,
DNSVersion: dnsVersion,
KubeadmVersion: kubeadmVersionStr,
KubeletVersions: kubeletVersions,
EtcdVersion: etcdVersion,
......@@ -163,6 +172,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState,
After: ClusterState{
KubeVersion: patchVersionStr,
DNSType: ActiveDNSAddon(featureGates),
DNSVersion: dns.GetDNSVersion(patchVersion, ActiveDNSAddon(featureGates)),
KubeadmVersion: newKubeadmVer,
EtcdVersion: getSuggestedEtcdVersion(patchVersionStr),
......@@ -179,6 +189,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState,
After: ClusterState{
KubeVersion: stableVersionStr,
DNSType: ActiveDNSAddon(featureGates),
DNSVersion: dns.GetDNSVersion(stableVersion, ActiveDNSAddon(featureGates)),
KubeadmVersion: stableVersionStr,
EtcdVersion: getSuggestedEtcdVersion(stableVersionStr),
......@@ -224,6 +235,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState,
After: ClusterState{
KubeVersion: previousBranchLatestVersionStr,
DNSType: ActiveDNSAddon(featureGates),
DNSVersion: dns.GetDNSVersion(previousBranchLatestVersion, ActiveDNSAddon(featureGates)),
KubeadmVersion: previousBranchLatestVersionStr,
EtcdVersion: getSuggestedEtcdVersion(previousBranchLatestVersionStr),
......@@ -250,6 +262,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState,
After: ClusterState{
KubeVersion: unstableKubeVersion,
DNSType: ActiveDNSAddon(featureGates),
DNSVersion: unstableKubeDNSVersion,
KubeadmVersion: unstableKubeVersion,
EtcdVersion: getSuggestedEtcdVersion(unstableKubeVersion),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment