From 459fe7d08adbae501c8a049315d3bf77e0684d6d Mon Sep 17 00:00:00 2001 From: wangyysde Date: Wed, 16 Jun 2021 09:40:22 +0800 Subject: [PATCH] add support of imagePullPolicy to kubeadm Signed-off-by: wangyysde --- cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go | 2 ++ cmd/kubeadm/app/apis/kubeadm/types.go | 5 ++++ .../app/apis/kubeadm/v1beta2/conversion.go | 5 ++++ .../v1beta2/zz_generated.conversion.go | 16 +++++------- cmd/kubeadm/app/apis/kubeadm/v1beta3/doc.go | 5 ++++ cmd/kubeadm/app/apis/kubeadm/v1beta3/types.go | 6 +++++ .../v1beta3/zz_generated.conversion.go | 2 ++ cmd/kubeadm/app/preflight/checks.go | 26 ++++++++++++------- cmd/kubeadm/app/preflight/checks_test.go | 6 +++-- 9 files changed, 52 insertions(+), 21 deletions(-) diff --git a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go index 69a86c63883..66478092386 100644 --- a/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go +++ b/cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go @@ -57,6 +57,7 @@ func fuzzInitConfiguration(obj *kubeadm.InitConfiguration, c fuzz.Continue) { }, } obj.SkipPhases = nil + obj.NodeRegistration.ImagePullPolicy = "" } func fuzzNodeRegistration(obj *kubeadm.NodeRegistrationOptions, c fuzz.Continue) { @@ -118,6 +119,7 @@ func fuzzJoinConfiguration(obj *kubeadm.JoinConfiguration, c fuzz.Continue) { Timeout: &metav1.Duration{Duration: 1234}, } obj.SkipPhases = nil + obj.NodeRegistration.ImagePullPolicy = "" } func fuzzJoinControlPlane(obj *kubeadm.JoinControlPlane, c fuzz.Continue) { diff --git a/cmd/kubeadm/app/apis/kubeadm/types.go b/cmd/kubeadm/app/apis/kubeadm/types.go index 39539b774a4..27762784299 100644 --- a/cmd/kubeadm/app/apis/kubeadm/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/types.go @@ -217,6 +217,11 @@ type NodeRegistrationOptions struct { // IgnorePreflightErrors provides a slice of pre-flight errors to be ignored when the current node is registered. IgnorePreflightErrors []string + + // ImagePullPolicy specifies the policy for image pulling during kubeadm "init" and "join" operations. + // The value of this field must be one of "Always", "IfNotPresent" or "Never". + // If this field is unset kubeadm will default it to "IfNotPresent", or pull the required images if not present on the host. + ImagePullPolicy v1.PullPolicy `json:"imagePullPolicy,omitempty"` } // Networking contains elements describing cluster's networking configuration. diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go index 896dbb3cde7..0e2112c56c9 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/conversion.go @@ -43,3 +43,8 @@ func Convert_v1beta2_ClusterConfiguration_To_kubeadm_ClusterConfiguration(in *Cl func Convert_kubeadm_JoinConfiguration_To_v1beta2_JoinConfiguration(in *kubeadm.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error { return autoConvert_kubeadm_JoinConfiguration_To_v1beta2_JoinConfiguration(in, out, s) } + +// Convert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOption is required since v1beta2 does not have NodeRegistrationOption.ImagePullPolicy +func Convert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(in *kubeadm.NodeRegistrationOptions, out *NodeRegistrationOptions, s conversion.Scope) error { + return autoConvert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(in, out, s) +} diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go index 4cc656a7fcb..6d2a9b1d5a5 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta2/zz_generated.conversion.go @@ -212,11 +212,6 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } - if err := s.AddGeneratedConversionFunc((*kubeadm.NodeRegistrationOptions)(nil), (*NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(a.(*kubeadm.NodeRegistrationOptions), b.(*NodeRegistrationOptions), 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_v1beta2_InitConfiguration(a.(*kubeadm.InitConfiguration), b.(*InitConfiguration), scope) }); err != nil { @@ -227,6 +222,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddConversionFunc((*kubeadm.NodeRegistrationOptions)(nil), (*NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(a.(*kubeadm.NodeRegistrationOptions), b.(*NodeRegistrationOptions), scope) + }); err != nil { + return err + } if err := s.AddConversionFunc((*ClusterConfiguration)(nil), (*kubeadm.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_ClusterConfiguration_To_kubeadm_ClusterConfiguration(a.(*ClusterConfiguration), b.(*kubeadm.ClusterConfiguration), scope) }); err != nil { @@ -782,10 +782,6 @@ func autoConvert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOpti out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) out.IgnorePreflightErrors = *(*[]string)(unsafe.Pointer(&in.IgnorePreflightErrors)) + // WARNING: in.ImagePullPolicy requires manual conversion: does not exist in peer-type return nil } - -// Convert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions is an autogenerated conversion function. -func Convert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(in *kubeadm.NodeRegistrationOptions, out *NodeRegistrationOptions, s conversion.Scope) error { - return autoConvert_kubeadm_NodeRegistrationOptions_To_v1beta2_NodeRegistrationOptions(in, out, s) -} diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta3/doc.go b/cmd/kubeadm/app/apis/kubeadm/v1beta3/doc.go index ce88587586f..8660af563b2 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta3/doc.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta3/doc.go @@ -31,6 +31,10 @@ limitations under the License. // This would result in the field values to be omitted when API structures are printed with klog. // - Add "InitConfiguration.SkipPhases", "JoinConfiguration.SkipPhases" to allow skipping // a list of phases during kubeadm init/join command execution. +// - Add "InitConfiguration.NodeRegistration.ImagePullPolicy" and "JoinConfiguration.NodeRegistration.ImagePullPolicy" +// to allow specifying the images pull policy during kubeadm "init" and "join". The value must be one of "Always", "Never" or +// "IfNotPresent". "IfNotPresent" is the default, which has been the existing behavior prior to this addition. + // // Migration from old kubeadm config versions // @@ -175,6 +179,7 @@ limitations under the License. // v: 4 // ignorePreflightErrors: // - IsPrivilegedUser +// imagePullPolicy: "IfNotPresent" // localAPIEndpoint: // advertiseAddress: "10.100.0.1" // bindPort: 6443 diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta3/types.go b/cmd/kubeadm/app/apis/kubeadm/v1beta3/types.go index c45bff745c4..6d1e450fa5b 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta3/types.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta3/types.go @@ -220,6 +220,12 @@ type NodeRegistrationOptions struct { // IgnorePreflightErrors provides a slice of pre-flight errors to be ignored when the current node is registered. // +optional IgnorePreflightErrors []string `json:"ignorePreflightErrors,omitempty"` + + // ImagePullPolicy specifies the policy for image pulling during kubeadm "init" and "join" operations. + // The value of this field must be one of "Always", "IfNotPresent" or "Never". + // If this field is unset kubeadm will default it to "IfNotPresent", or pull the required images if not present on the host. + // +optional + ImagePullPolicy v1.PullPolicy `json:"imagePullPolicy,omitempty"` } // Networking contains elements describing cluster's networking configuration diff --git a/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go b/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go index cb6f338079f..8a17d496eec 100644 --- a/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go +++ b/cmd/kubeadm/app/apis/kubeadm/v1beta3/zz_generated.conversion.go @@ -768,6 +768,7 @@ func autoConvert_v1beta3_NodeRegistrationOptions_To_kubeadm_NodeRegistrationOpti out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) out.IgnorePreflightErrors = *(*[]string)(unsafe.Pointer(&in.IgnorePreflightErrors)) + out.ImagePullPolicy = corev1.PullPolicy(in.ImagePullPolicy) return nil } @@ -782,6 +783,7 @@ func autoConvert_kubeadm_NodeRegistrationOptions_To_v1beta3_NodeRegistrationOpti out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) out.IgnorePreflightErrors = *(*[]string)(unsafe.Pointer(&in.IgnorePreflightErrors)) + out.ImagePullPolicy = corev1.PullPolicy(in.ImagePullPolicy) return nil } diff --git a/cmd/kubeadm/app/preflight/checks.go b/cmd/kubeadm/app/preflight/checks.go index e3b44788c2d..5de0e646fa8 100644 --- a/cmd/kubeadm/app/preflight/checks.go +++ b/cmd/kubeadm/app/preflight/checks.go @@ -36,6 +36,7 @@ import ( "github.com/PuerkitoBio/purell" "github.com/pkg/errors" + v1 "k8s.io/api/core/v1" netutil "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation" @@ -819,8 +820,9 @@ func getEtcdVersionResponse(client *http.Client, url string, target interface{}) // ImagePullCheck will pull container images used by kubeadm type ImagePullCheck struct { - runtime utilruntime.ContainerRuntime - imageList []string + runtime utilruntime.ContainerRuntime + imageList []string + imagePullPolicy v1.PullPolicy } // Name returns the label for ImagePullCheck @@ -831,14 +833,20 @@ func (ImagePullCheck) Name() string { // Check pulls images required by kubeadm. This is a mutating check func (ipc ImagePullCheck) Check() (warnings, errorList []error) { for _, image := range ipc.imageList { - ret, err := ipc.runtime.ImageExists(image) - if ret && err == nil { - klog.V(1).Infof("image exists: %s", image) + switch ipc.imagePullPolicy { + case v1.PullNever: continue + case v1.PullIfNotPresent: + ret, err := ipc.runtime.ImageExists(image) + if ret && err == nil { + klog.V(1).Infof("image exists: %s", image) + continue + } + if err != nil { + errorList = append(errorList, errors.Wrapf(err, "failed to check if image %s exists", image)) + } } - if err != nil { - errorList = append(errorList, errors.Wrapf(err, "failed to check if image %s exists", image)) - } + klog.V(1).Infof("pulling %s", image) if err := ipc.runtime.PullImage(image); err != nil { errorList = append(errorList, errors.Wrapf(err, "failed to pull image %s", image)) @@ -1061,7 +1069,7 @@ func RunPullImagesCheck(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigur } checks := []Checker{ - ImagePullCheck{runtime: containerRuntime, imageList: images.GetControlPlaneImages(&cfg.ClusterConfiguration)}, + ImagePullCheck{runtime: containerRuntime, imageList: images.GetControlPlaneImages(&cfg.ClusterConfiguration), imagePullPolicy: cfg.NodeRegistration.ImagePullPolicy}, } return RunChecks(checks, os.Stderr, ignorePreflightErrors) } diff --git a/cmd/kubeadm/app/preflight/checks_test.go b/cmd/kubeadm/app/preflight/checks_test.go index 52a8bb127b4..ba349a5996d 100644 --- a/cmd/kubeadm/app/preflight/checks_test.go +++ b/cmd/kubeadm/app/preflight/checks_test.go @@ -30,6 +30,7 @@ import ( "net/http" "os" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/constants" @@ -815,8 +816,9 @@ func TestImagePullCheck(t *testing.T) { } check := ImagePullCheck{ - runtime: containerRuntime, - imageList: []string{"img1", "img2", "img3"}, + runtime: containerRuntime, + imageList: []string{"img1", "img2", "img3"}, + imagePullPolicy: v1.PullIfNotPresent, } warnings, errors := check.Check() if len(warnings) != 0 {