feat: use architecture-specific image for core k8s components
This is one step towards running Talos on non-amd64 architectures (e.g. arm64). Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
committed by
talos-bot
parent
7f5ffdacb8
commit
15181aeade
@ -186,6 +186,7 @@ func create(ctx context.Context) (err error) {
|
||||
generate.WithInstallImage(nodeInstallImage),
|
||||
generate.WithDebug(configDebug),
|
||||
generate.WithDNSDomain(dnsDomain),
|
||||
generate.WithArchitecture(targetArch),
|
||||
}
|
||||
|
||||
for _, registryMirror := range registryMirrors {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@ -25,6 +26,7 @@ import (
|
||||
var (
|
||||
additionalSANs []string
|
||||
configVersion string
|
||||
architecture string
|
||||
dnsDomain string
|
||||
kubernetesVersion string
|
||||
installDisk string
|
||||
@ -101,6 +103,7 @@ func genV1Alpha1Config(args []string) error {
|
||||
generate.WithAdditionalSubjectAltNames(additionalSANs),
|
||||
generate.WithDNSDomain(dnsDomain),
|
||||
generate.WithPersist(persistConfig),
|
||||
generate.WithArchitecture(architecture),
|
||||
),
|
||||
},
|
||||
),
|
||||
@ -165,6 +168,7 @@ func init() {
|
||||
genConfigCmd.Flags().StringVar(&installImage, "install-image", helpers.DefaultImage(constants.DefaultInstallerImageRepository), "the image used to perform an installation")
|
||||
genConfigCmd.Flags().StringSliceVar(&additionalSANs, "additional-sans", []string{}, "additional Subject-Alt-Names for the APIServer certificate")
|
||||
genConfigCmd.Flags().StringVar(&dnsDomain, "dns-domain", "cluster.local", "the dns domain to use for cluster")
|
||||
genConfigCmd.Flags().StringVar(&architecture, "arch", runtime.GOARCH, "the architecture of the cluster")
|
||||
genConfigCmd.Flags().StringVar(&configVersion, "version", "v1alpha1", "the desired machine config version to generate")
|
||||
genConfigCmd.Flags().StringVar(&kubernetesVersion, "kubernetes-version", constants.DefaultKubernetesVersion, "desired kubernetes version to run")
|
||||
genConfigCmd.Flags().StringVarP(&outputDir, "output-dir", "o", "", "destination to output generated files")
|
||||
|
@ -6,6 +6,7 @@ package talos
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@ -30,11 +31,13 @@ var upgradeK8sCmd = &cobra.Command{
|
||||
var upgradeK8sCmdFlags struct {
|
||||
fromVersion string
|
||||
toVersion string
|
||||
arch string
|
||||
}
|
||||
|
||||
func init() {
|
||||
upgradeK8sCmd.Flags().StringVar(&upgradeK8sCmdFlags.fromVersion, "from", "", "the Kubernetes control plane version to upgrade from")
|
||||
upgradeK8sCmd.Flags().StringVar(&upgradeK8sCmdFlags.toVersion, "to", constants.DefaultKubernetesVersion, "the Kubernetes control plane version to upgrade to")
|
||||
upgradeK8sCmd.Flags().StringVar(&upgradeK8sCmdFlags.arch, "arch", runtime.GOARCH, "the cluster architecture")
|
||||
cli.Should(upgradeK8sCmd.MarkFlagRequired("from"))
|
||||
cli.Should(upgradeK8sCmd.MarkFlagRequired("to"))
|
||||
addCommand(upgradeK8sCmd)
|
||||
@ -55,5 +58,5 @@ func upgradeKubernetes(ctx context.Context, c *client.Client) error {
|
||||
},
|
||||
}
|
||||
|
||||
return k8s.Upgrade(ctx, &state, upgradeK8sCmdFlags.fromVersion, upgradeK8sCmdFlags.toVersion)
|
||||
return k8s.Upgrade(ctx, &state, upgradeK8sCmdFlags.arch, upgradeK8sCmdFlags.fromVersion, upgradeK8sCmdFlags.toVersion)
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ talosctl gen config <cluster name> <cluster endpoint> [flags]
|
||||
|
||||
```
|
||||
--additional-sans strings additional Subject-Alt-Names for the APIServer certificate
|
||||
--arch string the architecture of the cluster (default "amd64")
|
||||
--dns-domain string the dns domain to use for cluster (default "cluster.local")
|
||||
-h, --help help for config
|
||||
--install-disk string the disk to install to (default "/dev/sda")
|
||||
|
@ -14,6 +14,7 @@ talosctl upgrade-k8s [flags]
|
||||
### Options
|
||||
|
||||
```
|
||||
--arch string the cluster architecture (default "amd64")
|
||||
--from string the Kubernetes control plane version to upgrade from
|
||||
-h, --help help for upgrade-k8s
|
||||
--to string the Kubernetes control plane version to upgrade to (default "1.19.1")
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -464,7 +465,7 @@ func (suite *UpgradeSuite) upgradeKubernetes(fromVersion, toVersion string) {
|
||||
|
||||
suite.T().Logf("upgrading Kubernetes: %q -> %q", fromVersion, toVersion)
|
||||
|
||||
suite.Require().NoError(kubernetes.Upgrade(suite.ctx, suite.clusterAccess, fromVersion, toVersion))
|
||||
suite.Require().NoError(kubernetes.Upgrade(suite.ctx, suite.clusterAccess, runtime.GOARCH, fromVersion, toVersion))
|
||||
}
|
||||
|
||||
// TestRolling performs rolling upgrade starting with master nodes.
|
||||
|
@ -34,19 +34,19 @@ const (
|
||||
)
|
||||
|
||||
// Upgrade the Kubernetes control plane.
|
||||
func Upgrade(ctx context.Context, cluster cluster.K8sProvider, fromVersion, toVersion string) error {
|
||||
func Upgrade(ctx context.Context, cluster cluster.K8sProvider, arch, fromVersion, toVersion string) error {
|
||||
switch {
|
||||
case strings.HasPrefix(fromVersion, "1.18.") && strings.HasPrefix(toVersion, "1.19."):
|
||||
return hyperkubeUpgrade(ctx, cluster, toVersion)
|
||||
return hyperkubeUpgrade(ctx, cluster, arch, toVersion)
|
||||
case strings.HasPrefix(fromVersion, "1.19.") && strings.HasPrefix(toVersion, "1.19."):
|
||||
return hyperkubeUpgrade(ctx, cluster, toVersion)
|
||||
return hyperkubeUpgrade(ctx, cluster, arch, toVersion)
|
||||
default:
|
||||
return fmt.Errorf("unsupported upgrade from %q to %q", fromVersion, toVersion)
|
||||
}
|
||||
}
|
||||
|
||||
// hyperkubeUpgrade upgrades from hyperkube-based to distroless images in 1.19.
|
||||
func hyperkubeUpgrade(ctx context.Context, cluster cluster.K8sProvider, targetVersion string) error {
|
||||
func hyperkubeUpgrade(ctx context.Context, cluster cluster.K8sProvider, arch, targetVersion string) error {
|
||||
clientset, err := cluster.K8sClient(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building K8s client: %w", err)
|
||||
@ -64,7 +64,7 @@ func hyperkubeUpgrade(ctx context.Context, cluster cluster.K8sProvider, targetVe
|
||||
daemonsets := []string{kubeAPIServer, kubeControllerManager, kubeScheduler, kubeProxy}
|
||||
|
||||
for _, ds := range daemonsets {
|
||||
if err = hyperkubeUpgradeDs(ctx, clientset, ds, targetVersion); err != nil {
|
||||
if err = hyperkubeUpgradeDs(ctx, clientset, ds, arch, targetVersion); err != nil {
|
||||
return fmt.Errorf("failed updating daemonset %q: %w", ds, err)
|
||||
}
|
||||
}
|
||||
@ -158,7 +158,7 @@ func podCheckpointerGracePeriod(ctx context.Context, clientset *kubernetes.Clien
|
||||
}
|
||||
|
||||
//nolint: gocyclo
|
||||
func hyperkubeUpgradeDs(ctx context.Context, clientset *kubernetes.Clientset, ds, targetVersion string) error {
|
||||
func hyperkubeUpgradeDs(ctx context.Context, clientset *kubernetes.Clientset, ds, arch, targetVersion string) error {
|
||||
if ds == kubeAPIServer {
|
||||
fmt.Printf("temporarily taking %q out of pod-checkpointer control\n", ds)
|
||||
|
||||
@ -190,13 +190,13 @@ func hyperkubeUpgradeDs(ctx context.Context, clientset *kubernetes.Clientset, ds
|
||||
|
||||
switch ds {
|
||||
case kubeAPIServer:
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:v%s", constants.KubernetesAPIServerImage, targetVersion)
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s-%s:v%s", constants.KubernetesAPIServerImage, arch, targetVersion)
|
||||
case kubeControllerManager:
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:v%s", constants.KubernetesControllerManagerImage, targetVersion)
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s-%s:v%s", constants.KubernetesControllerManagerImage, arch, targetVersion)
|
||||
case kubeScheduler:
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:v%s", constants.KubernetesSchedulerImage, targetVersion)
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s-%s:v%s", constants.KubernetesSchedulerImage, arch, targetVersion)
|
||||
case kubeProxy:
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:v%s", constants.KubernetesProxyImage, targetVersion)
|
||||
daemonset.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s-%s:v%s", constants.KubernetesProxyImage, arch, targetVersion)
|
||||
default:
|
||||
return fmt.Errorf("failed to build new image spec")
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ type Input struct {
|
||||
AdditionalMachineCertSANs []string
|
||||
|
||||
ClusterName string
|
||||
Architecture string
|
||||
ServiceDomain string
|
||||
PodNet []string
|
||||
ServiceNet []string
|
||||
@ -315,6 +316,7 @@ func NewInput(clustername, endpoint, kubernetesVersion string, opts ...GenOption
|
||||
ServiceNet: []string{serviceNet},
|
||||
ServiceDomain: options.DNSDomain,
|
||||
ClusterName: clustername,
|
||||
Architecture: options.Architecture,
|
||||
KubernetesVersion: kubernetesVersion,
|
||||
Secrets: kubeadmTokens,
|
||||
TrustdInfo: trustdInfo,
|
||||
|
@ -53,16 +53,16 @@ func initUd(in *Input) (*v1alpha1.Config, error) {
|
||||
},
|
||||
APIServerConfig: &v1alpha1.APIServerConfig{
|
||||
CertSANs: certSANs,
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s:v%s", constants.KubernetesAPIServerImage, in.KubernetesVersion), in.KubernetesVersion),
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s-%s:v%s", constants.KubernetesAPIServerImage, in.Architecture, in.KubernetesVersion), in.KubernetesVersion),
|
||||
},
|
||||
ControllerManagerConfig: &v1alpha1.ControllerManagerConfig{
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s:v%s", constants.KubernetesControllerManagerImage, in.KubernetesVersion), in.KubernetesVersion),
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s-%s:v%s", constants.KubernetesControllerManagerImage, in.Architecture, in.KubernetesVersion), in.KubernetesVersion),
|
||||
},
|
||||
ProxyConfig: &v1alpha1.ProxyConfig{
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s:v%s", constants.KubeProxyImage, in.KubernetesVersion), in.KubernetesVersion),
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s-%s:v%s", constants.KubeProxyImage, in.Architecture, in.KubernetesVersion), in.KubernetesVersion),
|
||||
},
|
||||
SchedulerConfig: &v1alpha1.SchedulerConfig{
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s:v%s", constants.KubernetesSchedulerImage, in.KubernetesVersion), in.KubernetesVersion),
|
||||
ContainerImage: emptyIf(fmt.Sprintf("%s-%s:v%s", constants.KubernetesSchedulerImage, in.Architecture, in.KubernetesVersion), in.KubernetesVersion),
|
||||
},
|
||||
EtcdConfig: &v1alpha1.EtcdConfig{
|
||||
RootCA: in.Certs.Etcd,
|
||||
|
@ -114,6 +114,15 @@ func WithClusterCNIConfig(config *v1alpha1.CNIConfig) GenOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithArchitecture specifies architecture of the Talos cluster.
|
||||
func WithArchitecture(arch string) GenOption {
|
||||
return func(o *GenOptions) error {
|
||||
o.Architecture = arch
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GenOptions describes generate parameters.
|
||||
type GenOptions struct {
|
||||
EndpointList []string
|
||||
@ -125,6 +134,7 @@ type GenOptions struct {
|
||||
CNIConfig *v1alpha1.CNIConfig
|
||||
RegistryMirrors map[string]*v1alpha1.RegistryMirrorConfig
|
||||
DNSDomain string
|
||||
Architecture string
|
||||
Debug bool
|
||||
Persist bool
|
||||
}
|
||||
@ -132,6 +142,7 @@ type GenOptions struct {
|
||||
// DefaultGenOptions returns default options.
|
||||
func DefaultGenOptions() GenOptions {
|
||||
return GenOptions{
|
||||
Persist: true,
|
||||
Persist: true,
|
||||
Architecture: "amd64",
|
||||
}
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ func (a *APIServerConfig) Image() string {
|
||||
image := a.ContainerImage
|
||||
|
||||
if image == "" {
|
||||
image = fmt.Sprintf("%s:v%s", constants.KubernetesAPIServerImage, constants.DefaultKubernetesVersion)
|
||||
image = fmt.Sprintf("%s-%s:v%s", constants.KubernetesAPIServerImage, goruntime.GOARCH, constants.DefaultKubernetesVersion)
|
||||
}
|
||||
|
||||
return image
|
||||
@ -307,7 +307,7 @@ func (c *ControllerManagerConfig) Image() string {
|
||||
image := c.ContainerImage
|
||||
|
||||
if image == "" {
|
||||
image = fmt.Sprintf("%s:v%s", constants.KubernetesControllerManagerImage, constants.DefaultKubernetesVersion)
|
||||
image = fmt.Sprintf("%s-%s:v%s", constants.KubernetesControllerManagerImage, goruntime.GOARCH, constants.DefaultKubernetesVersion)
|
||||
}
|
||||
|
||||
return image
|
||||
@ -332,7 +332,7 @@ func (p *ProxyConfig) Image() string {
|
||||
image := p.ContainerImage
|
||||
|
||||
if image == "" {
|
||||
image = fmt.Sprintf("%s:v%s", constants.KubeProxyImage, constants.DefaultKubernetesVersion)
|
||||
image = fmt.Sprintf("%s-%s:v%s", constants.KubeProxyImage, goruntime.GOARCH, constants.DefaultKubernetesVersion)
|
||||
}
|
||||
|
||||
return image
|
||||
@ -371,7 +371,7 @@ func (s *SchedulerConfig) Image() string {
|
||||
image := s.ContainerImage
|
||||
|
||||
if image == "" {
|
||||
image = fmt.Sprintf("%s:v%s", constants.KubernetesSchedulerImage, constants.DefaultKubernetesVersion)
|
||||
image = fmt.Sprintf("%s-%s:v%s", constants.KubernetesSchedulerImage, goruntime.GOARCH, constants.DefaultKubernetesVersion)
|
||||
}
|
||||
|
||||
return image
|
||||
|
Reference in New Issue
Block a user