diff --git a/nodeup/pkg/model/context.go b/nodeup/pkg/model/context.go index cdf3780c6a..3d30fe2922 100644 --- a/nodeup/pkg/model/context.go +++ b/nodeup/pkg/model/context.go @@ -34,6 +34,7 @@ import ( "k8s.io/kops/pkg/apis/kops/util" "k8s.io/kops/pkg/apis/nodeup" "k8s.io/kops/pkg/dns" + "k8s.io/kops/pkg/model/components" "k8s.io/kops/pkg/systemd" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" @@ -84,9 +85,9 @@ type NodeupModelContext struct { // Init completes initialization of the object, for example pre-parsing the kubernetes version func (c *NodeupModelContext) Init() error { - k8sVersion, err := util.ParseKubernetesVersion(c.Cluster.Spec.KubernetesVersion) + k8sVersion, err := util.ParseKubernetesVersion(c.NodeupConfig.KubernetesVersion) if err != nil || k8sVersion == nil { - return fmt.Errorf("unable to parse KubernetesVersion %q", c.Cluster.Spec.KubernetesVersion) + return fmt.Errorf("unable to parse KubernetesVersion %q", c.NodeupConfig.KubernetesVersion) } c.kubernetesVersion = *k8sVersion c.bootstrapCerts = map[string]*nodetasks.BootstrapCert{} @@ -355,6 +356,17 @@ func (c *NodeupModelContext) BuildBootstrapKubeconfig(name string, ctx *fi.Nodeu } } +// RemapImage applies any needed remapping to an image reference. +func (c *NodeupModelContext) RemapImage(image string) string { + if components.IsBaseURL(c.NodeupConfig.KubernetesVersion) && c.IsKubernetesLT("1.25") { + image = strings.Replace(image, "registry.k8s.io", "k8s.gcr.io", 1) + } + if c.Architecture != architectures.ArchitectureAmd64 { + image = strings.Replace(image, "-amd64", "-"+string(c.Architecture), 1) + } + return image +} + // IsKubernetesGTE checks if the version is greater-than-or-equal func (c *NodeupModelContext) IsKubernetesGTE(version string) bool { if c.kubernetesVersion.Major == 0 { diff --git a/nodeup/pkg/model/kube_apiserver.go b/nodeup/pkg/model/kube_apiserver.go index f620a756e9..50177bdada 100644 --- a/nodeup/pkg/model/kube_apiserver.go +++ b/nodeup/pkg/model/kube_apiserver.go @@ -33,7 +33,6 @@ import ( "k8s.io/kops/pkg/wellknownusers" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" - "k8s.io/kops/util/pkg/architectures" "k8s.io/kops/util/pkg/proxy" v1 "k8s.io/api/core/v1" @@ -606,13 +605,7 @@ func (b *KubeAPIServerBuilder) buildPod(ctx context.Context, kubeAPIServer *kops resourceLimits["memory"] = *kubeAPIServer.MemoryLimit } - image := kubeAPIServer.Image - if components.IsBaseURL(b.Cluster.Spec.KubernetesVersion) && b.IsKubernetesLT("1.25") { - image = strings.Replace(image, "registry.k8s.io", "k8s.gcr.io", 1) - } - if b.Architecture != architectures.ArchitectureAmd64 { - image = strings.Replace(image, "-amd64", "-"+string(b.Architecture), 1) - } + image := b.RemapImage(kubeAPIServer.Image) container := &v1.Container{ Name: "kube-apiserver", diff --git a/nodeup/pkg/model/kube_controller_manager.go b/nodeup/pkg/model/kube_controller_manager.go index ad2055a5a9..cc2c2833b8 100644 --- a/nodeup/pkg/model/kube_controller_manager.go +++ b/nodeup/pkg/model/kube_controller_manager.go @@ -25,11 +25,9 @@ import ( "k8s.io/kops/pkg/flagbuilder" "k8s.io/kops/pkg/k8scodecs" "k8s.io/kops/pkg/kubemanifest" - "k8s.io/kops/pkg/model/components" "k8s.io/kops/pkg/rbac" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" - "k8s.io/kops/util/pkg/architectures" "k8s.io/kops/util/pkg/distributions" "k8s.io/kops/util/pkg/proxy" @@ -204,13 +202,7 @@ func (b *KubeControllerManagerBuilder) buildPod(kcm *kops.KubeControllerManagerC // Add the volumePluginDir flag if provided in the kubelet spec, or set above based on the OS flags = append(flags, "--flex-volume-plugin-dir="+volumePluginDir) - image := kcm.Image - if components.IsBaseURL(b.Cluster.Spec.KubernetesVersion) && b.IsKubernetesLT("1.25") { - image = strings.Replace(image, "registry.k8s.io", "k8s.gcr.io", 1) - } - if b.Architecture != architectures.ArchitectureAmd64 { - image = strings.Replace(image, "-amd64", "-"+string(b.Architecture), 1) - } + image := b.RemapImage(kcm.Image) container := &v1.Container{ Name: "kube-controller-manager", diff --git a/nodeup/pkg/model/kube_proxy.go b/nodeup/pkg/model/kube_proxy.go index 3f602b6464..5af6385eed 100644 --- a/nodeup/pkg/model/kube_proxy.go +++ b/nodeup/pkg/model/kube_proxy.go @@ -18,7 +18,6 @@ package model import ( "fmt" - "strings" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,11 +25,9 @@ import ( "k8s.io/kops/pkg/flagbuilder" "k8s.io/kops/pkg/k8scodecs" "k8s.io/kops/pkg/kubemanifest" - "k8s.io/kops/pkg/model/components" "k8s.io/kops/pkg/rbac" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" - "k8s.io/kops/util/pkg/architectures" ) // KubeProxyBuilder installs kube-proxy @@ -153,13 +150,7 @@ func (b *KubeProxyBuilder) buildPod() (*v1.Pod, error) { "--oom-score-adj=-998", }...) - image := c.Image - if b.Architecture != architectures.ArchitectureAmd64 { - image = strings.Replace(image, "-amd64", "-"+string(b.Architecture), 1) - } - if components.IsBaseURL(b.Cluster.Spec.KubernetesVersion) && b.IsKubernetesLT("1.25") { - image = strings.Replace(image, "registry.k8s.io", "k8s.gcr.io", 1) - } + image := b.RemapImage(c.Image) container := &v1.Container{ Name: "kube-proxy", diff --git a/nodeup/pkg/model/kube_scheduler.go b/nodeup/pkg/model/kube_scheduler.go index 7e1a6abb03..6d4a6b6386 100644 --- a/nodeup/pkg/model/kube_scheduler.go +++ b/nodeup/pkg/model/kube_scheduler.go @@ -20,7 +20,6 @@ import ( "fmt" "path/filepath" "strconv" - "strings" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" @@ -28,12 +27,10 @@ import ( "k8s.io/kops/pkg/flagbuilder" "k8s.io/kops/pkg/k8scodecs" "k8s.io/kops/pkg/kubemanifest" - "k8s.io/kops/pkg/model/components" "k8s.io/kops/pkg/model/components/kubescheduler" "k8s.io/kops/pkg/rbac" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" - "k8s.io/kops/util/pkg/architectures" "k8s.io/kops/util/pkg/proxy" v1 "k8s.io/api/core/v1" @@ -217,13 +214,7 @@ func (b *KubeSchedulerBuilder) buildPod(kubeScheduler *kops.KubeSchedulerConfig) }, } - image := kubeScheduler.Image - if components.IsBaseURL(b.Cluster.Spec.KubernetesVersion) && b.IsKubernetesLT("1.25") { - image = strings.Replace(image, "registry.k8s.io", "k8s.gcr.io", 1) - } - if b.Architecture != architectures.ArchitectureAmd64 { - image = strings.Replace(image, "-amd64", "-"+string(b.Architecture), 1) - } + image := b.RemapImage(kubeScheduler.Image) healthAction := &v1.HTTPGetAction{ Host: "127.0.0.1", diff --git a/nodeup/pkg/model/protokube.go b/nodeup/pkg/model/protokube.go index 06740a061b..0e92cb34b8 100644 --- a/nodeup/pkg/model/protokube.go +++ b/nodeup/pkg/model/protokube.go @@ -23,10 +23,8 @@ import ( "regexp" "strings" - "github.com/blang/semver/v4" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" - "k8s.io/kops/pkg/apis/kops/util" "k8s.io/kops/pkg/flagbuilder" "k8s.io/kops/pkg/rbac" "k8s.io/kops/pkg/systemd" @@ -111,12 +109,7 @@ func (t *ProtokubeBuilder) Build(c *fi.NodeupModelBuilderContext) error { // buildSystemdService generates the manifest for the protokube service func (t *ProtokubeBuilder) buildSystemdService() (*nodetasks.Service, error) { - k8sVersion, err := util.ParseKubernetesVersion(t.Cluster.Spec.KubernetesVersion) - if err != nil || k8sVersion == nil { - return nil, fmt.Errorf("unable to parse KubernetesVersion %q", t.Cluster.Spec.KubernetesVersion) - } - - protokubeFlags, err := t.ProtokubeFlags(*k8sVersion) + protokubeFlags, err := t.ProtokubeFlags() if err != nil { return nil, err } @@ -179,7 +172,7 @@ type ProtokubeFlags struct { } // ProtokubeFlags is responsible for building the command line flags for protokube -func (t *ProtokubeBuilder) ProtokubeFlags(k8sVersion semver.Version) (*ProtokubeFlags, error) { +func (t *ProtokubeBuilder) ProtokubeFlags() (*ProtokubeFlags, error) { f := &ProtokubeFlags{ Channels: t.NodeupConfig.Channels, Cloud: fi.PtrTo(string(t.BootConfig.CloudProvider)), diff --git a/pkg/apis/nodeup/config.go b/pkg/apis/nodeup/config.go index 6b0ec7f70b..610b84b331 100644 --- a/pkg/apis/nodeup/config.go +++ b/pkg/apis/nodeup/config.go @@ -38,6 +38,8 @@ type Config struct { Channels []string `json:"channels,omitempty"` // ApiserverAdditionalIPs are additional IP address to put in the apiserver server cert. ApiserverAdditionalIPs []string `json:",omitempty"` + // KubernetesVersion is the version of Kubernetes to install. + KubernetesVersion string // Packages specifies additional packages to be installed. Packages []string `json:"packages,omitempty"` @@ -168,15 +170,16 @@ func NewConfig(cluster *kops.Cluster, instanceGroup *kops.InstanceGroup) (*Confi igHooks := filterHooks(instanceGroup.Spec.Hooks, instanceGroup.Spec.Role) config := Config{ - ClusterName: cluster.ObjectMeta.Name, - CAs: map[string]string{}, - KeypairIDs: map[string]string{}, - SysctlParameters: instanceGroup.Spec.SysctlParameters, - VolumeMounts: instanceGroup.Spec.VolumeMounts, - FileAssets: append(filterFileAssets(instanceGroup.Spec.FileAssets, role), filterFileAssets(cluster.Spec.FileAssets, role)...), - Hooks: [][]kops.HookSpec{igHooks, clusterHooks}, - ContainerRuntime: cluster.Spec.ContainerRuntime, - Docker: cluster.Spec.Docker, + ClusterName: cluster.ObjectMeta.Name, + KubernetesVersion: cluster.Spec.KubernetesVersion, + CAs: map[string]string{}, + KeypairIDs: map[string]string{}, + SysctlParameters: instanceGroup.Spec.SysctlParameters, + VolumeMounts: instanceGroup.Spec.VolumeMounts, + FileAssets: append(filterFileAssets(instanceGroup.Spec.FileAssets, role), filterFileAssets(cluster.Spec.FileAssets, role)...), + Hooks: [][]kops.HookSpec{igHooks, clusterHooks}, + ContainerRuntime: cluster.Spec.ContainerRuntime, + Docker: cluster.Spec.Docker, } bootConfig := BootConfig{