add DNS struct to kubeadm config

This commit is contained in:
fabriziopandini 2018-11-10 17:27:39 +01:00
parent a3ccea9d87
commit 6759334f6e
30 changed files with 596 additions and 278 deletions

View File

@ -18,7 +18,6 @@ package fuzzer
import ( import (
fuzz "github.com/google/gofuzz" fuzz "github.com/google/gofuzz"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
@ -34,6 +33,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
fuzzAuditPolicyConfiguration, fuzzAuditPolicyConfiguration,
fuzzComponentConfigs, fuzzComponentConfigs,
fuzzNodeRegistration, fuzzNodeRegistration,
fuzzDNS,
fuzzLocalEtcd, fuzzLocalEtcd,
fuzzNetworking, fuzzNetworking,
fuzzJoinConfiguration, fuzzJoinConfiguration,
@ -59,6 +59,9 @@ func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) {
LogDir: constants.StaticPodAuditPolicyLogDir, LogDir: constants.StaticPodAuditPolicyLogDir,
LogMaxAge: &v1beta1.DefaultAuditPolicyLogMaxAge, LogMaxAge: &v1beta1.DefaultAuditPolicyLogMaxAge,
}, },
DNS: kubeadm.DNS{
Type: kubeadm.CoreDNS,
},
CertificatesDir: v1beta1.DefaultCertificatesDir, CertificatesDir: v1beta1.DefaultCertificatesDir,
ClusterName: v1beta1.DefaultClusterName, ClusterName: v1beta1.DefaultClusterName,
Etcd: kubeadm.Etcd{ Etcd: kubeadm.Etcd{
@ -107,6 +110,14 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue
} }
} }
func fuzzDNS(obj *kubeadm.DNS, c fuzz.Continue) {
// This is intentionally not calling c.FuzzNoCustom because DNS struct does not exists in v1alpha3 api
// (so no random value will be applied, and this is necessary for getting roundtrip passing)
// Pinning values for fields that get defaults if fuzz value is empty string or nil
obj.Type = kubeadm.CoreDNS
}
func fuzzAuditPolicyConfiguration(obj *kubeadm.AuditPolicyConfiguration, c fuzz.Continue) { func fuzzAuditPolicyConfiguration(obj *kubeadm.AuditPolicyConfiguration, c fuzz.Continue) {
c.FuzzNoCustom(obj) c.FuzzNoCustom(obj)
@ -125,6 +136,10 @@ func fuzzLocalEtcd(obj *kubeadm.LocalEtcd, c fuzz.Continue) {
// Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail) // Pinning values for fields that get defaults if fuzz value is empty string or nil (thus making the round trip test fail)
obj.DataDir = "foo" obj.DataDir = "foo"
// Pinning values for fields that does not exists in v1alpha3 api
obj.ImageRepository = ""
obj.ImageTag = ""
} }
func fuzzNetworking(obj *kubeadm.Networking, c fuzz.Continue) { func fuzzNetworking(obj *kubeadm.Networking, c fuzz.Continue) {

View File

@ -95,10 +95,16 @@ type ClusterConfiguration struct {
// Scheduler contains extra settings for the scheduler control plane component // Scheduler contains extra settings for the scheduler control plane component
Scheduler ControlPlaneComponent Scheduler ControlPlaneComponent
// DNS defines the options for the DNS add-on installed in the cluster.
DNS DNS
// CertificatesDir specifies where to store or look for all required certificates. // CertificatesDir specifies where to store or look for all required certificates.
CertificatesDir string CertificatesDir string
// ImageRepository is the container registry to pull control plane images from. // ImageRepository sets the container registry to pull images from.
// If empty, `k8s.gcr.io` will be used by default; in case of kubernetes version is a CI build (kubernetes version starts with `ci/` or `ci-cross/`)
// `gcr.io/kubernetes-ci-images` will be used as a default for control plane components and for kube-proxy, while `k8s.gcr.io`
// will be used for all the other images.
ImageRepository string ImageRepository string
// CIImageRepository is the container registry for core images generated by CI. // CIImageRepository is the container registry for core images generated by CI.
@ -122,6 +128,8 @@ type ClusterConfiguration struct {
// ControlPlaneComponent holds settings common to control plane component of the cluster // ControlPlaneComponent holds settings common to control plane component of the cluster
type ControlPlaneComponent struct { type ControlPlaneComponent struct {
// ExtraArgs is an extra set of flags to pass to the control plane component. // ExtraArgs is an extra set of flags to pass to the control plane component.
// TODO: This is temporary and ideally we would like to switch all components to
// use ComponentConfig + ConfigMaps.
ExtraArgs map[string]string ExtraArgs map[string]string
// ExtraVolumes is an extra set of host volumes, mounted to the control plane component. // ExtraVolumes is an extra set of host volumes, mounted to the control plane component.
@ -139,6 +147,40 @@ type APIServer struct {
TimeoutForControlPlane *metav1.Duration TimeoutForControlPlane *metav1.Duration
} }
// DNSAddOnType defines string identifying DNS add-on types
type DNSAddOnType string
const (
// CoreDNS add-on type
CoreDNS DNSAddOnType = "CoreDNS"
// KubeDNS add-on type
KubeDNS DNSAddOnType = "kube-dns"
)
// DNS defines the DNS addon that should be used in the cluster
type DNS struct {
// Type defines the DNS add-on to be used
Type DNSAddOnType
// ImageMeta allows to customize the image used for the DNS component
ImageMeta `json:",inline"`
}
// ImageMeta allows to customize the image used for components that are not
// originated from the Kubernetes/Kubernetes release process
type ImageMeta struct {
// ImageRepository sets the container registry to pull images from.
// if not set, the ImageRepository defined in ClusterConfiguration will be used instead.
ImageRepository string
// ImageTag allows to specify a tag for the image.
// In case this value is set, kubeadm does not change automatically the version of the above components during upgrades.
ImageTag string
//TODO: evaluate if we need also a ImageName based on user feedbacks
}
// ComponentConfigs holds known internal ComponentConfig types for other components // ComponentConfigs holds known internal ComponentConfig types for other components
type ComponentConfigs struct { type ComponentConfigs struct {
// Kubelet holds the ComponentConfiguration for the kubelet // Kubelet holds the ComponentConfiguration for the kubelet
@ -239,11 +281,8 @@ type Etcd struct {
// LocalEtcd describes that kubeadm should run an etcd cluster locally // LocalEtcd describes that kubeadm should run an etcd cluster locally
type LocalEtcd struct { type LocalEtcd struct {
// ImageMeta allows to customize the container used for etcd
// Image specifies which container image to use for running etcd. ImageMeta `json:",inline"`
// If empty, automatically populated by kubeadm using the image
// repository and default etcd version.
Image string
// DataDir is the directory etcd will place its data. // DataDir is the directory etcd will place its data.
// Defaults to "/var/lib/etcd". // Defaults to "/var/lib/etcd".

View File

@ -17,16 +17,21 @@ limitations under the License.
package v1alpha3 package v1alpha3
import ( import (
"github.com/pkg/errors" "regexp"
"strings"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/conversion"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/images" "k8s.io/kubernetes/cmd/kubeadm/app/images"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
) )
var imageRegEx = regexp.MustCompile(`(?P<repository>.+/)(?P<image>[^:]+)(?P<tag>:.+)`)
func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error { func Convert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in *InitConfiguration, out *kubeadm.InitConfiguration, s conversion.Scope) error {
if err := autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s); err != nil { if err := autoConvert_v1alpha3_InitConfiguration_To_kubeadm_InitConfiguration(in, out, s); err != nil {
return err return err
@ -133,6 +138,14 @@ func Convert_v1alpha3_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *C
return err return err
} }
// converting v1alpha3 featureGate CoreDNS to internal DNS.Type
if features.Enabled(in.FeatureGates, features.CoreDNS) {
out.DNS.Type = kubeadm.CoreDNS
} else {
out.DNS.Type = kubeadm.KubeDNS
}
delete(out.FeatureGates, features.CoreDNS)
return nil return nil
} }
@ -174,11 +187,19 @@ func Convert_kubeadm_ClusterConfiguration_To_v1alpha3_ClusterConfiguration(in *k
} }
if in.UseHyperKubeImage { if in.UseHyperKubeImage {
out.UnifiedControlPlaneImage = images.GetKubeControlPlaneImage("", in) out.UnifiedControlPlaneImage = images.GetKubernetesImage("", in)
} else { } else {
out.UnifiedControlPlaneImage = "" out.UnifiedControlPlaneImage = ""
} }
// converting internal DNS.Type to v1alpha3 featureGate CoreDNS (this is only for getting roundtrip passing, but it is never used in reality)
if out.FeatureGates == nil {
out.FeatureGates = map[string]bool{}
}
if in.DNS.Type == kubeadm.KubeDNS {
out.FeatureGates[features.CoreDNS] = false
}
return nil return nil
} }
@ -225,5 +246,52 @@ func convertSlice_kubeadm_HostPathMount_To_v1alpha3_HostPathMount(in *[]kubeadm.
} else { } else {
*out = nil *out = nil
} }
return nil
}
func Convert_v1alpha3_LocalEtcd_To_kubeadm_LocalEtcd(in *LocalEtcd, out *kubeadm.LocalEtcd, s conversion.Scope) error {
if err := autoConvert_v1alpha3_LocalEtcd_To_kubeadm_LocalEtcd(in, out, s); err != nil {
return err
}
var err error
out.ImageMeta, err = etcdImageToImageMeta(in.Image)
return err
}
func etcdImageToImageMeta(image string) (kubeadm.ImageMeta, error) {
// empty image -> empty image meta
if image == "" {
return kubeadm.ImageMeta{}, nil
}
matches := imageRegEx.FindStringSubmatch(image)
if len(matches) != 4 {
return kubeadm.ImageMeta{}, errors.New("Conversion Error: kubeadm does not support converting v1alpha3 configurations with etcd image without explicit repository or tag definition. Please fix the image name")
}
imageRepository := strings.TrimSuffix(matches[1], "/")
imageName := matches[2]
imageTag := strings.TrimPrefix(matches[3], ":")
if imageName != constants.Etcd {
return kubeadm.ImageMeta{}, errors.New("Conversion Error: kubeadm does not support converting v1alpha3 configurations with etcd imageName different than etcd. Please fix the image name")
}
return kubeadm.ImageMeta{
ImageRepository: imageRepository,
ImageTag: imageTag,
}, nil
}
func Convert_kubeadm_LocalEtcd_To_v1alpha3_LocalEtcd(in *kubeadm.LocalEtcd, out *LocalEtcd, s conversion.Scope) error {
if err := autoConvert_kubeadm_LocalEtcd_To_v1alpha3_LocalEtcd(in, out, s); err != nil {
return err
}
// converting internal LocalEtcd.ImageMeta to v1alpha3 LocalEtcd.Image (this is only for getting roundtrip passing, but it is
// never used in reality)
return nil return nil
} }

View File

@ -14,48 +14,44 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package v1alpha3_test package v1alpha3
import ( import (
"testing" "testing"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
) )
func TestJoinConfigurationConversion(t *testing.T) { func TestJoinConfigurationConversion(t *testing.T) {
testcases := map[string]struct { testcases := map[string]struct {
old *v1alpha3.JoinConfiguration old *JoinConfiguration
expectedErr string expectedError bool
}{ }{
"conversion succeeds": { "conversion succeeds": {
old: &v1alpha3.JoinConfiguration{}, old: &JoinConfiguration{},
expectedErr: "", expectedError: false,
}, },
"cluster name fails to be converted": { "cluster name fails to be converted": {
old: &v1alpha3.JoinConfiguration{ old: &JoinConfiguration{
ClusterName: "kubernetes", ClusterName: "kubernetes",
}, },
expectedErr: "clusterName has been removed from JoinConfiguration and clusterName from ClusterConfiguration will be used instead. Please cleanup JoinConfiguration.ClusterName fields", expectedError: true,
}, },
"feature gates fails to be converted": { "feature gates fails to be converted": {
old: &v1alpha3.JoinConfiguration{ old: &JoinConfiguration{
FeatureGates: map[string]bool{ FeatureGates: map[string]bool{
"someGate": true, "someGate": true,
}, },
}, },
expectedErr: "featureGates has been removed from JoinConfiguration and featureGates from ClusterConfiguration will be used instead. Please cleanup JoinConfiguration.FeatureGates fields", expectedError: true,
}, },
} }
for _, tc := range testcases { for _, tc := range testcases {
internal := &kubeadm.JoinConfiguration{} internal := &kubeadm.JoinConfiguration{}
err := scheme.Scheme.Convert(tc.old, internal, nil) err := Convert_v1alpha3_JoinConfiguration_To_kubeadm_JoinConfiguration(tc.old, internal, nil)
if len(tc.expectedErr) != 0 { if (err != nil) != tc.expectedError {
testutil.AssertError(t, err, tc.expectedErr) t.Errorf("ImageToImageMeta returned unexpected error: %v, saw: %v", tc.expectedError, (err != nil))
} else if err != nil { return
t.Errorf("no error was expected but '%s' was found", err)
} }
} }
} }
@ -63,19 +59,19 @@ func TestJoinConfigurationConversion(t *testing.T) {
func TestConvertToUseHyperKubeImage(t *testing.T) { func TestConvertToUseHyperKubeImage(t *testing.T) {
tests := []struct { tests := []struct {
desc string desc string
in *v1alpha3.ClusterConfiguration in *ClusterConfiguration
useHyperKubeImage bool useHyperKubeImage bool
expectedErr bool expectedErr bool
}{ }{
{ {
desc: "unset UnifiedControlPlaneImage sets UseHyperKubeImage to false", desc: "unset UnifiedControlPlaneImage sets UseHyperKubeImage to false",
in: &v1alpha3.ClusterConfiguration{}, in: &ClusterConfiguration{},
useHyperKubeImage: false, useHyperKubeImage: false,
expectedErr: false, expectedErr: false,
}, },
{ {
desc: "matching UnifiedControlPlaneImage sets UseHyperKubeImage to true", desc: "matching UnifiedControlPlaneImage sets UseHyperKubeImage to true",
in: &v1alpha3.ClusterConfiguration{ in: &ClusterConfiguration{
ImageRepository: "k8s.gcr.io", ImageRepository: "k8s.gcr.io",
KubernetesVersion: "v1.12.2", KubernetesVersion: "v1.12.2",
UnifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.12.2", UnifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.12.2",
@ -85,7 +81,7 @@ func TestConvertToUseHyperKubeImage(t *testing.T) {
}, },
{ {
desc: "mismatching UnifiedControlPlaneImage tag causes an error", desc: "mismatching UnifiedControlPlaneImage tag causes an error",
in: &v1alpha3.ClusterConfiguration{ in: &ClusterConfiguration{
ImageRepository: "k8s.gcr.io", ImageRepository: "k8s.gcr.io",
KubernetesVersion: "v1.12.0", KubernetesVersion: "v1.12.0",
UnifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.12.2", UnifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.12.2",
@ -94,7 +90,7 @@ func TestConvertToUseHyperKubeImage(t *testing.T) {
}, },
{ {
desc: "mismatching UnifiedControlPlaneImage repo causes an error", desc: "mismatching UnifiedControlPlaneImage repo causes an error",
in: &v1alpha3.ClusterConfiguration{ in: &ClusterConfiguration{
ImageRepository: "my.repo", ImageRepository: "my.repo",
KubernetesVersion: "v1.12.2", KubernetesVersion: "v1.12.2",
UnifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.12.2", UnifiedControlPlaneImage: "k8s.gcr.io/hyperkube:v1.12.2",
@ -103,7 +99,7 @@ func TestConvertToUseHyperKubeImage(t *testing.T) {
}, },
{ {
desc: "mismatching UnifiedControlPlaneImage image name causes an error", desc: "mismatching UnifiedControlPlaneImage image name causes an error",
in: &v1alpha3.ClusterConfiguration{ in: &ClusterConfiguration{
ImageRepository: "k8s.gcr.io", ImageRepository: "k8s.gcr.io",
KubernetesVersion: "v1.12.2", KubernetesVersion: "v1.12.2",
UnifiedControlPlaneImage: "k8s.gcr.io/otherimage:v1.12.2", UnifiedControlPlaneImage: "k8s.gcr.io/otherimage:v1.12.2",
@ -115,7 +111,7 @@ func TestConvertToUseHyperKubeImage(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
out := &kubeadm.ClusterConfiguration{} out := &kubeadm.ClusterConfiguration{}
err := v1alpha3.Convert_v1alpha3_UnifiedControlPlaneImage_To_kubeadm_UseHyperKubeImage(test.in, out) err := Convert_v1alpha3_UnifiedControlPlaneImage_To_kubeadm_UseHyperKubeImage(test.in, out)
if test.expectedErr { if test.expectedErr {
if err == nil { if err == nil {
t.Fatalf("unexpected success, UseHyperKubeImage: %t", out.UseHyperKubeImage) t.Fatalf("unexpected success, UseHyperKubeImage: %t", out.UseHyperKubeImage)
@ -131,3 +127,59 @@ func TestConvertToUseHyperKubeImage(t *testing.T) {
}) })
} }
} }
func TestEtcdImageToImageMeta(t *testing.T) {
tests := []struct {
name string
image string
expectedImageMeta kubeadm.ImageMeta
expectedError bool
}{
{
name: "Empty image -> Empty image meta",
image: "",
expectedImageMeta: kubeadm.ImageMeta{
ImageRepository: "",
ImageTag: "",
},
},
{
name: "image with tag and repository",
image: "custom.repo/etcd:custom.tag",
expectedImageMeta: kubeadm.ImageMeta{
ImageRepository: "custom.repo",
ImageTag: "custom.tag",
},
},
{
name: "image with custom imageName",
image: "real.repo/custom-image-name-for-etcd:real.tag",
expectedError: true,
},
{
name: "image without repository",
image: "etcd:real.tag",
expectedError: true,
},
{
name: "image without tag",
image: "real.repo/etcd",
expectedError: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ret, err := etcdImageToImageMeta(test.image)
if (err != nil) != test.expectedError {
t.Errorf("etcdImageToImageMeta returned unexpected error: %v, saw: %v", test.expectedError, (err != nil))
return
}
if ret != test.expectedImageMeta {
t.Errorf("etcdImageToImageMeta returned unexpected ImageMeta: %v, saw: %v", test.expectedImageMeta, ret)
}
})
}
}

View File

@ -99,6 +99,7 @@ func SetDefaults_ClusterConfiguration(obj *ClusterConfiguration) {
obj.ClusterName = DefaultClusterName obj.ClusterName = DefaultClusterName
} }
SetDefaults_DNS(obj)
SetDefaults_Etcd(obj) SetDefaults_Etcd(obj)
SetDefaults_AuditPolicyConfiguration(obj) SetDefaults_AuditPolicyConfiguration(obj)
SetDefaults_APIServer(&obj.APIServer) SetDefaults_APIServer(&obj.APIServer)
@ -113,7 +114,14 @@ func SetDefaults_APIServer(obj *APIServer) {
} }
} }
// SetDefaults_Etcd assigns default values for the Proxy // SetDefaults_DNS assigns default values for the DNS component
func SetDefaults_DNS(obj *ClusterConfiguration) {
if obj.DNS.Type == "" {
obj.DNS.Type = CoreDNS
}
}
// SetDefaults_Etcd assigns default values for the proxy
func SetDefaults_Etcd(obj *ClusterConfiguration) { func SetDefaults_Etcd(obj *ClusterConfiguration) {
if obj.Etcd.External == nil && obj.Etcd.Local == nil { if obj.Etcd.External == nil && obj.Etcd.Local == nil {
obj.Etcd.Local = &LocalEtcd{} obj.Etcd.Local = &LocalEtcd{}

View File

@ -91,10 +91,16 @@ type ClusterConfiguration struct {
// Scheduler contains extra settings for the scheduler control plane component // Scheduler contains extra settings for the scheduler control plane component
Scheduler ControlPlaneComponent `json:"scheduler,omitempty"` Scheduler ControlPlaneComponent `json:"scheduler,omitempty"`
// DNS defines the options for the DNS add-on installed in the cluster.
DNS DNS `json:"dns"`
// CertificatesDir specifies where to store or look for all required certificates. // CertificatesDir specifies where to store or look for all required certificates.
CertificatesDir string `json:"certificatesDir"` CertificatesDir string `json:"certificatesDir"`
// ImageRepository what container registry to pull control plane images from // ImageRepository sets the container registry to pull images from.
// If empty, `k8s.gcr.io` will be used by default; in case of kubernetes version is a CI build (kubernetes version starts with `ci/` or `ci-cross/`)
// `gcr.io/kubernetes-ci-images` will be used as a default for control plane components and for kube-proxy, while `k8s.gcr.io`
// will be used for all the other images.
ImageRepository string `json:"imageRepository"` ImageRepository string `json:"imageRepository"`
// UseHyperKubeImage controls if hyperkube should be used for Kubernetes components instead of their respective separate images // UseHyperKubeImage controls if hyperkube should be used for Kubernetes components instead of their respective separate images
@ -113,6 +119,8 @@ type ClusterConfiguration struct {
// ControlPlaneComponent holds settings common to control plane component of the cluster // ControlPlaneComponent holds settings common to control plane component of the cluster
type ControlPlaneComponent struct { type ControlPlaneComponent struct {
// ExtraArgs is an extra set of flags to pass to the control plane component. // ExtraArgs is an extra set of flags to pass to the control plane component.
// TODO: This is temporary and ideally we would like to switch all components to
// use ComponentConfig + ConfigMaps.
ExtraArgs map[string]string `json:"extraArgs,omitempty"` ExtraArgs map[string]string `json:"extraArgs,omitempty"`
// ExtraVolumes is an extra set of host volumes, mounted to the control plane component. // ExtraVolumes is an extra set of host volumes, mounted to the control plane component.
@ -130,6 +138,40 @@ type APIServer struct {
TimeoutForControlPlane *metav1.Duration `json:"timeoutForControlPlane,omitempty"` TimeoutForControlPlane *metav1.Duration `json:"timeoutForControlPlane,omitempty"`
} }
// DNSAddOnType defines string identifying DNS add-on types
type DNSAddOnType string
const (
// CoreDNS add-on type
CoreDNS DNSAddOnType = "CoreDNS"
// KubeDNS add-on type
KubeDNS DNSAddOnType = "kube-dns"
)
// DNS defines the DNS addon that should be used in the cluster
type DNS struct {
// Type defines the DNS add-on to be used
Type DNSAddOnType `json:"type"`
// ImageMeta allows to customize the image used for the DNS component
ImageMeta `json:",inline"`
}
// ImageMeta allows to customize the image used for components that are not
// originated from the Kubernetes/Kubernetes release process
type ImageMeta struct {
// ImageRepository sets the container registry to pull images from.
// if not set, the ImageRepository defined in ClusterConfiguration will be used instead.
ImageRepository string `json:"imageRepository,omitempty"`
// ImageTag allows to specify a tag for the image.
// In case this value is set, kubeadm does not change automatically the version of the above components during upgrades.
ImageTag string `json:"imageTag,omitempty"`
//TODO: evaluate if we need also a ImageName based on user feedbacks
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config // ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config
@ -220,11 +262,8 @@ type Etcd struct {
// LocalEtcd describes that kubeadm should run an etcd cluster locally // LocalEtcd describes that kubeadm should run an etcd cluster locally
type LocalEtcd struct { type LocalEtcd struct {
// ImageMeta allows to customize the container used for etcd
// Image specifies which container image to use for running etcd. ImageMeta `json:",inline"`
// If empty, automatically populated by kubeadm using the image
// repository and default etcd version.
Image string `json:"image"`
// DataDir is the directory etcd will place its data. // DataDir is the directory etcd will place its data.
// Defaults to "/var/lib/etcd". // Defaults to "/var/lib/etcd".

View File

@ -27,7 +27,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
@ -407,13 +406,12 @@ func ValidateMixedArguments(flag *pflag.FlagSet) error {
// ValidateFeatureGates validates provided feature gates // ValidateFeatureGates validates provided feature gates
func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) field.ErrorList { func ValidateFeatureGates(featureGates map[string]bool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
validFeatures := features.Keys(features.InitFeatureGates)
// check valid feature names are provided // check valid feature names are provided
for k := range featureGates { for k := range featureGates {
if !features.Supports(features.InitFeatureGates, k) { if !features.Supports(features.InitFeatureGates, k) {
allErrs = append(allErrs, field.Invalid(fldPath, featureGates, allErrs = append(allErrs, field.Invalid(fldPath, featureGates,
fmt.Sprintf("%s is not a valid feature name. Valid features are: %s", k, validFeatures))) fmt.Sprintf("%s is not a valid feature name.", k)))
} }
} }

View File

@ -23,7 +23,6 @@ import (
"time" "time"
"github.com/spf13/pflag" "github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
@ -605,14 +604,17 @@ func TestValidateFeatureGates(t *testing.T) {
}{ }{
{featureFlag{"Unknown": true}, false}, {featureFlag{"Unknown": true}, false},
{featureFlag{"Unknown": false}, false}, {featureFlag{"Unknown": false}, false},
{featureFlag{"CoreDNS": true}, true}, {featureFlag{"CoreDNS": true}, false},
{featureFlag{"CoreDNS": false}, true}, {featureFlag{"CoreDNS": false}, false},
{featureFlag{"DynamicKubeletConfig": true}, true},
{featureFlag{"DynamicKubeletConfig": false}, true},
} }
for _, rt := range tests { for _, rt := range tests {
actual := ValidateFeatureGates(rt.featureGates, nil) actual := ValidateFeatureGates(rt.featureGates, nil)
if (len(actual) == 0) != rt.expected { if (len(actual) == 0) != rt.expected {
t.Errorf( t.Errorf(
"failed featureGates:\n\texpected: %t\n\t actual: %t", "failed featureGates %v:\n\texpected: %t\n\t actual: %t",
rt.featureGates,
rt.expected, rt.expected,
(len(actual) == 0), (len(actual) == 0),
) )

View File

@ -29,11 +29,9 @@ import (
"github.com/renstrom/dedent" "github.com/renstrom/dedent"
"github.com/spf13/cobra" "github.com/spf13/cobra"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs" "k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
"k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime" utilruntime "k8s.io/kubernetes/cmd/kubeadm/app/util/runtime"
@ -89,8 +87,6 @@ func TestImagesListRunWithCustomConfigPath(t *testing.T) {
apiVersion: kubeadm.k8s.io/v1beta1 apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration kind: ClusterConfiguration
kubernetesVersion: v1.11.0 kubernetesVersion: v1.11.0
featureGates:
CoreDNS: true
`)), `)),
}, },
} }
@ -167,14 +163,23 @@ func TestConfigImagesListRunWithoutPath(t *testing.T) {
name: "coredns enabled", name: "coredns enabled",
cfg: kubeadmapiv1beta1.InitConfiguration{ cfg: kubeadmapiv1beta1.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{ ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{
FeatureGates: map[string]bool{
features.CoreDNS: true,
},
KubernetesVersion: dummyKubernetesVersion, KubernetesVersion: dummyKubernetesVersion,
}, },
}, },
expectedImages: defaultNumberOfImages, expectedImages: defaultNumberOfImages,
}, },
{
name: "kube-dns enabled",
cfg: kubeadmapiv1beta1.InitConfiguration{
ClusterConfiguration: kubeadmapiv1beta1.ClusterConfiguration{
KubernetesVersion: dummyKubernetesVersion,
DNS: kubeadmapiv1beta1.DNS{
Type: kubeadmapiv1beta1.KubeDNS,
},
},
},
expectedImages: defaultNumberOfImages + 2,
},
} }
for _, tc := range testcases { for _, tc := range testcases {

View File

@ -41,6 +41,9 @@ func TestPrintConfiguration(t *testing.T) {
DataDir: "/some/path", DataDir: "/some/path",
}, },
}, },
DNS: kubeadmapi.DNS{
Type: kubeadmapi.CoreDNS,
},
}, },
expectedBytes: []byte(`[upgrade/config] Configuration used: expectedBytes: []byte(`[upgrade/config] Configuration used:
apiServer: {} apiServer: {}
@ -51,10 +54,11 @@ func TestPrintConfiguration(t *testing.T) {
certificatesDir: "" certificatesDir: ""
controlPlaneEndpoint: "" controlPlaneEndpoint: ""
controllerManager: {} controllerManager: {}
dns:
type: CoreDNS
etcd: etcd:
local: local:
dataDir: /some/path dataDir: /some/path
image: ""
imageRepository: "" imageRepository: ""
kind: ClusterConfiguration kind: ClusterConfiguration
kubernetesVersion: v1.7.1 kubernetesVersion: v1.7.1
@ -76,6 +80,9 @@ func TestPrintConfiguration(t *testing.T) {
Endpoints: []string{"https://one-etcd-instance:2379"}, Endpoints: []string{"https://one-etcd-instance:2379"},
}, },
}, },
DNS: kubeadmapi.DNS{
Type: kubeadmapi.CoreDNS,
},
}, },
expectedBytes: []byte(`[upgrade/config] Configuration used: expectedBytes: []byte(`[upgrade/config] Configuration used:
apiServer: {} apiServer: {}
@ -86,6 +93,8 @@ func TestPrintConfiguration(t *testing.T) {
certificatesDir: "" certificatesDir: ""
controlPlaneEndpoint: "" controlPlaneEndpoint: ""
controllerManager: {} controllerManager: {}
dns:
type: CoreDNS
etcd: etcd:
external: external:
caFile: "" caFile: ""

View File

@ -28,9 +28,9 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/util/version" "k8s.io/apimachinery/pkg/util/version"
"k8s.io/klog" "k8s.io/klog"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation" "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config" configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
@ -121,7 +121,7 @@ func RunPlan(flags *planFlags) error {
// Compute which upgrade possibilities there are // Compute which upgrade possibilities there are
klog.V(1).Infof("[upgrade/plan] computing upgrade possibilities") klog.V(1).Infof("[upgrade/plan] computing upgrade possibilities")
availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, flags.allowExperimentalUpgrades, flags.allowRCUpgrades, etcdClient, upgradeVars.cfg.FeatureGates, upgradeVars.client) availUpgrades, err := upgrade.GetAvailableUpgrades(upgradeVars.versionGetter, flags.allowExperimentalUpgrades, flags.allowRCUpgrades, etcdClient, upgradeVars.cfg.DNS.Type, upgradeVars.client)
if err != nil { if err != nil {
return errors.Wrap(err, "[upgrade/versions] FATAL") return errors.Wrap(err, "[upgrade/versions] FATAL")
} }
@ -207,19 +207,19 @@ func printAvailableUpgrades(upgrades []upgrade.Upgrade, w io.Writer, isExternalE
coreDNSBeforeVersion, coreDNSAfterVersion, kubeDNSBeforeVersion, kubeDNSAfterVersion := "", "", "", "" coreDNSBeforeVersion, coreDNSAfterVersion, kubeDNSBeforeVersion, kubeDNSAfterVersion := "", "", "", ""
switch upgrade.Before.DNSType { switch upgrade.Before.DNSType {
case constants.CoreDNS: case kubeadmapi.CoreDNS:
printCoreDNS = true printCoreDNS = true
coreDNSBeforeVersion = upgrade.Before.DNSVersion coreDNSBeforeVersion = upgrade.Before.DNSVersion
case constants.KubeDNS: case kubeadmapi.KubeDNS:
printKubeDNS = true printKubeDNS = true
kubeDNSBeforeVersion = upgrade.Before.DNSVersion kubeDNSBeforeVersion = upgrade.Before.DNSVersion
} }
switch upgrade.After.DNSType { switch upgrade.After.DNSType {
case constants.CoreDNS: case kubeadmapi.CoreDNS:
printCoreDNS = true printCoreDNS = true
coreDNSAfterVersion = upgrade.After.DNSVersion coreDNSAfterVersion = upgrade.After.DNSVersion
case constants.KubeDNS: case kubeadmapi.KubeDNS:
printKubeDNS = true printKubeDNS = true
kubeDNSAfterVersion = upgrade.After.DNSVersion kubeDNSAfterVersion = upgrade.After.DNSVersion
} }

View File

@ -21,6 +21,7 @@ import (
"reflect" "reflect"
"testing" "testing"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade"
) )
@ -91,14 +92,14 @@ func TestPrintAvailableUpgrades(t *testing.T) {
"v1.8.1": 1, "v1.8.1": 1,
}, },
KubeadmVersion: "v1.8.2", KubeadmVersion: "v1.8.2",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.8.3", KubeVersion: "v1.8.3",
KubeadmVersion: "v1.8.3", KubeadmVersion: "v1.8.3",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
@ -139,14 +140,14 @@ _____________________________________________________________________
"v1.8.3": 1, "v1.8.3": 1,
}, },
KubeadmVersion: "v1.9.0", KubeadmVersion: "v1.9.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.9.0", KubeVersion: "v1.9.0",
KubeadmVersion: "v1.9.0", KubeadmVersion: "v1.9.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.13", DNSVersion: "1.14.13",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -185,14 +186,14 @@ _____________________________________________________________________
"v1.8.3": 1, "v1.8.3": 1,
}, },
KubeadmVersion: "v1.8.3", KubeadmVersion: "v1.8.3",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.8.5", KubeVersion: "v1.8.5",
KubeadmVersion: "v1.8.3", KubeadmVersion: "v1.8.3",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
@ -205,14 +206,14 @@ _____________________________________________________________________
"v1.8.3": 1, "v1.8.3": 1,
}, },
KubeadmVersion: "v1.8.3", KubeadmVersion: "v1.8.3",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.9.0", KubeVersion: "v1.9.0",
KubeadmVersion: "v1.9.0", KubeadmVersion: "v1.9.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.13", DNSVersion: "1.14.13",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -273,14 +274,14 @@ _____________________________________________________________________
"v1.8.5": 1, "v1.8.5": 1,
}, },
KubeadmVersion: "v1.8.5", KubeadmVersion: "v1.8.5",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.9.0-beta.1", KubeVersion: "v1.9.0-beta.1",
KubeadmVersion: "v1.9.0-beta.1", KubeadmVersion: "v1.9.0-beta.1",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.13", DNSVersion: "1.14.13",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -321,14 +322,14 @@ _____________________________________________________________________
"v1.8.5": 1, "v1.8.5": 1,
}, },
KubeadmVersion: "v1.8.5", KubeadmVersion: "v1.8.5",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.9.0-rc.1", KubeVersion: "v1.9.0-rc.1",
KubeadmVersion: "v1.9.0-rc.1", KubeadmVersion: "v1.9.0-rc.1",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.13", DNSVersion: "1.14.13",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -370,14 +371,14 @@ _____________________________________________________________________
"v1.9.3": 2, "v1.9.3": 2,
}, },
KubeadmVersion: "v1.9.2", KubeadmVersion: "v1.9.2",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.9.3", KubeVersion: "v1.9.3",
KubeadmVersion: "v1.9.3", KubeadmVersion: "v1.9.3",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.8", DNSVersion: "1.14.8",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -420,14 +421,14 @@ _____________________________________________________________________
"v1.9.2": 1, "v1.9.2": 1,
}, },
KubeadmVersion: "v1.9.2", KubeadmVersion: "v1.9.2",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.5", DNSVersion: "1.14.5",
EtcdVersion: "3.0.17", EtcdVersion: "3.0.17",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.9.3", KubeVersion: "v1.9.3",
KubeadmVersion: "v1.9.3", KubeadmVersion: "v1.9.3",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.8", DNSVersion: "1.14.8",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -472,14 +473,14 @@ _____________________________________________________________________
"v1.10.2": 1, "v1.10.2": 1,
}, },
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.7", DNSVersion: "1.14.7",
EtcdVersion: "3.1.11", EtcdVersion: "3.1.11",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.11.0", KubeVersion: "v1.11.0",
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -519,14 +520,14 @@ _____________________________________________________________________
"v1.10.2": 1, "v1.10.2": 1,
}, },
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.5", DNSVersion: "1.0.5",
EtcdVersion: "3.1.11", EtcdVersion: "3.1.11",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.11.0", KubeVersion: "v1.11.0",
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -565,14 +566,14 @@ _____________________________________________________________________
"v1.10.2": 1, "v1.10.2": 1,
}, },
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.11", EtcdVersion: "3.1.11",
}, },
After: upgrade.ClusterState{ After: upgrade.ClusterState{
KubeVersion: "v1.11.0", KubeVersion: "v1.11.0",
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.9", DNSVersion: "1.14.9",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },

View File

@ -30,6 +30,7 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/version" "k8s.io/apimachinery/pkg/util/version"
bootstrapapi "k8s.io/cluster-bootstrap/token/api" bootstrapapi "k8s.io/cluster-bootstrap/token/api"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator" "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
) )
@ -283,10 +284,29 @@ const (
// DefaultCIImageRepository points to image registry where CI uploads images from ci-cross build job // DefaultCIImageRepository points to image registry where CI uploads images from ci-cross build job
DefaultCIImageRepository = "gcr.io/kubernetes-ci-images" DefaultCIImageRepository = "gcr.io/kubernetes-ci-images"
// CoreDNS defines a variable used internally when referring to the CoreDNS addon for a cluster // CoreDNSConfigMap specifies in what ConfigMap in the kube-system namespace the CoreDNS config should be stored
CoreDNS = "coredns" CoreDNSConfigMap = "coredns"
// KubeDNS defines a variable used internally when referring to the kube-dns addon for a cluster
KubeDNS = "kube-dns" // CoreDNSDeploymentName specifies the name of the Deployment for CoreDNS add-on
CoreDNSDeploymentName = "coredns"
// CoreDNSImageName specifies the name of the image for CoreDNS add-on
CoreDNSImageName = "coredns"
// KubeDNSConfigMap specifies in what ConfigMap in the kube-system namespace the kube-dns config should be stored
KubeDNSConfigMap = "kube-dns"
// KubeDNSDeploymentName specifies the name of the Deployment for kube-dns add-on
KubeDNSDeploymentName = "kube-dns"
// KubeDNSKubeDNSImageName specifies the name of the image for the kubedns container in the kube-dns add-on
KubeDNSKubeDNSImageName = "k8s-dns-kube-dns"
// KubeDNSSidecarImageName specifies the name of the image for the sidecar container in the kube-dns add-on
KubeDNSSidecarImageName = "k8s-dns-sidecar"
// KubeDNSDnsMasqNannyImageName specifies the name of the image for the dnsmasq container in the kube-dns add-on
KubeDNSDnsMasqNannyImageName = "k8s-dns-dnsmasq-nanny"
// CRICtlPackage defines the go package that installs crictl // CRICtlPackage defines the go package that installs crictl
CRICtlPackage = "github.com/kubernetes-incubator/cri-tools/cmd/crictl" CRICtlPackage = "github.com/kubernetes-incubator/cri-tools/cmd/crictl"
@ -474,12 +494,12 @@ func GetStaticPodAuditPolicyFile() string {
} }
// GetDNSVersion is a handy function that returns the DNS version by DNS type // GetDNSVersion is a handy function that returns the DNS version by DNS type
func GetDNSVersion(dnsType string) string { func GetDNSVersion(dnsType kubeadmapi.DNSAddOnType) string {
switch dnsType { switch dnsType {
case CoreDNS: case kubeadmapi.KubeDNS:
return CoreDNSVersion
default:
return KubeDNSVersion return KubeDNSVersion
default:
return CoreDNSVersion
} }
} }

View File

@ -24,6 +24,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/version" "k8s.io/apimachinery/pkg/util/version"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
) )
func TestGetStaticPodDirectory(t *testing.T) { func TestGetStaticPodDirectory(t *testing.T) {
@ -203,15 +204,15 @@ func TestEtcdSupportedVersion(t *testing.T) {
func TestGetKubeDNSVersion(t *testing.T) { func TestGetKubeDNSVersion(t *testing.T) {
var tests = []struct { var tests = []struct {
dns string dns kubeadmapi.DNSAddOnType
expected string expected string
}{ }{
{ {
dns: KubeDNS, dns: kubeadmapi.KubeDNS,
expected: KubeDNSVersion, expected: KubeDNSVersion,
}, },
{ {
dns: CoreDNS, dns: kubeadmapi.CoreDNS,
expected: CoreDNSVersion, expected: CoreDNSVersion,
}, },
} }

View File

@ -23,7 +23,6 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/version" "k8s.io/apimachinery/pkg/util/version"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
) )
@ -40,9 +39,12 @@ const (
Auditing = "Auditing" Auditing = "Auditing"
) )
var coreDNSMessage = "featureGates:CoreDNS has been removed in v1.13\n" +
"\tUse kubeadm-config to select which DNS addon to install."
// InitFeatureGates are the default feature gates for the init command // InitFeatureGates are the default feature gates for the init command
var InitFeatureGates = FeatureList{ var InitFeatureGates = FeatureList{
CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.GA}}, CoreDNS: {FeatureSpec: utilfeature.FeatureSpec{Default: true, PreRelease: utilfeature.Deprecated}, HiddenInHelpText: true, DeprecationMessage: coreDNSMessage},
DynamicKubeletConfig: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}}, DynamicKubeletConfig: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Beta}},
Auditing: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}}, Auditing: {FeatureSpec: utilfeature.FeatureSpec{Default: false, PreRelease: utilfeature.Alpha}},
} }
@ -90,9 +92,9 @@ func Enabled(featureList map[string]bool, featureName string) bool {
// Supports indicates whether a feature name is supported on the given // Supports indicates whether a feature name is supported on the given
// feature set // feature set
func Supports(featureList FeatureList, featureName string) bool { func Supports(featureList FeatureList, featureName string) bool {
for k := range featureList { for k, v := range featureList {
if featureName == string(k) { if featureName == string(k) {
return true return v.PreRelease != utilfeature.Deprecated
} }
} }
return false return false

View File

@ -21,7 +21,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
) )
@ -30,8 +29,9 @@ func GetGenericImage(prefix, image, tag string) string {
return fmt.Sprintf("%s/%s:%s", prefix, image, tag) return fmt.Sprintf("%s/%s:%s", prefix, image, tag)
} }
// GetKubeControlPlaneImage generates and returns the image for the core Kubernetes components or returns the unified control plane image if specified // GetKubernetesImage generates and returns the image for the components managed in the Kubernetes main repository,
func GetKubeControlPlaneImage(image string, cfg *kubeadmapi.ClusterConfiguration) string { // including the control-plane components ad kube-proxy. If specified, the HyperKube image will be used.
func GetKubernetesImage(image string, cfg *kubeadmapi.ClusterConfiguration) string {
if cfg.UseHyperKubeImage { if cfg.UseHyperKubeImage {
image = constants.HyperKube image = constants.HyperKube
} }
@ -40,17 +40,44 @@ func GetKubeControlPlaneImage(image string, cfg *kubeadmapi.ClusterConfiguration
return GetGenericImage(repoPrefix, image, kubernetesImageTag) return GetGenericImage(repoPrefix, image, kubernetesImageTag)
} }
// GetEtcdImage generates and returns the image for etcd or returns cfg.Etcd.Local.Image if specified // GetDNSImage generates and returns the image for the DNS, that can be CoreDNS or kube-dns.
// Given that kube-dns uses 3 containers, an additional imageName parameter was added
func GetDNSImage(cfg *kubeadmapi.ClusterConfiguration, imageName string) string {
// DNS uses default image repository by default
dnsImageRepository := cfg.ImageRepository
// unless an override is specified
if cfg.DNS.ImageRepository != "" {
dnsImageRepository = cfg.DNS.ImageRepository
}
// DNS uses an imageTag that corresponds to the DNS version matching the Kubernetes version
dnsImageTag := constants.GetDNSVersion(cfg.DNS.Type)
// unless an override is specified
if cfg.DNS.ImageTag != "" {
dnsImageTag = cfg.DNS.ImageTag
}
return GetGenericImage(dnsImageRepository, imageName, dnsImageTag)
}
// GetEtcdImage generates and returns the image for etcd
func GetEtcdImage(cfg *kubeadmapi.ClusterConfiguration) string { func GetEtcdImage(cfg *kubeadmapi.ClusterConfiguration) string {
if cfg.Etcd.Local != nil && cfg.Etcd.Local.Image != "" { // Etcd uses default image repository by default
return cfg.Etcd.Local.Image etcdImageRepository := cfg.ImageRepository
// unless an override is specified
if cfg.Etcd.Local != nil && cfg.Etcd.Local.ImageRepository != "" {
etcdImageRepository = cfg.Etcd.Local.ImageRepository
} }
// Etcd uses an imageTag that corresponds to the etcd version matching the Kubernetes version
etcdImageTag := constants.DefaultEtcdVersion etcdImageTag := constants.DefaultEtcdVersion
etcdImageVersion, err := constants.EtcdSupportedVersion(cfg.KubernetesVersion) etcdVersion, err := constants.EtcdSupportedVersion(cfg.KubernetesVersion)
if err == nil { if err == nil {
etcdImageTag = etcdImageVersion.String() etcdImageTag = etcdVersion.String()
} }
return GetGenericImage(cfg.ImageRepository, constants.Etcd, etcdImageTag) // unless an override is specified
if cfg.Etcd.Local != nil && cfg.Etcd.Local.ImageTag != "" {
etcdImageTag = cfg.Etcd.Local.ImageTag
}
return GetGenericImage(etcdImageRepository, constants.Etcd, etcdImageTag)
} }
// GetAllImages returns a list of container images kubeadm expects to use on a control plane node // GetAllImages returns a list of container images kubeadm expects to use on a control plane node
@ -59,15 +86,15 @@ func GetAllImages(cfg *kubeadmapi.ClusterConfiguration) []string {
// start with core kubernetes images // start with core kubernetes images
if cfg.UseHyperKubeImage { if cfg.UseHyperKubeImage {
imgs = append(imgs, GetKubeControlPlaneImage(constants.HyperKube, cfg)) imgs = append(imgs, GetKubernetesImage(constants.HyperKube, cfg))
} else { } else {
imgs = append(imgs, GetKubeControlPlaneImage(constants.KubeAPIServer, cfg)) imgs = append(imgs, GetKubernetesImage(constants.KubeAPIServer, cfg))
imgs = append(imgs, GetKubeControlPlaneImage(constants.KubeControllerManager, cfg)) imgs = append(imgs, GetKubernetesImage(constants.KubeControllerManager, cfg))
imgs = append(imgs, GetKubeControlPlaneImage(constants.KubeScheduler, cfg)) imgs = append(imgs, GetKubernetesImage(constants.KubeScheduler, cfg))
imgs = append(imgs, GetKubeControlPlaneImage(constants.KubeProxy, cfg)) imgs = append(imgs, GetKubernetesImage(constants.KubeProxy, cfg))
} }
// pause, etcd and kube-dns are not available on the ci image repository so use the default image repository. // pause is not available on the ci image repository so use the default image repository.
imgs = append(imgs, GetGenericImage(cfg.ImageRepository, "pause", constants.PauseVersion)) imgs = append(imgs, GetGenericImage(cfg.ImageRepository, "pause", constants.PauseVersion))
// if etcd is not external then add the image as it will be required // if etcd is not external then add the image as it will be required
@ -76,12 +103,12 @@ func GetAllImages(cfg *kubeadmapi.ClusterConfiguration) []string {
} }
// Append the appropriate DNS images // Append the appropriate DNS images
if features.Enabled(cfg.FeatureGates, features.CoreDNS) { if cfg.DNS.Type == kubeadmapi.CoreDNS {
imgs = append(imgs, GetGenericImage(cfg.ImageRepository, constants.CoreDNS, constants.CoreDNSVersion)) imgs = append(imgs, GetDNSImage(cfg, constants.CoreDNSImageName))
} else { } else {
imgs = append(imgs, GetGenericImage(cfg.ImageRepository, "k8s-dns-kube-dns", constants.KubeDNSVersion)) imgs = append(imgs, GetDNSImage(cfg, constants.KubeDNSKubeDNSImageName))
imgs = append(imgs, GetGenericImage(cfg.ImageRepository, "k8s-dns-sidecar", constants.KubeDNSVersion)) imgs = append(imgs, GetDNSImage(cfg, constants.KubeDNSSidecarImageName))
imgs = append(imgs, GetGenericImage(cfg.ImageRepository, "k8s-dns-dnsmasq-nanny", constants.KubeDNSVersion)) imgs = append(imgs, GetDNSImage(cfg, constants.KubeDNSDnsMasqNannyImageName))
} }
return imgs return imgs

View File

@ -44,7 +44,7 @@ func TestGetGenericImage(t *testing.T) {
} }
} }
func TestGetKubeControlPlaneImage(t *testing.T) { func TestGetKubernetesImage(t *testing.T) {
var tests = []struct { var tests = []struct {
image string image string
expected string expected string
@ -84,10 +84,10 @@ func TestGetKubeControlPlaneImage(t *testing.T) {
}, },
} }
for _, rt := range tests { for _, rt := range tests {
actual := GetKubeControlPlaneImage(rt.image, rt.cfg) actual := GetKubernetesImage(rt.image, rt.cfg)
if actual != rt.expected { if actual != rt.expected {
t.Errorf( t.Errorf(
"failed GetKubeControlPlaneImage:\n\texpected: %s\n\t actual: %s", "failed GetKubernetesImage:\n\texpected: %s\n\t actual: %s",
rt.expected, rt.expected,
actual, actual,
) )
@ -101,14 +101,42 @@ func TestGetEtcdImage(t *testing.T) {
cfg *kubeadmapi.ClusterConfiguration cfg *kubeadmapi.ClusterConfiguration
}{ }{
{ {
expected: "override",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
ImageRepository: "real.repo",
KubernetesVersion: "1.12.0",
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{},
},
},
expected: "real.repo/etcd:3.2.24",
},
{
cfg: &kubeadmapi.ClusterConfiguration{
ImageRepository: "real.repo",
KubernetesVersion: "1.12.0",
Etcd: kubeadmapi.Etcd{ Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{ Local: &kubeadmapi.LocalEtcd{
Image: "override", ImageMeta: kubeadmapi.ImageMeta{
ImageTag: "override",
},
}, },
}, },
}, },
expected: "real.repo/etcd:override",
},
{
cfg: &kubeadmapi.ClusterConfiguration{
ImageRepository: "real.repo",
KubernetesVersion: "1.12.0",
Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{
ImageMeta: kubeadmapi.ImageMeta{
ImageRepository: "override",
},
},
},
},
expected: "override/etcd:3.2.24",
}, },
{ {
expected: GetGenericImage(gcrPrefix, "etcd", constants.DefaultEtcdVersion), expected: GetGenericImage(gcrPrefix, "etcd", constants.DefaultEtcdVersion),
@ -162,38 +190,38 @@ func TestGetAllImages(t *testing.T) {
{ {
name: "CoreDNS image is returned", name: "CoreDNS image is returned",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{ DNS: kubeadmapi.DNS{
"CoreDNS": true, Type: kubeadmapi.CoreDNS,
}, },
}, },
expect: constants.CoreDNS, expect: constants.CoreDNSImageName,
}, },
{ {
name: "main kube-dns image is returned", name: "main kube-dns image is returned",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{ DNS: kubeadmapi.DNS{
"CoreDNS": false, Type: kubeadmapi.KubeDNS,
}, },
}, },
expect: "k8s-dns-kube-dns", expect: constants.KubeDNSKubeDNSImageName,
}, },
{ {
name: "kube-dns sidecar image is returned", name: "kube-dns sidecar image is returned",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{ DNS: kubeadmapi.DNS{
"CoreDNS": false, Type: kubeadmapi.KubeDNS,
}, },
}, },
expect: "k8s-dns-sidecar", expect: constants.KubeDNSSidecarImageName,
}, },
{ {
name: "kube-dns dnsmasq-nanny image is returned", name: "kube-dns dnsmasq-nanny image is returned",
cfg: &kubeadmapi.ClusterConfiguration{ cfg: &kubeadmapi.ClusterConfiguration{
FeatureGates: map[string]bool{ DNS: kubeadmapi.DNS{
"CoreDNS": false, Type: kubeadmapi.KubeDNS,
}, },
}, },
expect: "k8s-dns-dnsmasq-nanny", expect: constants.KubeDNSDnsMasqNannyImageName,
}, },
} }
for _, tc := range testcases { for _, tc := range testcases {

View File

@ -23,7 +23,6 @@ import (
"github.com/mholt/caddy/caddyfile" "github.com/mholt/caddy/caddyfile"
"github.com/pkg/errors" "github.com/pkg/errors"
apps "k8s.io/api/apps/v1" apps "k8s.io/api/apps/v1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1" rbac "k8s.io/api/rbac/v1"
@ -34,7 +33,7 @@ import (
clientsetscheme "k8s.io/client-go/kubernetes/scheme" clientsetscheme "k8s.io/client-go/kubernetes/scheme"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features" "k8s.io/kubernetes/cmd/kubeadm/app/images"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient" "k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
) )
@ -48,7 +47,7 @@ const (
) )
// DeployedDNSAddon returns the type of DNS addon currently deployed // DeployedDNSAddon returns the type of DNS addon currently deployed
func DeployedDNSAddon(client clientset.Interface) (string, string, error) { func DeployedDNSAddon(client clientset.Interface) (kubeadmapi.DNSAddOnType, string, error) {
deploymentsClient := client.AppsV1().Deployments(metav1.NamespaceSystem) deploymentsClient := client.AppsV1().Deployments(metav1.NamespaceSystem)
deployments, err := deploymentsClient.List(metav1.ListOptions{LabelSelector: "k8s-app=kube-dns"}) deployments, err := deploymentsClient.List(metav1.ListOptions{LabelSelector: "k8s-app=kube-dns"})
if err != nil { if err != nil {
@ -60,10 +59,14 @@ func DeployedDNSAddon(client clientset.Interface) (string, string, error) {
return "", "", nil return "", "", nil
case 1: case 1:
addonName := deployments.Items[0].Name addonName := deployments.Items[0].Name
addonType := kubeadmapi.CoreDNS
if addonName == kubeadmconstants.KubeDNSDeploymentName {
addonType = kubeadmapi.KubeDNS
}
addonImage := deployments.Items[0].Spec.Template.Spec.Containers[0].Image addonImage := deployments.Items[0].Spec.Template.Spec.Containers[0].Image
addonImageParts := strings.Split(addonImage, ":") addonImageParts := strings.Split(addonImage, ":")
addonVersion := addonImageParts[len(addonImageParts)-1] addonVersion := addonImageParts[len(addonImageParts)-1]
return addonName, addonVersion, nil return addonType, addonVersion, nil
default: default:
return "", "", errors.Errorf("multiple DNS addon deployments found: %v", deployments.Items) return "", "", errors.Errorf("multiple DNS addon deployments found: %v", deployments.Items)
} }
@ -71,7 +74,7 @@ func DeployedDNSAddon(client clientset.Interface) (string, string, error) {
// EnsureDNSAddon creates the kube-dns or CoreDNS addon // EnsureDNSAddon creates the kube-dns or CoreDNS addon
func EnsureDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error { func EnsureDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
if features.Enabled(cfg.FeatureGates, features.CoreDNS) { if cfg.DNS.Type == kubeadmapi.CoreDNS {
return coreDNSAddon(cfg, client) return coreDNSAddon(cfg, client)
} }
return kubeDNSAddon(cfg, client) return kubeDNSAddon(cfg, client)
@ -97,13 +100,15 @@ func kubeDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface)
} }
dnsDeploymentBytes, err := kubeadmutil.ParseTemplate(KubeDNSDeployment, dnsDeploymentBytes, err := kubeadmutil.ParseTemplate(KubeDNSDeployment,
struct{ ImageRepository, Version, DNSBindAddr, DNSProbeAddr, DNSDomain, MasterTaintKey string }{ struct{ DeploymentName, KubeDNSImage, DNSMasqImage, SidecarImage, DNSBindAddr, DNSProbeAddr, DNSDomain, MasterTaintKey string }{
ImageRepository: cfg.ImageRepository, DeploymentName: kubeadmconstants.KubeDNSDeploymentName,
Version: kubeadmconstants.KubeDNSVersion, KubeDNSImage: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.KubeDNSKubeDNSImageName),
DNSBindAddr: dnsBindAddr, DNSMasqImage: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.KubeDNSDnsMasqNannyImageName),
DNSProbeAddr: dnsProbeAddr, SidecarImage: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.KubeDNSSidecarImageName),
DNSDomain: cfg.Networking.DNSDomain, DNSBindAddr: dnsBindAddr,
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster, DNSProbeAddr: dnsProbeAddr,
DNSDomain: cfg.Networking.DNSDomain,
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
}) })
if err != nil { if err != nil {
return errors.Wrap(err, "error when parsing kube-dns deployment template") return errors.Wrap(err, "error when parsing kube-dns deployment template")
@ -151,17 +156,17 @@ func createKubeDNSAddon(deploymentBytes, serviceBytes []byte, client clientset.I
func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error { func coreDNSAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interface) error {
// Get the YAML manifest // Get the YAML manifest
coreDNSDeploymentBytes, err := kubeadmutil.ParseTemplate(CoreDNSDeployment, struct{ ImageRepository, MasterTaintKey, Version string }{ coreDNSDeploymentBytes, err := kubeadmutil.ParseTemplate(CoreDNSDeployment, struct{ DeploymentName, Image, MasterTaintKey string }{
ImageRepository: cfg.ImageRepository, DeploymentName: kubeadmconstants.CoreDNSDeploymentName,
MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster, Image: images.GetDNSImage(&cfg.ClusterConfiguration, kubeadmconstants.CoreDNSImageName),
Version: kubeadmconstants.CoreDNSVersion, MasterTaintKey: kubeadmconstants.LabelNodeRoleMaster,
}) })
if err != nil { if err != nil {
return errors.Wrap(err, "error when parsing CoreDNS deployment template") return errors.Wrap(err, "error when parsing CoreDNS deployment template")
} }
// Get the kube-dns ConfigMap for translation to equivalent CoreDNS Config. // Get the kube-dns ConfigMap for translation to equivalent CoreDNS Config.
kubeDNSConfigMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(kubeadmconstants.KubeDNS, metav1.GetOptions{}) kubeDNSConfigMap, err := client.CoreV1().ConfigMaps(metav1.NamespaceSystem).Get(kubeadmconstants.KubeDNSConfigMap, metav1.GetOptions{})
if err != nil && !apierrors.IsNotFound(err) { if err != nil && !apierrors.IsNotFound(err) {
return err return err
} }
@ -219,7 +224,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien
} }
// Create the ConfigMap for CoreDNS or retain it in case it already exists // Create the ConfigMap for CoreDNS or retain it in case it already exists
if err := apiclient.CreateOrRetainConfigMap(client, coreDNSConfigMap, kubeadmconstants.CoreDNS); err != nil { if err := apiclient.CreateOrRetainConfigMap(client, coreDNSConfigMap, kubeadmconstants.CoreDNSConfigMap); err != nil {
return err return err
} }

View File

@ -95,13 +95,15 @@ func TestCompileManifests(t *testing.T) {
}{ }{
{ {
manifest: KubeDNSDeployment, manifest: KubeDNSDeployment,
data: struct{ ImageRepository, Version, DNSBindAddr, DNSProbeAddr, DNSDomain, MasterTaintKey string }{ data: struct{ DeploymentName, KubeDNSImage, DNSMasqImage, SidecarImage, DNSBindAddr, DNSProbeAddr, DNSDomain, MasterTaintKey string }{
ImageRepository: "foo", DeploymentName: "foo",
Version: "foo", KubeDNSImage: "foo",
DNSBindAddr: "foo", DNSMasqImage: "foo",
DNSProbeAddr: "foo", SidecarImage: "foo",
DNSDomain: "foo", DNSBindAddr: "foo",
MasterTaintKey: "foo", DNSProbeAddr: "foo",
DNSDomain: "foo",
MasterTaintKey: "foo",
}, },
expected: true, expected: true,
}, },
@ -114,10 +116,10 @@ func TestCompileManifests(t *testing.T) {
}, },
{ {
manifest: CoreDNSDeployment, manifest: CoreDNSDeployment,
data: struct{ ImageRepository, MasterTaintKey, Version string }{ data: struct{ DeploymentName, Image, MasterTaintKey string }{
ImageRepository: "foo", DeploymentName: "foo",
MasterTaintKey: "foo", Image: "foo",
Version: "foo", MasterTaintKey: "foo",
}, },
expected: true, expected: true,
}, },

View File

@ -22,7 +22,7 @@ const (
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: kube-dns name: {{ .DeploymentName }}
namespace: kube-system namespace: kube-system
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
@ -50,7 +50,7 @@ spec:
optional: true optional: true
containers: containers:
- name: kubedns - name: kubedns
image: {{ .ImageRepository }}/k8s-dns-kube-dns:{{ .Version }} image: {{ .KubeDNSImage }}
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
resources: resources:
# TODO: Set memory limits when we've profiled the container for large # TODO: Set memory limits when we've profiled the container for large
@ -102,7 +102,7 @@ spec:
- name: kube-dns-config - name: kube-dns-config
mountPath: /kube-dns-config mountPath: /kube-dns-config
- name: dnsmasq - name: dnsmasq
image: {{ .ImageRepository }}/k8s-dns-dnsmasq-nanny:{{ .Version }} image: {{ .DNSMasqImage }}
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
livenessProbe: livenessProbe:
httpGet: httpGet:
@ -143,7 +143,7 @@ spec:
- name: kube-dns-config - name: kube-dns-config
mountPath: /etc/k8s/dns/dnsmasq-nanny mountPath: /etc/k8s/dns/dnsmasq-nanny
- name: sidecar - name: sidecar
image: {{ .ImageRepository }}/k8s-dns-sidecar:{{ .Version }} image: {{ .SidecarImage }}
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
livenessProbe: livenessProbe:
httpGet: httpGet:
@ -213,7 +213,7 @@ spec:
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: coredns name: {{ .DeploymentName }}
namespace: kube-system namespace: kube-system
labels: labels:
k8s-app: kube-dns k8s-app: kube-dns
@ -239,7 +239,7 @@ spec:
effect: NoSchedule effect: NoSchedule
containers: containers:
- name: coredns - name: coredns
image: {{ .ImageRepository }}/coredns:{{ .Version }} image: {{ .Image }}
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
resources: resources:
limits: limits:

View File

@ -21,7 +21,6 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
apps "k8s.io/api/apps/v1" apps "k8s.io/api/apps/v1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1" rbac "k8s.io/api/rbac/v1"
@ -82,7 +81,7 @@ func EnsureProxyAddon(cfg *kubeadmapi.InitConfiguration, client clientset.Interf
return errors.Wrap(err, "error when parsing kube-proxy configmap template") return errors.Wrap(err, "error when parsing kube-proxy configmap template")
} }
proxyDaemonSetBytes, err = kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{ proxyDaemonSetBytes, err = kubeadmutil.ParseTemplate(KubeProxyDaemonSet19, struct{ Image, ProxyConfigMap, ProxyConfigMapKey string }{
Image: images.GetKubeControlPlaneImage(constants.KubeProxy, &cfg.ClusterConfiguration), Image: images.GetKubernetesImage(constants.KubeProxy, &cfg.ClusterConfiguration),
ProxyConfigMap: constants.KubeProxyConfigMap, ProxyConfigMap: constants.KubeProxyConfigMap,
ProxyConfigMapKey: constants.KubeProxyConfigMapKey, ProxyConfigMapKey: constants.KubeProxyConfigMapKey,
}) })

View File

@ -25,10 +25,9 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/klog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/version" "k8s.io/apimachinery/pkg/util/version"
"k8s.io/klog"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
@ -56,7 +55,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Ve
staticPodSpecs := map[string]v1.Pod{ staticPodSpecs := map[string]v1.Pod{
kubeadmconstants.KubeAPIServer: staticpodutil.ComponentPod(v1.Container{ kubeadmconstants.KubeAPIServer: staticpodutil.ComponentPod(v1.Container{
Name: kubeadmconstants.KubeAPIServer, Name: kubeadmconstants.KubeAPIServer,
Image: images.GetKubeControlPlaneImage(kubeadmconstants.KubeAPIServer, &cfg.ClusterConfiguration), Image: images.GetKubernetesImage(kubeadmconstants.KubeAPIServer, &cfg.ClusterConfiguration),
ImagePullPolicy: v1.PullIfNotPresent, ImagePullPolicy: v1.PullIfNotPresent,
Command: getAPIServerCommand(cfg), Command: getAPIServerCommand(cfg),
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer)), VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeAPIServer)),
@ -66,7 +65,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Ve
}, mounts.GetVolumes(kubeadmconstants.KubeAPIServer)), }, mounts.GetVolumes(kubeadmconstants.KubeAPIServer)),
kubeadmconstants.KubeControllerManager: staticpodutil.ComponentPod(v1.Container{ kubeadmconstants.KubeControllerManager: staticpodutil.ComponentPod(v1.Container{
Name: kubeadmconstants.KubeControllerManager, Name: kubeadmconstants.KubeControllerManager,
Image: images.GetKubeControlPlaneImage(kubeadmconstants.KubeControllerManager, &cfg.ClusterConfiguration), Image: images.GetKubernetesImage(kubeadmconstants.KubeControllerManager, &cfg.ClusterConfiguration),
ImagePullPolicy: v1.PullIfNotPresent, ImagePullPolicy: v1.PullIfNotPresent,
Command: getControllerManagerCommand(cfg, k8sVersion), Command: getControllerManagerCommand(cfg, k8sVersion),
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager)), VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeControllerManager)),
@ -76,7 +75,7 @@ func GetStaticPodSpecs(cfg *kubeadmapi.InitConfiguration, k8sVersion *version.Ve
}, mounts.GetVolumes(kubeadmconstants.KubeControllerManager)), }, mounts.GetVolumes(kubeadmconstants.KubeControllerManager)),
kubeadmconstants.KubeScheduler: staticpodutil.ComponentPod(v1.Container{ kubeadmconstants.KubeScheduler: staticpodutil.ComponentPod(v1.Container{
Name: kubeadmconstants.KubeScheduler, Name: kubeadmconstants.KubeScheduler,
Image: images.GetKubeControlPlaneImage(kubeadmconstants.KubeScheduler, &cfg.ClusterConfiguration), Image: images.GetKubernetesImage(kubeadmconstants.KubeScheduler, &cfg.ClusterConfiguration),
ImagePullPolicy: v1.PullIfNotPresent, ImagePullPolicy: v1.PullIfNotPresent,
Command: getSchedulerCommand(cfg), Command: getSchedulerCommand(cfg),
VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler)), VolumeMounts: staticpodutil.VolumeMountMapToSlice(mounts.GetVolumeMounts(kubeadmconstants.KubeScheduler)),

View File

@ -38,7 +38,6 @@ func TestGetEtcdPodSpec(t *testing.T) {
Etcd: kubeadmapi.Etcd{ Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{ Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd", DataDir: "/var/lib/etcd",
Image: "",
}, },
}, },
}, },
@ -69,7 +68,6 @@ func TestCreateLocalEtcdStaticPodManifestFile(t *testing.T) {
Etcd: kubeadmapi.Etcd{ Etcd: kubeadmapi.Etcd{
Local: &kubeadmapi.LocalEtcd{ Local: &kubeadmapi.LocalEtcd{
DataDir: "/var/lib/etcd", DataDir: "/var/lib/etcd",
Image: "k8s.gcr.io/etcd",
}, },
}, },
}, },

View File

@ -22,8 +22,8 @@ import (
versionutil "k8s.io/apimachinery/pkg/util/version" versionutil "k8s.io/apimachinery/pkg/util/version"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns" "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd"
) )
@ -56,20 +56,12 @@ func (u *Upgrade) CanUpgradeEtcd() bool {
return u.Before.EtcdVersion != u.After.EtcdVersion return u.Before.EtcdVersion != u.After.EtcdVersion
} }
// ActiveDNSAddon returns the version of CoreDNS or kube-dns
func ActiveDNSAddon(featureGates map[string]bool) string {
if features.Enabled(featureGates, features.CoreDNS) {
return kubeadmconstants.CoreDNS
}
return kubeadmconstants.KubeDNS
}
// ClusterState describes the state of certain versions for a cluster // ClusterState describes the state of certain versions for a cluster
type ClusterState struct { type ClusterState struct {
// KubeVersion describes the version of the Kubernetes API Server, Controller Manager, Scheduler and Proxy. // KubeVersion describes the version of the Kubernetes API Server, Controller Manager, Scheduler and Proxy.
KubeVersion string KubeVersion string
// DNSType // DNSType
DNSType string DNSType kubeadmapi.DNSAddOnType
// DNSVersion describes the version of the kube-dns images used and manifest version // DNSVersion describes the version of the kube-dns images used and manifest version
DNSVersion string DNSVersion string
// KubeadmVersion describes the version of the kubeadm CLI // KubeadmVersion describes the version of the kubeadm CLI
@ -82,7 +74,7 @@ type ClusterState struct {
// GetAvailableUpgrades fetches all versions from the specified VersionGetter and computes which // GetAvailableUpgrades fetches all versions from the specified VersionGetter and computes which
// kinds of upgrades can be performed // kinds of upgrades can be performed
func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesAllowed, rcUpgradesAllowed bool, etcdClient etcdutil.ClusterInterrogator, featureGates map[string]bool, client clientset.Interface) ([]Upgrade, error) { func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesAllowed, rcUpgradesAllowed bool, etcdClient etcdutil.ClusterInterrogator, dnsType kubeadmapi.DNSAddOnType, client clientset.Interface) ([]Upgrade, error) {
fmt.Println("[upgrade] Fetching available versions to upgrade to") fmt.Println("[upgrade] Fetching available versions to upgrade to")
// Collect the upgrades kubeadm can do in this list // Collect the upgrades kubeadm can do in this list
@ -120,7 +112,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
return upgrades, err return upgrades, err
} }
dnsType, dnsVersion, err := dns.DeployedDNSAddon(client) currentDNSType, dnsVersion, err := dns.DeployedDNSAddon(client)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -128,7 +120,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
// Construct a descriptor for the current state of the world // Construct a descriptor for the current state of the world
beforeState := ClusterState{ beforeState := ClusterState{
KubeVersion: clusterVersionStr, KubeVersion: clusterVersionStr,
DNSType: dnsType, DNSType: currentDNSType,
DNSVersion: dnsVersion, DNSVersion: dnsVersion,
KubeadmVersion: kubeadmVersionStr, KubeadmVersion: kubeadmVersionStr,
KubeletVersions: kubeletVersions, KubeletVersions: kubeletVersions,
@ -172,8 +164,8 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState, Before: beforeState,
After: ClusterState{ After: ClusterState{
KubeVersion: patchVersionStr, KubeVersion: patchVersionStr,
DNSType: ActiveDNSAddon(featureGates), DNSType: dnsType,
DNSVersion: kubeadmconstants.GetDNSVersion(ActiveDNSAddon(featureGates)), DNSVersion: kubeadmconstants.GetDNSVersion(dnsType),
KubeadmVersion: newKubeadmVer, KubeadmVersion: newKubeadmVer,
EtcdVersion: getSuggestedEtcdVersion(patchVersionStr), EtcdVersion: getSuggestedEtcdVersion(patchVersionStr),
// KubeletVersions is unset here as it is not used anywhere in .After // KubeletVersions is unset here as it is not used anywhere in .After
@ -189,8 +181,8 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState, Before: beforeState,
After: ClusterState{ After: ClusterState{
KubeVersion: stableVersionStr, KubeVersion: stableVersionStr,
DNSType: ActiveDNSAddon(featureGates), DNSType: dnsType,
DNSVersion: kubeadmconstants.GetDNSVersion(ActiveDNSAddon(featureGates)), DNSVersion: kubeadmconstants.GetDNSVersion(dnsType),
KubeadmVersion: stableVersionStr, KubeadmVersion: stableVersionStr,
EtcdVersion: getSuggestedEtcdVersion(stableVersionStr), EtcdVersion: getSuggestedEtcdVersion(stableVersionStr),
// KubeletVersions is unset here as it is not used anywhere in .After // KubeletVersions is unset here as it is not used anywhere in .After
@ -235,8 +227,8 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState, Before: beforeState,
After: ClusterState{ After: ClusterState{
KubeVersion: previousBranchLatestVersionStr, KubeVersion: previousBranchLatestVersionStr,
DNSType: ActiveDNSAddon(featureGates), DNSType: dnsType,
DNSVersion: kubeadmconstants.GetDNSVersion(ActiveDNSAddon(featureGates)), DNSVersion: kubeadmconstants.GetDNSVersion(dnsType),
KubeadmVersion: previousBranchLatestVersionStr, KubeadmVersion: previousBranchLatestVersionStr,
EtcdVersion: getSuggestedEtcdVersion(previousBranchLatestVersionStr), EtcdVersion: getSuggestedEtcdVersion(previousBranchLatestVersionStr),
// KubeletVersions is unset here as it is not used anywhere in .After // KubeletVersions is unset here as it is not used anywhere in .After
@ -249,12 +241,12 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
// Default to assume that the experimental version to show is the unstable one // Default to assume that the experimental version to show is the unstable one
unstableKubeVersion := latestVersionStr unstableKubeVersion := latestVersionStr
unstableKubeDNSVersion := kubeadmconstants.GetDNSVersion(ActiveDNSAddon(featureGates)) unstableKubeDNSVersion := kubeadmconstants.GetDNSVersion(dnsType)
// Ẃe should not display alpha.0. The previous branch's beta/rc versions are more relevant due how the kube branching process works. // Ẃe should not display alpha.0. The previous branch's beta/rc versions are more relevant due how the kube branching process works.
if latestVersion.PreRelease() == "alpha.0" { if latestVersion.PreRelease() == "alpha.0" {
unstableKubeVersion = previousBranchLatestVersionStr unstableKubeVersion = previousBranchLatestVersionStr
unstableKubeDNSVersion = kubeadmconstants.GetDNSVersion(ActiveDNSAddon(featureGates)) unstableKubeDNSVersion = kubeadmconstants.GetDNSVersion(dnsType)
} }
upgrades = append(upgrades, Upgrade{ upgrades = append(upgrades, Upgrade{
@ -262,7 +254,7 @@ func GetAvailableUpgrades(versionGetterImpl VersionGetter, experimentalUpgradesA
Before: beforeState, Before: beforeState,
After: ClusterState{ After: ClusterState{
KubeVersion: unstableKubeVersion, KubeVersion: unstableKubeVersion,
DNSType: ActiveDNSAddon(featureGates), DNSType: dnsType,
DNSVersion: unstableKubeDNSVersion, DNSVersion: unstableKubeDNSVersion,
KubeadmVersion: unstableKubeVersion, KubeadmVersion: unstableKubeVersion,
EtcdVersion: getSuggestedEtcdVersion(unstableKubeVersion), EtcdVersion: getSuggestedEtcdVersion(unstableKubeVersion),

View File

@ -24,12 +24,12 @@ import (
"github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/clientv3"
"github.com/pkg/errors" "github.com/pkg/errors"
apps "k8s.io/api/apps/v1" apps "k8s.io/api/apps/v1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
versionutil "k8s.io/apimachinery/pkg/util/version" versionutil "k8s.io/apimachinery/pkg/util/version"
clientsetfake "k8s.io/client-go/kubernetes/fake" clientsetfake "k8s.io/client-go/kubernetes/fake"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
"k8s.io/kubernetes/cmd/kubeadm/app/constants" "k8s.io/kubernetes/cmd/kubeadm/app/constants"
etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd" etcdutil "k8s.io/kubernetes/cmd/kubeadm/app/util/etcd"
) )
@ -124,9 +124,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
allowExperimental, allowRCs bool allowExperimental, allowRCs bool
errExpected bool errExpected bool
etcdClient etcdutil.ClusterInterrogator etcdClient etcdutil.ClusterInterrogator
beforeDNSType string beforeDNSType kubeadmapi.DNSAddOnType
beforeDNSVersion string beforeDNSVersion string
featureGates map[string]bool dnsType kubeadmapi.DNSAddOnType
}{ }{
{ {
name: "no action needed, already up-to-date", name: "no action needed, already up-to-date",
@ -138,9 +138,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stablePatchVersion: "v1.10.3", stablePatchVersion: "v1.10.3",
stableVersion: "v1.10.3", stableVersion: "v1.10.3",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "v1.0.6", beforeDNSVersion: "v1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{}, expectedUpgrades: []Upgrade{},
allowExperimental: false, allowExperimental: false,
errExpected: false, errExpected: false,
@ -156,9 +156,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stablePatchVersion: "v1.10.3", stablePatchVersion: "v1.10.3",
stableVersion: "v1.10.3", stableVersion: "v1.10.3",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "version in the v1.10 series", Description: "version in the v1.10 series",
@ -168,14 +168,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.1": 1, "v1.10.1": 1,
}, },
KubeadmVersion: "v1.10.2", KubeadmVersion: "v1.10.2",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.10.3", KubeVersion: "v1.10.3",
KubeadmVersion: "v1.10.3", KubeadmVersion: "v1.10.3",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -195,9 +195,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stablePatchVersion: "v1.10.3", stablePatchVersion: "v1.10.3",
stableVersion: "v1.10.3", stableVersion: "v1.10.3",
}, ""), }, ""),
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "version in the v1.10 series", Description: "version in the v1.10 series",
@ -207,14 +207,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.1": 1, "v1.10.1": 1,
}, },
KubeadmVersion: "v1.10.2", KubeadmVersion: "v1.10.2",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.10.3", KubeVersion: "v1.10.3",
KubeadmVersion: "v1.10.3", KubeadmVersion: "v1.10.3",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -234,9 +234,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stablePatchVersion: "v1.10.1", stablePatchVersion: "v1.10.1",
stableVersion: "v1.11.0", stableVersion: "v1.11.0",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "stable version", Description: "stable version",
@ -246,14 +246,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.1": 1, "v1.10.1": 1,
}, },
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.0", KubeVersion: "v1.11.0",
KubeadmVersion: "v1.11.0", KubeadmVersion: "v1.11.0",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -273,9 +273,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stablePatchVersion: "v1.10.5", stablePatchVersion: "v1.10.5",
stableVersion: "v1.11.1", stableVersion: "v1.11.1",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "version in the v1.10 series", Description: "version in the v1.10 series",
@ -285,14 +285,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.3": 1, "v1.10.3": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.10.5", KubeVersion: "v1.10.5",
KubeadmVersion: "v1.10.5", // Note: The kubeadm version mustn't be "downgraded" here KubeadmVersion: "v1.10.5", // Note: The kubeadm version mustn't be "downgraded" here
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
@ -305,14 +305,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.3": 1, "v1.10.3": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.1", KubeVersion: "v1.11.1",
KubeadmVersion: "v1.11.1", KubeadmVersion: "v1.11.1",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -333,9 +333,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stableVersion: "v1.10.5", stableVersion: "v1.10.5",
latestVersion: "v1.11.0-alpha.2", latestVersion: "v1.11.0-alpha.2",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "v1.0.6", beforeDNSVersion: "v1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{}, expectedUpgrades: []Upgrade{},
allowExperimental: true, allowExperimental: true,
errExpected: false, errExpected: false,
@ -352,9 +352,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stableVersion: "v1.10.5", stableVersion: "v1.10.5",
latestVersion: "v1.11.0-alpha.2", latestVersion: "v1.11.0-alpha.2",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "experimental version", Description: "experimental version",
@ -364,14 +364,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.5": 1, "v1.10.5": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.0-alpha.2", KubeVersion: "v1.11.0-alpha.2",
KubeadmVersion: "v1.11.0-alpha.2", KubeadmVersion: "v1.11.0-alpha.2",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -392,9 +392,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stableVersion: "v1.10.5", stableVersion: "v1.10.5",
latestVersion: "v1.11.0-alpha.2", latestVersion: "v1.11.0-alpha.2",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "experimental version", Description: "experimental version",
@ -404,14 +404,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.5": 1, "v1.10.5": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.0-alpha.2", KubeVersion: "v1.11.0-alpha.2",
KubeadmVersion: "v1.11.0-alpha.2", KubeadmVersion: "v1.11.0-alpha.2",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -433,9 +433,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
latestDevBranchVersion: "v1.11.0-beta.1", latestDevBranchVersion: "v1.11.0-beta.1",
latestVersion: "v1.12.0-alpha.0", latestVersion: "v1.12.0-alpha.0",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "experimental version", Description: "experimental version",
@ -445,14 +445,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.5": 1, "v1.10.5": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.0-beta.1", KubeVersion: "v1.11.0-beta.1",
KubeadmVersion: "v1.11.0-beta.1", KubeadmVersion: "v1.11.0-beta.1",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -474,9 +474,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
latestDevBranchVersion: "v1.11.0-rc.1", latestDevBranchVersion: "v1.11.0-rc.1",
latestVersion: "v1.12.0-alpha.1", latestVersion: "v1.12.0-alpha.1",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "release candidate version", Description: "release candidate version",
@ -486,14 +486,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.5": 1, "v1.10.5": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.0-rc.1", KubeVersion: "v1.11.0-rc.1",
KubeadmVersion: "v1.11.0-rc.1", KubeadmVersion: "v1.11.0-rc.1",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -515,9 +515,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
latestDevBranchVersion: "v1.11.6-rc.1", latestDevBranchVersion: "v1.11.6-rc.1",
latestVersion: "v1.12.1-alpha.0", latestVersion: "v1.12.1-alpha.0",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "experimental version", // Note that this is considered an experimental version in this uncommon scenario Description: "experimental version", // Note that this is considered an experimental version in this uncommon scenario
@ -527,14 +527,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.5": 1, "v1.10.5": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.6-rc.1", KubeVersion: "v1.11.6-rc.1",
KubeadmVersion: "v1.11.6-rc.1", KubeadmVersion: "v1.11.6-rc.1",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -556,9 +556,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
latestDevBranchVersion: "v1.11.0-rc.1", latestDevBranchVersion: "v1.11.0-rc.1",
latestVersion: "v1.12.0-alpha.2", latestVersion: "v1.12.0-alpha.2",
}, },
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "release candidate version", Description: "release candidate version",
@ -568,14 +568,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.5": 1, "v1.10.5": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.11.0-rc.1", KubeVersion: "v1.11.0-rc.1",
KubeadmVersion: "v1.11.0-rc.1", KubeadmVersion: "v1.11.0-rc.1",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.18", EtcdVersion: "3.2.18",
}, },
@ -588,14 +588,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.10.5": 1, "v1.10.5": 1,
}, },
KubeadmVersion: "v1.10.5", KubeadmVersion: "v1.10.5",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.12.0-alpha.2", KubeVersion: "v1.12.0-alpha.2",
KubeadmVersion: "v1.12.0-alpha.2", KubeadmVersion: "v1.12.0-alpha.2",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.24", EtcdVersion: "3.2.24",
}, },
@ -629,9 +629,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
kubeadmVersion: "v1.11.1", kubeadmVersion: "v1.11.1",
}, "v1.12.1"), }, "v1.12.1"),
etcdClient: etcdClient, etcdClient: etcdClient,
beforeDNSType: constants.CoreDNS, beforeDNSType: kubeadmapi.CoreDNS,
beforeDNSVersion: "1.0.6", beforeDNSVersion: "1.0.6",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "version in the v1.11 series", Description: "version in the v1.11 series",
@ -641,14 +641,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.11.0": 1, "v1.11.0": 1,
}, },
KubeadmVersion: "v1.11.1", KubeadmVersion: "v1.11.1",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.0.6", DNSVersion: "1.0.6",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.12.1", KubeVersion: "v1.12.1",
KubeadmVersion: "v1.12.1", KubeadmVersion: "v1.12.1",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.24", EtcdVersion: "3.2.24",
}, },
@ -666,9 +666,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stableVersion: "v1.12.0", stableVersion: "v1.12.0",
}, },
etcdClient: etcdClient, etcdClient: etcdClient,
beforeDNSType: constants.KubeDNS, beforeDNSType: kubeadmapi.KubeDNS,
beforeDNSVersion: "1.14.7", beforeDNSVersion: "1.14.7",
featureGates: make(map[string]bool), dnsType: kubeadmapi.CoreDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "version in the v1.11 series", Description: "version in the v1.11 series",
@ -678,14 +678,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.11.2": 1, "v1.11.2": 1,
}, },
KubeadmVersion: "v1.12.0", KubeadmVersion: "v1.12.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.7", DNSVersion: "1.14.7",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.12.0", KubeVersion: "v1.12.0",
KubeadmVersion: "v1.12.0", KubeadmVersion: "v1.12.0",
DNSType: "coredns", DNSType: kubeadmapi.CoreDNS,
DNSVersion: "1.2.6", DNSVersion: "1.2.6",
EtcdVersion: "3.2.24", EtcdVersion: "3.2.24",
}, },
@ -703,9 +703,9 @@ func TestGetAvailableUpgrades(t *testing.T) {
stableVersion: "v1.12.0", stableVersion: "v1.12.0",
}, },
etcdClient: etcdClient, etcdClient: etcdClient,
beforeDNSType: constants.KubeDNS, beforeDNSType: kubeadmapi.KubeDNS,
beforeDNSVersion: "1.14.7", beforeDNSVersion: "1.14.7",
featureGates: map[string]bool{"CoreDNS": false}, dnsType: kubeadmapi.KubeDNS,
expectedUpgrades: []Upgrade{ expectedUpgrades: []Upgrade{
{ {
Description: "version in the v1.11 series", Description: "version in the v1.11 series",
@ -715,14 +715,14 @@ func TestGetAvailableUpgrades(t *testing.T) {
"v1.11.2": 1, "v1.11.2": 1,
}, },
KubeadmVersion: "v1.12.0", KubeadmVersion: "v1.12.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.7", DNSVersion: "1.14.7",
EtcdVersion: "3.1.12", EtcdVersion: "3.1.12",
}, },
After: ClusterState{ After: ClusterState{
KubeVersion: "v1.12.0", KubeVersion: "v1.12.0",
KubeadmVersion: "v1.12.0", KubeadmVersion: "v1.12.0",
DNSType: "kube-dns", DNSType: kubeadmapi.KubeDNS,
DNSVersion: "1.14.13", DNSVersion: "1.14.13",
EtcdVersion: "3.2.24", EtcdVersion: "3.2.24",
}, },
@ -736,13 +736,18 @@ func TestGetAvailableUpgrades(t *testing.T) {
for _, rt := range tests { for _, rt := range tests {
t.Run(rt.name, func(t *testing.T) { t.Run(rt.name, func(t *testing.T) {
dnsName := constants.CoreDNSDeploymentName
if rt.beforeDNSType == kubeadmapi.KubeDNS {
dnsName = constants.KubeDNSDeploymentName
}
client := clientsetfake.NewSimpleClientset(&apps.Deployment{ client := clientsetfake.NewSimpleClientset(&apps.Deployment{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "Deployment", Kind: "Deployment",
APIVersion: "apps/v1", APIVersion: "apps/v1",
}, },
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: rt.beforeDNSType, Name: dnsName,
Namespace: "kube-system", Namespace: "kube-system",
Labels: map[string]string{ Labels: map[string]string{
"k8s-app": "kube-dns", "k8s-app": "kube-dns",
@ -761,7 +766,7 @@ func TestGetAvailableUpgrades(t *testing.T) {
}, },
}) })
actualUpgrades, actualErr := GetAvailableUpgrades(rt.vg, rt.allowExperimental, rt.allowRCs, rt.etcdClient, rt.featureGates, client) actualUpgrades, actualErr := GetAvailableUpgrades(rt.vg, rt.allowExperimental, rt.allowRCs, rt.etcdClient, rt.dnsType, client)
if !reflect.DeepEqual(actualUpgrades, rt.expectedUpgrades) { if !reflect.DeepEqual(actualUpgrades, rt.expectedUpgrades) {
t.Errorf("failed TestGetAvailableUpgrades\n\texpected upgrades: %v\n\tgot: %v", rt.expectedUpgrades, actualUpgrades) t.Errorf("failed TestGetAvailableUpgrades\n\texpected upgrades: %v\n\tgot: %v", rt.expectedUpgrades, actualUpgrades)
} }

View File

@ -24,7 +24,6 @@ import (
"time" "time"
pkgerrors "github.com/pkg/errors" pkgerrors "github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/errors"
@ -34,7 +33,6 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/features"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns" "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy" "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo" "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
@ -125,12 +123,12 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.InitCon
func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.InitConfiguration, client clientset.Interface, dryRun bool) error { func removeOldDNSDeploymentIfAnotherDNSIsUsed(cfg *kubeadmapi.InitConfiguration, client clientset.Interface, dryRun bool) error {
return apiclient.TryRunCommand(func() error { return apiclient.TryRunCommand(func() error {
installedDeploymentName := kubeadmconstants.KubeDNS installedDeploymentName := kubeadmconstants.KubeDNSDeploymentName
deploymentToDelete := kubeadmconstants.CoreDNS deploymentToDelete := kubeadmconstants.CoreDNSDeploymentName
if features.Enabled(cfg.FeatureGates, features.CoreDNS) { if cfg.DNS.Type == kubeadmapi.CoreDNS {
installedDeploymentName = kubeadmconstants.CoreDNS installedDeploymentName = kubeadmconstants.CoreDNSDeploymentName
deploymentToDelete = kubeadmconstants.KubeDNS deploymentToDelete = kubeadmconstants.KubeDNSDeploymentName
} }
// If we're dry-running, we don't need to wait for the new DNS addon to become ready // If we're dry-running, we don't need to wait for the new DNS addon to become ready

View File

@ -21,7 +21,6 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
apps "k8s.io/api/apps/v1" apps "k8s.io/api/apps/v1"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -65,7 +64,7 @@ func (d *DaemonSetPrepuller) CreateFunc(component string) error {
if component == constants.Etcd { if component == constants.Etcd {
image = images.GetEtcdImage(d.cfg) image = images.GetEtcdImage(d.cfg)
} else { } else {
image = images.GetKubeControlPlaneImage(component, d.cfg) image = images.GetKubernetesImage(component, d.cfg)
} }
ds := buildPrePullDaemonSet(component, image) ds := buildPrePullDaemonSet(component, image)

View File

@ -172,12 +172,17 @@ ControlPlaneEndpoint: ""
ControllerManager: ControllerManager:
ExtraArgs: null ExtraArgs: null
ExtraVolumes: null ExtraVolumes: null
DNS:
ImageRepository: ""
ImageTag: ""
Type: CoreDNS
Etcd: Etcd:
External: null External: null
Local: Local:
DataDir: /var/lib/etcd DataDir: /var/lib/etcd
ExtraArgs: null ExtraArgs: null
Image: "" ImageRepository: ""
ImageTag: ""
PeerCertSANs: null PeerCertSANs: null
ServerCertSANs: null ServerCertSANs: null
FeatureGates: null FeatureGates: null

View File

@ -39,10 +39,11 @@ certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes clusterName: kubernetes
controlPlaneEndpoint: "" controlPlaneEndpoint: ""
controllerManager: {} controllerManager: {}
dns:
type: CoreDNS
etcd: etcd:
local: local:
dataDir: /var/lib/etcd dataDir: /var/lib/etcd
image: ""
imageRepository: k8s.gcr.io imageRepository: k8s.gcr.io
kind: ClusterConfiguration kind: ClusterConfiguration
kubernetesVersion: v1.11.2 kubernetesVersion: v1.11.2

View File

@ -29,10 +29,11 @@ certificatesDir: /var/lib/kubernetes/pki
clusterName: kubernetes clusterName: kubernetes
controlPlaneEndpoint: "" controlPlaneEndpoint: ""
controllerManager: {} controllerManager: {}
dns:
type: CoreDNS
etcd: etcd:
local: local:
dataDir: /var/lib/etcd dataDir: /var/lib/etcd
image: ""
imageRepository: my-company.com imageRepository: my-company.com
kind: ClusterConfiguration kind: ClusterConfiguration
kubernetesVersion: v1.12.0 kubernetesVersion: v1.12.0