Merge pull request #114534 from ruquanzhao/skipaddons

kubeadm: Support skipping addons image pull
This commit is contained in:
Kubernetes Prow Robot 2023-10-30 04:20:44 +01:00 committed by GitHub
commit f3560758d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 404 additions and 38 deletions

View File

@ -92,10 +92,12 @@ func fuzzClusterConfiguration(obj *kubeadm.ClusterConfiguration, c fuzz.Continue
obj.Scheduler.ExtraEnvs = []kubeadm.EnvVar{}
obj.Etcd.Local.ExtraEnvs = []kubeadm.EnvVar{}
obj.EncryptionAlgorithm = kubeadm.EncryptionAlgorithmRSA
obj.Proxy.Disabled = false
}
func fuzzDNS(obj *kubeadm.DNS, c fuzz.Continue) {
c.FuzzNoCustom(obj)
obj.Disabled = false
}
func fuzzComponentConfigMap(obj *kubeadm.ComponentConfigMap, c fuzz.Continue) {

View File

@ -120,6 +120,9 @@ type ClusterConfiguration struct {
// DNS defines the options for the DNS add-on installed in the cluster.
DNS DNS
// Proxy defines the options for the proxy add-on installed in the cluster.
Proxy Proxy
// CertificatesDir specifies where to store or look for all required certificates.
CertificatesDir string
@ -175,8 +178,17 @@ type APIServer struct {
// DNS defines the DNS addon that should be used in the cluster
type DNS struct {
// ImageMeta allows to customize the image used for the DNS component
// ImageMeta allows to customize the image used for the DNS addon
ImageMeta `json:",inline"`
// Disabled specifies whether to disable this addon in the cluster
Disabled bool
}
// Proxy defines the proxy addon that should be used in the cluster
type Proxy struct {
// Disabled specifies whether to disable this addon in the cluster
Disabled bool
}
// ImageMeta allows to customize the image used for components that are not

View File

@ -99,6 +99,11 @@ func Convert_kubeadm_NodeRegistrationOptions_To_v1beta3_NodeRegistrationOptions(
return autoConvert_kubeadm_NodeRegistrationOptions_To_v1beta3_NodeRegistrationOptions(in, out, s)
}
// Convert_kubeadm_DNS_To_v1beta3_DNS converts a private DNS to public DNS.
func Convert_kubeadm_DNS_To_v1beta3_DNS(in *kubeadm.DNS, out *DNS, s conversion.Scope) error {
return autoConvert_kubeadm_DNS_To_v1beta3_DNS(in, out, s)
}
// convertToArgs takes a argument map and converts it to a slice of arguments.
// Te resulting argument slice is sorted alpha-numerically.
func convertToArgs(in map[string]string) []kubeadm.Arg {

View File

@ -74,11 +74,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kubeadm.DNS)(nil), (*DNS)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_DNS_To_v1beta3_DNS(a.(*kubeadm.DNS), b.(*DNS), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Discovery)(nil), (*kubeadm.Discovery)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta3_Discovery_To_kubeadm_Discovery(a.(*Discovery), b.(*kubeadm.Discovery), scope)
}); err != nil {
@ -184,6 +179,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddConversionFunc((*kubeadm.DNS)(nil), (*DNS)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_DNS_To_v1beta3_DNS(a.(*kubeadm.DNS), b.(*DNS), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*kubeadm.InitConfiguration)(nil), (*InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_InitConfiguration_To_v1beta3_InitConfiguration(a.(*kubeadm.InitConfiguration), b.(*InitConfiguration), scope)
}); err != nil {
@ -359,6 +359,7 @@ func autoConvert_kubeadm_ClusterConfiguration_To_v1beta3_ClusterConfiguration(in
if err := Convert_kubeadm_DNS_To_v1beta3_DNS(&in.DNS, &out.DNS, s); err != nil {
return err
}
// WARNING: in.Proxy requires manual conversion: does not exist in peer-type
out.CertificatesDir = in.CertificatesDir
out.ImageRepository = in.ImageRepository
// INFO: in.CIImageRepository opted out of conversion generation
@ -397,14 +398,10 @@ func autoConvert_kubeadm_DNS_To_v1beta3_DNS(in *kubeadm.DNS, out *DNS, s convers
if err := Convert_kubeadm_ImageMeta_To_v1beta3_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil {
return err
}
// WARNING: in.Disabled requires manual conversion: does not exist in peer-type
return nil
}
// Convert_kubeadm_DNS_To_v1beta3_DNS is an autogenerated conversion function.
func Convert_kubeadm_DNS_To_v1beta3_DNS(in *kubeadm.DNS, out *DNS, s conversion.Scope) error {
return autoConvert_kubeadm_DNS_To_v1beta3_DNS(in, out, s)
}
func autoConvert_v1beta3_Discovery_To_kubeadm_Discovery(in *Discovery, out *kubeadm.Discovery, s conversion.Scope) error {
out.BootstrapToken = (*kubeadm.BootstrapTokenDiscovery)(unsafe.Pointer(in.BootstrapToken))
out.File = (*kubeadm.FileDiscovery)(unsafe.Pointer(in.File))

View File

@ -35,6 +35,9 @@ limitations under the License.
// - Add `ClusterConfiguration.EncryptionAlgorithm` that can be used to set the asymmetric encryption algorithm
// used for this cluster's keys and certificates. Can be "RSA" (default algorithm, key size is 2048) or
// "ECDSA" (uses the P-256 elliptic curve).
// - Add `ClusterConfiguration.DNS.Disabled` and `ClusterConfiguration.Proxy.Disabled` that can be used to disable
// the CoreDNS and kube-proxy addons during cluster initialization. Skipping the related addons phases,
// during cluster creation will set the same fields to `false`.
//
// Migration from old kubeadm config versions
//

View File

@ -122,6 +122,9 @@ type ClusterConfiguration struct {
// +optional
DNS DNS `json:"dns,omitempty"`
// Proxy defines the options for the proxy add-on installed in the cluster.
Proxy Proxy `json:"proxy,omitempty"`
// CertificatesDir specifies where to store or look for all required certificates.
// +optional
CertificatesDir string `json:"certificatesDir,omitempty"`
@ -181,8 +184,19 @@ type APIServer struct {
// DNS defines the DNS addon that should be used in the cluster
type DNS struct {
// ImageMeta allows to customize the image used for the DNS component
// ImageMeta allows to customize the image used for the DNS addon
ImageMeta `json:",inline"`
// Disabled specifies whether to disable this addon in the cluster
// +optional
Disabled bool `json:"disabled,omitempty"`
}
// Proxy defines the proxy addon that should be used in the cluster
type Proxy struct {
// Disabled specifies whether to disable this addon in the cluster
// +optional
Disabled bool `json:"disabled,omitempty"`
}
// ImageMeta allows to customize the image used for components that are not

View File

@ -239,6 +239,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*Proxy)(nil), (*kubeadm.Proxy)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta4_Proxy_To_kubeadm_Proxy(a.(*Proxy), b.(*kubeadm.Proxy), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*kubeadm.Proxy)(nil), (*Proxy)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_kubeadm_Proxy_To_v1beta4_Proxy(a.(*kubeadm.Proxy), b.(*Proxy), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*ResetConfiguration)(nil), (*kubeadm.ResetConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta4_ResetConfiguration_To_kubeadm_ResetConfiguration(a.(*ResetConfiguration), b.(*kubeadm.ResetConfiguration), scope)
}); err != nil {
@ -381,6 +391,9 @@ func autoConvert_v1beta4_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in
if err := Convert_v1beta4_DNS_To_kubeadm_DNS(&in.DNS, &out.DNS, s); err != nil {
return err
}
if err := Convert_v1beta4_Proxy_To_kubeadm_Proxy(&in.Proxy, &out.Proxy, s); err != nil {
return err
}
out.CertificatesDir = in.CertificatesDir
out.ImageRepository = in.ImageRepository
out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates))
@ -417,6 +430,9 @@ func autoConvert_kubeadm_ClusterConfiguration_To_v1beta4_ClusterConfiguration(in
if err := Convert_kubeadm_DNS_To_v1beta4_DNS(&in.DNS, &out.DNS, s); err != nil {
return err
}
if err := Convert_kubeadm_Proxy_To_v1beta4_Proxy(&in.Proxy, &out.Proxy, s); err != nil {
return err
}
out.CertificatesDir = in.CertificatesDir
out.ImageRepository = in.ImageRepository
// INFO: in.CIImageRepository opted out of conversion generation
@ -459,6 +475,7 @@ func autoConvert_v1beta4_DNS_To_kubeadm_DNS(in *DNS, out *kubeadm.DNS, s convers
if err := Convert_v1beta4_ImageMeta_To_kubeadm_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil {
return err
}
out.Disabled = in.Disabled
return nil
}
@ -471,6 +488,7 @@ func autoConvert_kubeadm_DNS_To_v1beta4_DNS(in *kubeadm.DNS, out *DNS, s convers
if err := Convert_kubeadm_ImageMeta_To_v1beta4_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil {
return err
}
out.Disabled = in.Disabled
return nil
}
@ -848,6 +866,26 @@ func Convert_kubeadm_Patches_To_v1beta4_Patches(in *kubeadm.Patches, out *Patche
return autoConvert_kubeadm_Patches_To_v1beta4_Patches(in, out, s)
}
func autoConvert_v1beta4_Proxy_To_kubeadm_Proxy(in *Proxy, out *kubeadm.Proxy, s conversion.Scope) error {
out.Disabled = in.Disabled
return nil
}
// Convert_v1beta4_Proxy_To_kubeadm_Proxy is an autogenerated conversion function.
func Convert_v1beta4_Proxy_To_kubeadm_Proxy(in *Proxy, out *kubeadm.Proxy, s conversion.Scope) error {
return autoConvert_v1beta4_Proxy_To_kubeadm_Proxy(in, out, s)
}
func autoConvert_kubeadm_Proxy_To_v1beta4_Proxy(in *kubeadm.Proxy, out *Proxy, s conversion.Scope) error {
out.Disabled = in.Disabled
return nil
}
// Convert_kubeadm_Proxy_To_v1beta4_Proxy is an autogenerated conversion function.
func Convert_kubeadm_Proxy_To_v1beta4_Proxy(in *kubeadm.Proxy, out *Proxy, s conversion.Scope) error {
return autoConvert_kubeadm_Proxy_To_v1beta4_Proxy(in, out, s)
}
func autoConvert_v1beta4_ResetConfiguration_To_kubeadm_ResetConfiguration(in *ResetConfiguration, out *kubeadm.ResetConfiguration, s conversion.Scope) error {
out.CleanupTmpDir = in.CleanupTmpDir
out.CertificatesDir = in.CertificatesDir

View File

@ -118,6 +118,7 @@ func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) {
in.ControllerManager.DeepCopyInto(&out.ControllerManager)
in.Scheduler.DeepCopyInto(&out.Scheduler)
out.DNS = in.DNS
out.Proxy = in.Proxy
if in.FeatureGates != nil {
in, out := &in.FeatureGates, &out.FeatureGates
*out = make(map[string]bool, len(*in))
@ -546,6 +547,22 @@ func (in *Patches) DeepCopy() *Patches {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Proxy) DeepCopyInto(out *Proxy) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Proxy.
func (in *Proxy) DeepCopy() *Proxy {
if in == nil {
return nil
}
out := new(Proxy)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResetConfiguration) DeepCopyInto(out *ResetConfiguration) {
*out = *in

View File

@ -125,6 +125,7 @@ func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) {
in.ControllerManager.DeepCopyInto(&out.ControllerManager)
in.Scheduler.DeepCopyInto(&out.Scheduler)
out.DNS = in.DNS
out.Proxy = in.Proxy
if in.FeatureGates != nil {
in, out := &in.FeatureGates, &out.FeatureGates
*out = make(map[string]bool, len(*in))
@ -576,6 +577,22 @@ func (in *Patches) DeepCopy() *Patches {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Proxy) DeepCopyInto(out *Proxy) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Proxy.
func (in *Proxy) DeepCopy() *Proxy {
if in == nil {
return nil
}
out := new(Proxy)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResetConfiguration) DeepCopyInto(out *ResetConfiguration) {
*out = *in

View File

@ -235,9 +235,9 @@ func TestConfigImagesListOutput(t *testing.T) {
registry.k8s.io/kube-controller-manager:{{.KubeVersion}}
registry.k8s.io/kube-scheduler:{{.KubeVersion}}
registry.k8s.io/kube-proxy:{{.KubeVersion}}
registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
registry.k8s.io/pause:{{.PauseVersion}}
registry.k8s.io/etcd:{{.EtcdVersion}}
registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
`,
},
{
@ -254,9 +254,9 @@ registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
"registry.k8s.io/kube-controller-manager:{{.KubeVersion}}",
"registry.k8s.io/kube-scheduler:{{.KubeVersion}}",
"registry.k8s.io/kube-proxy:{{.KubeVersion}}",
"registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}",
"registry.k8s.io/pause:{{.PauseVersion}}",
"registry.k8s.io/etcd:{{.EtcdVersion}}",
"registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}"
"registry.k8s.io/etcd:{{.EtcdVersion}}"
]
}
`,
@ -273,9 +273,9 @@ images:
- registry.k8s.io/kube-controller-manager:{{.KubeVersion}}
- registry.k8s.io/kube-scheduler:{{.KubeVersion}}
- registry.k8s.io/kube-proxy:{{.KubeVersion}}
- registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
- registry.k8s.io/pause:{{.PauseVersion}}
- registry.k8s.io/etcd:{{.EtcdVersion}}
- registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
kind: Images
`,
},
@ -289,9 +289,9 @@ kind: Images
registry.k8s.io/kube-controller-manager:{{.KubeVersion}}
registry.k8s.io/kube-scheduler:{{.KubeVersion}}
registry.k8s.io/kube-proxy:{{.KubeVersion}}
registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
registry.k8s.io/pause:{{.PauseVersion}}
registry.k8s.io/etcd:{{.EtcdVersion}}
registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
`,
},
{
@ -301,7 +301,7 @@ registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}}
},
outputFormat: `jsonpath={range.images[*]}{@} {end}`,
expectedOutput: "registry.k8s.io/kube-apiserver:{{.KubeVersion}} registry.k8s.io/kube-controller-manager:{{.KubeVersion}} registry.k8s.io/kube-scheduler:{{.KubeVersion}} " +
"registry.k8s.io/kube-proxy:{{.KubeVersion}} registry.k8s.io/pause:{{.PauseVersion}} registry.k8s.io/etcd:{{.EtcdVersion}} registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}} ",
"registry.k8s.io/kube-proxy:{{.KubeVersion}} registry.k8s.io/coredns/coredns:{{.CoreDNSVersion}} registry.k8s.io/pause:{{.PauseVersion}} registry.k8s.io/etcd:{{.EtcdVersion}} ",
},
}

View File

@ -66,6 +66,17 @@ type initOptions struct {
skipCRIDetect bool
}
const (
// CoreDNSPhase is the name of CoreDNS subphase in "kubeadm init"
coreDNSPhase = "addon/coredns"
// KubeProxyPhase is the name of kube-proxy subphase during "kubeadm init"
kubeProxyPhase = "addon/kube-proxy"
// AddonPhase is the name of addon phase during "kubeadm init"
addonPhase = "addon"
)
// compile-time assert that the local data object satisfies the phases data interface.
var _ phases.InitData = &initData{}
@ -164,6 +175,8 @@ func newCmdInit(out io.Writer, initOptions *initOptions) *cobra.Command {
if len(initRunner.Options.SkipPhases) == 0 {
initRunner.Options.SkipPhases = data.cfg.SkipPhases
}
initRunner.Options.SkipPhases = manageSkippedAddons(&data.cfg.ClusterConfiguration, initRunner.Options.SkipPhases)
return data, nil
})
@ -538,3 +551,43 @@ func (d *initData) PatchesDir() string {
}
return ""
}
// manageSkippedAddons syncs proxy and DNS "Disabled" status and skipPhases.
func manageSkippedAddons(cfg *kubeadmapi.ClusterConfiguration, skipPhases []string) []string {
var (
skipDNSPhase = false
skipProxyPhase = false
)
// If the DNS or Proxy addons are disabled, skip the corresponding phase.
// Alternatively, update the proxy and DNS "Disabled" status based on skipped addon phases.
if isPhaseInSkipPhases(addonPhase, skipPhases) {
skipDNSPhase = true
skipProxyPhase = true
cfg.DNS.Disabled = true
cfg.Proxy.Disabled = true
}
if isPhaseInSkipPhases(coreDNSPhase, skipPhases) {
skipDNSPhase = true
cfg.DNS.Disabled = true
}
if isPhaseInSkipPhases(kubeProxyPhase, skipPhases) {
skipProxyPhase = true
cfg.Proxy.Disabled = true
}
if cfg.DNS.Disabled && !skipDNSPhase {
skipPhases = append(skipPhases, coreDNSPhase)
}
if cfg.Proxy.Disabled && !skipProxyPhase {
skipPhases = append(skipPhases, kubeProxyPhase)
}
return skipPhases
}
func isPhaseInSkipPhases(phase string, skipPhases []string) bool {
for _, item := range skipPhases {
if item == phase {
return true
}
}
return false
}

View File

@ -24,6 +24,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
@ -212,6 +213,131 @@ func TestNewInitData(t *testing.T) {
}
}
func TestManageSkippedAddons(t *testing.T) {
testcases := []struct {
name string
cfg *kubeadmapi.ClusterConfiguration
expectedCfg *kubeadmapi.ClusterConfiguration
skipPhases []string
expectedSkipPhases []string
}{
{
name: "disable proxy and DNS if 'addon' is in skipPhases",
cfg: &kubeadmapi.ClusterConfiguration{},
expectedCfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
Proxy: kubeadmapi.Proxy{
Disabled: true,
},
},
skipPhases: []string{"addon"},
expectedSkipPhases: []string{"addon"},
},
{
name: "disable proxy and DNS if 'addon/coredns' and 'addon/kube-proxy' are in skipPhases",
cfg: &kubeadmapi.ClusterConfiguration{},
expectedCfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
Proxy: kubeadmapi.Proxy{
Disabled: true,
},
},
skipPhases: []string{"addon/coredns", "addon/kube-proxy"},
expectedSkipPhases: []string{"addon/coredns", "addon/kube-proxy"},
},
{
name: "disable proxy if 'addon/kube-proxy' is in skipPhases",
cfg: &kubeadmapi.ClusterConfiguration{},
expectedCfg: &kubeadmapi.ClusterConfiguration{
Proxy: kubeadmapi.Proxy{
Disabled: true,
},
},
skipPhases: []string{"addon/kube-proxy"},
expectedSkipPhases: []string{"addon/kube-proxy"},
},
{
name: "disable DNS if 'addon/coredns' is in skipPhases",
cfg: &kubeadmapi.ClusterConfiguration{},
expectedCfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
},
skipPhases: []string{"addon/coredns"},
expectedSkipPhases: []string{"addon/coredns"},
},
{
name: "add 'addon/coredns' and 'addon/kube-proxy' to skipPhases if DNS and proxy are disabled",
cfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
Proxy: kubeadmapi.Proxy{
Disabled: true,
},
},
expectedCfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
Proxy: kubeadmapi.Proxy{
Disabled: true,
},
},
expectedSkipPhases: []string{"addon/coredns", "addon/kube-proxy"},
},
{
name: "don't add duplicates in skipPhases",
cfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
},
expectedCfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
},
skipPhases: []string{"addon/coredns"},
expectedSkipPhases: []string{"addon/coredns"},
},
{
name: "overwrite addon Disabled status if skipPhases is set",
cfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: false,
},
},
expectedCfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
},
skipPhases: []string{"addon/coredns"},
expectedSkipPhases: []string{"addon/coredns"},
},
{
name: "do nothing if addon Disabled field and skipPhases are not configured",
cfg: &kubeadmapi.ClusterConfiguration{},
expectedCfg: &kubeadmapi.ClusterConfiguration{},
skipPhases: []string{},
expectedSkipPhases: []string{},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
skipPhases := manageSkippedAddons(tc.cfg, tc.skipPhases)
assert.Equal(t, tc.expectedSkipPhases, skipPhases)
assert.Equal(t, tc.expectedCfg, tc.cfg)
})
}
}
func expectedInitIgnorePreflightErrors(expectedItems ...string) func(t *testing.T, data *initData) {
expected := sets.New(expectedItems...)
return func(t *testing.T, data *initData) {

View File

@ -94,7 +94,19 @@ func GetControlPlaneImages(cfg *kubeadmapi.ClusterConfiguration) []string {
images = append(images, GetKubernetesImage(constants.KubeAPIServer, cfg))
images = append(images, GetKubernetesImage(constants.KubeControllerManager, cfg))
images = append(images, GetKubernetesImage(constants.KubeScheduler, cfg))
images = append(images, GetKubernetesImage(constants.KubeProxy, cfg))
// if Proxy addon is not disable then add the image
if cfg.Proxy.Disabled {
klog.V(1).Infof("skipping the kube-proxy image pull since the bundled addon is disabled")
} else {
images = append(images, GetKubernetesImage(constants.KubeProxy, cfg))
}
// if DNS addon is not disable then add the image
if cfg.DNS.Disabled {
klog.V(1).Infof("skipping the CoreDNS image pull since the bundled addon is disabled")
} else {
images = append(images, GetDNSImage(cfg))
}
// pause is not available on the ci image repository so use the default image repository.
images = append(images, GetPauseImage(cfg))
@ -104,9 +116,6 @@ func GetControlPlaneImages(cfg *kubeadmapi.ClusterConfiguration) []string {
images = append(images, GetEtcdImage(cfg))
}
// Append the appropriate DNS images
images = append(images, GetDNSImage(cfg))
return images
}

View File

@ -18,9 +18,9 @@ package images
import (
"fmt"
"strings"
"testing"
"github.com/stretchr/testify/assert"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmapiv1beta3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta3"
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
@ -190,23 +190,37 @@ func TestGetPauseImage(t *testing.T) {
func TestGetAllImages(t *testing.T) {
testcases := []struct {
name string
expect string
cfg *kubeadmapi.ClusterConfiguration
name string
expectedImages []string
cfg *kubeadmapi.ClusterConfiguration
}{
{
name: "defined CIImageRepository",
cfg: &kubeadmapi.ClusterConfiguration{
CIImageRepository: "test.repo",
},
expect: "test.repo",
expectedImages: []string{
"test.repo/kube-apiserver:",
"test.repo/kube-controller-manager:",
"test.repo/kube-scheduler:",
"test.repo/kube-proxy:",
"/coredns:" + constants.CoreDNSVersion,
"/pause:" + constants.PauseVersion,
},
},
{
name: "undefined CIImagerRepository should contain the default image prefix",
cfg: &kubeadmapi.ClusterConfiguration{
ImageRepository: "real.repo",
},
expect: "real.repo",
expectedImages: []string{
"real.repo/kube-apiserver:",
"real.repo/kube-controller-manager:",
"real.repo/kube-scheduler:",
"real.repo/kube-proxy:",
"real.repo/coredns:" + constants.CoreDNSVersion,
"real.repo/pause:" + constants.PauseVersion,
},
},
{
name: "test that etcd is returned when it is not external",
@ -215,23 +229,82 @@ func TestGetAllImages(t *testing.T) {
Local: &kubeadmapi.LocalEtcd{},
},
},
expect: constants.Etcd,
expectedImages: []string{
"/kube-apiserver:",
"/kube-controller-manager:",
"/kube-scheduler:",
"/kube-proxy:",
"/coredns:" + constants.CoreDNSVersion,
"/pause:" + constants.PauseVersion,
"/etcd:" + constants.DefaultEtcdVersion,
},
},
{
name: "CoreDNS image is returned",
cfg: &kubeadmapi.ClusterConfiguration{},
expect: constants.CoreDNSImageName,
name: "CoreDNS and kube-proxy image are returned",
cfg: &kubeadmapi.ClusterConfiguration{},
expectedImages: []string{
"/kube-apiserver:",
"/kube-controller-manager:",
"/kube-scheduler:",
"/kube-proxy:",
"/coredns:" + constants.CoreDNSVersion,
"/pause:" + constants.PauseVersion,
},
},
{
name: "CoreDNS image is skipped",
cfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: true,
},
},
expectedImages: []string{
"/kube-apiserver:",
"/kube-controller-manager:",
"/kube-scheduler:",
"/kube-proxy:",
"/pause:" + constants.PauseVersion,
},
},
{
name: "kube-proxy image is skipped",
cfg: &kubeadmapi.ClusterConfiguration{
Proxy: kubeadmapi.Proxy{
Disabled: true,
},
},
expectedImages: []string{
"/kube-apiserver:",
"/kube-controller-manager:",
"/kube-scheduler:",
"/coredns:" + constants.CoreDNSVersion,
"/pause:" + constants.PauseVersion,
},
},
{
name: "setting addons Disabled to false has no effect",
cfg: &kubeadmapi.ClusterConfiguration{
DNS: kubeadmapi.DNS{
Disabled: false,
},
Proxy: kubeadmapi.Proxy{
Disabled: false,
},
},
expectedImages: []string{
"/kube-apiserver:",
"/kube-controller-manager:",
"/kube-scheduler:",
"/kube-proxy:",
"/coredns:" + constants.CoreDNSVersion,
"/pause:" + constants.PauseVersion,
},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
imgs := GetControlPlaneImages(tc.cfg)
for _, img := range imgs {
if strings.Contains(img, tc.expect) {
return
}
}
t.Fatalf("did not find %q in %q", tc.expect, imgs)
assert.Equal(t, tc.expectedImages, imgs)
})
}
}