Remove Docker config option

This commit is contained in:
Ciprian Hacman 2023-09-04 23:50:57 +03:00
parent 92c0f48e33
commit c43b48a8d8
35 changed files with 229 additions and 1206 deletions

View File

@ -252,9 +252,10 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
cmd.Flags().StringSliceVar(&options.KubernetesFeatureGates, "kubernetes-feature-gates", options.KubernetesFeatureGates, "List of Kubernetes feature gates to enable/disable")
cmd.RegisterFlagCompletionFunc("kubernetes-version", completeKubernetesFeatureGates)
cmd.Flags().StringVar(&options.ContainerRuntime, "container-runtime", options.ContainerRuntime, "Container runtime to use: containerd, docker")
cmd.Flags().StringVar(&options.ContainerRuntime, "container-runtime", options.ContainerRuntime, "Container runtime to use: containerd")
cmd.Flags().MarkDeprecated("container-runtime", "containerd is the only supported value")
cmd.RegisterFlagCompletionFunc("container-runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"containerd", "docker"}, cobra.ShellCompDirectiveNoFileComp
return []string{"containerd"}, cobra.ShellCompDirectiveNoFileComp
})
cmd.Flags().StringVar(&sshPublicKey, "ssh-public-key", sshPublicKey, "SSH public key to use")
@ -609,10 +610,6 @@ func RunCreateCluster(ctx context.Context, f *util.Factory, out io.Writer, c *Cr
cluster.Spec.DNSZone = c.DNSZone
}
if c.ContainerRuntime != "" {
cluster.Spec.ContainerRuntime = c.ContainerRuntime
}
for i, cidr := range c.NetworkCIDRs {
if i == 0 {
cluster.Spec.Networking.NetworkCIDR = cidr

View File

@ -59,26 +59,22 @@ func (b *ContainerdBuilder) Build(c *fi.NodeupModelBuilderContext) error {
case distributions.DistributionFlatcar:
klog.Infof("Detected Flatcar; won't install containerd")
installContainerd = false
if b.NodeupConfig.ContainerRuntime == "containerd" {
b.buildSystemdServiceOverrideFlatcar(c)
}
b.buildSystemdServiceOverrideFlatcar(c)
case distributions.DistributionContainerOS:
klog.Infof("Detected ContainerOS; won't install containerd")
installContainerd = false
b.buildSystemdServiceOverrideContainerOS(c)
}
if b.NodeupConfig.ContainerRuntime == "containerd" {
// Using containerd with Kubenet requires special configuration.
// This is a temporary backwards-compatible solution for kubenet users and will be deprecated when Kubenet is deprecated:
// https://github.com/containerd/containerd/blob/master/docs/cri/config.md#cni-config-template
if b.NodeupConfig.UsesKubenet {
if err := b.buildCNIConfigTemplateFile(c); err != nil {
return err
}
if err := b.buildIPMasqueradeRules(c); err != nil {
return err
}
// Using containerd with Kubenet requires special configuration.
// This is a temporary backwards-compatible solution for kubenet users and will be deprecated when Kubenet is deprecated:
// https://github.com/containerd/containerd/blob/master/docs/cri/config.md#cni-config-template
if b.NodeupConfig.UsesKubenet {
if err := b.buildCNIConfigTemplateFile(c); err != nil {
return err
}
if err := b.buildIPMasqueradeRules(c); err != nil {
return err
}
}
@ -109,72 +105,67 @@ func (b *ContainerdBuilder) installContainerd(c *fi.NodeupModelBuilderContext) e
c.AddTask(t)
}
// Add binaries from assets
if b.NodeupConfig.ContainerRuntime == "containerd" {
// Add containerd binaries from containerd release package
f := b.Assets.FindMatches(regexp.MustCompile(`^bin/(containerd|ctr)`))
if len(f) == 0 {
// Add containerd binaries from containerd bundle package
f = b.Assets.FindMatches(regexp.MustCompile(`^(\./)?usr/local/bin/(containerd|crictl|ctr)`))
// Add containerd binaries from containerd release package
f := b.Assets.FindMatches(regexp.MustCompile(`^bin/(containerd|ctr)`))
if len(f) == 0 {
// Add containerd binaries from containerd bundle package
f = b.Assets.FindMatches(regexp.MustCompile(`^(\./)?usr/local/bin/(containerd|crictl|ctr)`))
}
if len(f) == 0 {
// Add containerd binaries from Docker package (for ARM64 builds < v1.6.0)
// https://github.com/containerd/containerd/pull/6196
f = b.Assets.FindMatches(regexp.MustCompile(`^docker/(containerd|ctr)`))
}
if len(f) == 0 {
return fmt.Errorf("unable to find any containerd binaries in assets")
}
for k, v := range f {
fileTask := &nodetasks.File{
Path: filepath.Join("/usr/bin", k),
Contents: v,
Type: nodetasks.FileType_File,
Mode: fi.PtrTo("0755"),
}
if len(f) == 0 {
// Add containerd binaries from Docker package (for ARM64 builds < v1.6.0)
// https://github.com/containerd/containerd/pull/6196
f = b.Assets.FindMatches(regexp.MustCompile(`^docker/(containerd|ctr)`))
}
if len(f) == 0 {
return fmt.Errorf("unable to find any containerd binaries in assets")
}
for k, v := range f {
fileTask := &nodetasks.File{
Path: filepath.Join("/usr/bin", k),
Contents: v,
Type: nodetasks.FileType_File,
Mode: fi.PtrTo("0755"),
}
c.AddTask(fileTask)
}
// Add runc binary from https://github.com/opencontainers/runc
// https://github.com/containerd/containerd/issues/6541
f = b.Assets.FindMatches(regexp.MustCompile(`/runc\.(amd64|arm64)$`))
if len(f) == 0 {
// Add runc binary from containerd package (for builds < v1.6.0)
f = b.Assets.FindMatches(regexp.MustCompile(`^(\./)?usr/local/sbin/runc$`))
}
if len(f) == 0 {
// Add runc binary from Docker package (for ARM64 builds < v1.6.0)
// https://github.com/containerd/containerd/pull/6196
f = b.Assets.FindMatches(regexp.MustCompile(`^docker/runc$`))
}
if len(f) != 1 {
return fmt.Errorf("error finding runc asset")
}
for _, v := range f {
fileTask := &nodetasks.File{
Path: "/usr/sbin/runc",
Contents: v,
Type: nodetasks.FileType_File,
Mode: fi.PtrTo("0755"),
}
c.AddTask(fileTask)
}
// Add configuration file for easier use of crictl
b.addCrictlConfig(c)
c.AddTask(fileTask)
}
var containerRuntimeVersion string
if b.NodeupConfig.ContainerRuntime == "containerd" {
if b.NodeupConfig.ContainerdConfig != nil {
containerRuntimeVersion = fi.ValueOf(b.NodeupConfig.ContainerdConfig.Version)
} else {
return fmt.Errorf("error finding contained version")
}
// Add runc binary from https://github.com/opencontainers/runc
// https://github.com/containerd/containerd/issues/6541
f = b.Assets.FindMatches(regexp.MustCompile(`/runc\.(amd64|arm64)$`))
if len(f) == 0 {
// Add runc binary from containerd package (for builds < v1.6.0)
f = b.Assets.FindMatches(regexp.MustCompile(`^(\./)?usr/local/sbin/runc$`))
}
sv, err := semver.ParseTolerant(containerRuntimeVersion)
if len(f) == 0 {
// Add runc binary from Docker package (for ARM64 builds < v1.6.0)
// https://github.com/containerd/containerd/pull/6196
f = b.Assets.FindMatches(regexp.MustCompile(`^docker/runc$`))
}
if len(f) != 1 {
return fmt.Errorf("error finding runc asset")
}
for _, v := range f {
fileTask := &nodetasks.File{
Path: "/usr/sbin/runc",
Contents: v,
Type: nodetasks.FileType_File,
Mode: fi.PtrTo("0755"),
}
c.AddTask(fileTask)
}
// Add configuration file for easier use of crictl
b.addCrictlConfig(c)
var containerdVersion string
if b.NodeupConfig.ContainerdConfig != nil {
containerdVersion = fi.ValueOf(b.NodeupConfig.ContainerdConfig.Version)
} else {
return fmt.Errorf("error finding contained version")
}
sv, err := semver.ParseTolerant(containerdVersion)
if err != nil {
return fmt.Errorf("error parsing container runtime version %q: %v", containerRuntimeVersion, err)
return fmt.Errorf("error parsing container runtime version %q: %v", containerdVersion, err)
}
c.AddTask(b.buildSystemdService(sv))
@ -193,19 +184,13 @@ func (b *ContainerdBuilder) buildSystemdService(sv semver.Version) *nodetasks.Se
manifest.Set("Unit", "Documentation", "https://containerd.io")
manifest.Set("Unit", "After", "network.target local-fs.target")
// Restore the default SELinux security contexts for the containerd and runc binaries
if b.Distribution.IsRHELFamily() && b.NodeupConfig.Docker != nil && fi.ValueOf(b.NodeupConfig.Docker.SelinuxEnabled) {
manifest.Set("Service", "ExecStartPre", "/bin/sh -c 'restorecon -v /usr/bin/runc'")
manifest.Set("Service", "ExecStartPre", "/bin/sh -c 'restorecon -v /usr/bin/containerd*'")
}
manifest.Set("Service", "EnvironmentFile", "/etc/sysconfig/containerd")
manifest.Set("Service", "EnvironmentFile", "/etc/environment")
manifest.Set("Service", "ExecStartPre", "-/sbin/modprobe overlay")
manifest.Set("Service", "ExecStart", "/usr/bin/containerd -c "+containerdConfigFilePath+" \"$CONTAINERD_OPTS\"")
// notify the daemon's readiness to systemd
if (b.NodeupConfig.ContainerRuntime == "containerd" && sv.GTE(semver.MustParse("1.3.4"))) || sv.GTE(semver.MustParse("19.3.13")) {
if sv.GTE(semver.MustParse("1.3.4")) {
manifest.Set("Service", "Type", "notify")
}
@ -487,10 +472,6 @@ func (b *ContainerdBuilder) buildCNIConfigTemplateFile(c *fi.NodeupModelBuilderC
}
func (b *ContainerdBuilder) buildContainerdConfig() (string, error) {
if b.NodeupConfig.ContainerRuntime != "containerd" {
return "", nil
}
containerd := b.NodeupConfig.ContainerdConfig
if fi.ValueOf(containerd.ConfigOverride) != "" {
return *containerd.ConfigOverride, nil

View File

@ -177,7 +177,6 @@ func TestContainerdConfig(t *testing.T) {
b := &ContainerdBuilder{
NodeupModelContext: &NodeupModelContext{
NodeupConfig: &nodeup.Config{
ContainerRuntime: "containerd",
ContainerdConfig: &kops.ContainerdConfig{},
},
},

View File

@ -124,13 +124,8 @@ func (h *HookBuilder) buildSystemdService(name string, hook *kops.HookSpec) (*no
case nil:
unit.SetSection("Service", hook.Manifest)
default:
switch h.NodeupConfig.ContainerRuntime {
case "containerd":
if err := h.buildContainerdService(unit, hook, name); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unknown container runtime %q", h.NodeupConfig.ContainerRuntime)
if err := h.buildContainerdService(unit, hook, name); err != nil {
return nil, err
}
}
definition = s(unit.Render())

View File

@ -164,7 +164,7 @@ func (b *KubeletBuilder) Build(c *fi.NodeupModelBuilderContext) error {
}
}
if kubeletConfig.CgroupDriver == "systemd" && b.NodeupConfig.ContainerRuntime == "containerd" {
if kubeletConfig.CgroupDriver == "systemd" {
{
cgroup := kubeletConfig.KubeletCgroups
@ -312,14 +312,11 @@ func (b *KubeletBuilder) buildSystemdEnvironmentFile(kubeletConfig *kops.Kubelet
}
// Add container runtime spcific flags
switch b.NodeupConfig.ContainerRuntime {
case "containerd":
flags += " --runtime-request-timeout=15m"
if b.NodeupConfig.ContainerdConfig.Address == nil {
flags += " --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
} else {
flags += " --container-runtime-endpoint=unix://" + fi.ValueOf(b.NodeupConfig.ContainerdConfig.Address)
}
flags += " --runtime-request-timeout=15m"
if b.NodeupConfig.ContainerdConfig.Address == nil {
flags += " --container-runtime-endpoint=unix:///run/containerd/containerd.sock"
} else {
flags += " --container-runtime-endpoint=unix://" + fi.ValueOf(b.NodeupConfig.ContainerdConfig.Address)
}
flags += " --tls-cert-file=" + b.PathSrvKubernetes() + "/kubelet-server.crt"
@ -356,12 +353,7 @@ func (b *KubeletBuilder) buildSystemdService() *nodetasks.Service {
manifest := &systemd.Manifest{}
manifest.Set("Unit", "Description", "Kubernetes Kubelet Server")
manifest.Set("Unit", "Documentation", "https://github.com/kubernetes/kubernetes")
switch b.NodeupConfig.ContainerRuntime {
case "containerd":
manifest.Set("Unit", "After", "containerd.service")
default:
klog.Warningf("unknown container runtime %q", b.NodeupConfig.ContainerRuntime)
}
manifest.Set("Unit", "After", "containerd.service")
manifest.Set("Service", "EnvironmentFile", "/etc/sysconfig/kubelet")
@ -376,7 +368,7 @@ func (b *KubeletBuilder) buildSystemdService() *nodetasks.Service {
manifest.Set("Install", "WantedBy", "multi-user.target")
if b.NodeupConfig.KubeletConfig.CgroupDriver == "systemd" && b.NodeupConfig.ContainerRuntime == "containerd" {
if b.NodeupConfig.KubeletConfig.CgroupDriver == "systemd" {
cgroup := b.NodeupConfig.KubeletConfig.KubeletCgroups
if cgroup != "" {
manifest.Set("Service", "Slice", strings.Trim(cgroup, "/")+".slice")

View File

@ -38,8 +38,7 @@ func (b *WarmPoolBuilder) Build(c *fi.NodeupModelBuilderContext) error {
if b.NodeupConfig != nil && b.ConfigurationMode == "Warming" {
for _, image := range b.NodeupConfig.WarmPoolImages {
c.AddTask(&nodetasks.PullImageTask{
Name: image,
Runtime: b.NodeupConfig.ContainerRuntime,
Name: image,
})
}
}

View File

@ -61,8 +61,9 @@ type ClusterSpec struct {
CloudProvider CloudProviderSpec `json:"cloudProvider,omitempty"`
// GossipConfig for the cluster assuming the use of gossip DNS
GossipConfig *GossipConfig `json:"gossipConfig,omitempty"`
// Container runtime to use for Kubernetes
ContainerRuntime string `json:"containerRuntime,omitempty"`
// ContainerRuntime was removed.
// +k8s:conversion-gen=false
ContainerRuntime string `json:"-"`
// The version of kubernetes to install (optional, and can be a "spec" like stable)
KubernetesVersion string `json:"kubernetesVersion,omitempty"`
// DNSZone is the DNS zone we should use when configuring DNS
@ -96,8 +97,10 @@ type ClusterSpec struct {
// EtcdClusters stores the configuration for each cluster
EtcdClusters []EtcdClusterSpec `json:"etcdClusters,omitempty"`
// Component configurations
Containerd *ContainerdConfig `json:"containerd,omitempty"`
Docker *DockerConfig `json:"docker,omitempty"`
Containerd *ContainerdConfig `json:"containerd,omitempty"`
// Docker was removed.
// +k8s:conversion-gen=false
Docker *DockerConfig `json:"-"`
KubeDNS *KubeDNSConfig `json:"kubeDNS,omitempty"`
KubeAPIServer *KubeAPIServerConfig `json:"kubeAPIServer,omitempty"`
KubeControllerManager *KubeControllerManagerConfig `json:"kubeControllerManager,omitempty"`
@ -337,11 +340,11 @@ type FileAssetSpec struct {
// AssetsSpec defines the privately hosted assets
type AssetsSpec struct {
// ContainerRegistry is a url for to a docker registry
// ContainerRegistry is a url for to a container registry.
ContainerRegistry *string `json:"containerRegistry,omitempty"`
// FileRepository is the url for a private file serving repository
FileRepository *string `json:"fileRepository,omitempty"`
// ContainerProxy is a url for a pull-through proxy of a docker registry
// ContainerProxy is a url for a pull-through proxy of a container registry.
ContainerProxy *string `json:"containerProxy,omitempty"`
}
@ -381,7 +384,7 @@ type HookSpec struct {
// ExecContainerAction defines an hood action
type ExecContainerAction struct {
// Image is the docker image
// Image is the container image.
Image string `json:"image,omitempty"`
// Command is the command supplied to the above image
Command []string `json:"command,omitempty"`
@ -402,7 +405,7 @@ func (s *AuthenticationSpec) IsEmpty() bool {
type KopeioAuthenticationSpec struct{}
type AWSAuthenticationSpec struct {
// Image is the AWS IAM Authenticator docker image to use
// Image is the AWS IAM Authenticator container image to use.
Image string `json:"image,omitempty"`
// BackendMode is the AWS IAM Authenticator backend to use. Default MountedFile
BackendMode string `json:"backendMode,omitempty"`
@ -594,7 +597,7 @@ type NodeLocalDNSConfig struct {
ExternalCoreFile string `json:"externalCoreFile,omitempty"`
// AdditionalConfig is used to provide additional config for node local dns by the user - it will include the original CoreFile made by kOps.
AdditionalConfig string `json:"additionalConfig,omitempty"`
// Image overrides the default docker image used for node-local-dns addon.
// Image overrides the default container image used for node-local-dns addon.
Image *string `json:"image,omitempty"`
// Local listen IP address. It can be any IP in the 169.254.20.0/16 space or any other IP address that can be guaranteed to not collide with any existing IP.
LocalIP string `json:"localIP,omitempty"`
@ -652,7 +655,7 @@ type EtcdClusterSpec struct {
LeaderElectionTimeout *metav1.Duration `json:"leaderElectionTimeout,omitempty"`
// HeartbeatInterval is the time (in milliseconds) for an etcd heartbeat interval
HeartbeatInterval *metav1.Duration `json:"heartbeatInterval,omitempty"`
// Image is the etcd docker image to use. Setting this will ignore the Version specified.
// Image is the etcd container image to use. Setting this will ignore the Version specified.
Image string `json:"image,omitempty"`
// Backups describes how we do backups of etcd
Backups *EtcdBackupSpec `json:"backups,omitempty"`

View File

@ -116,10 +116,7 @@ type KubeletConfigSpec struct {
ReconcileCIDR *bool `json:"reconcileCIDR,omitempty" flag:"reconcile-cidr"`
// registerSchedulable tells the kubelet to register the node as schedulable. No-op if register-node is false.
RegisterSchedulable *bool `json:"registerSchedulable,omitempty" flag:"register-schedulable"`
//// SerializeImagePulls when enabled, tells the Kubelet to pull images one
//// at a time. We recommend *not* changing the default value on nodes that
//// run docker daemon with version < 1.9 or an Aufs storage backend.
//// Issue #10959 has more details.
// SerializeImagePulls when enabled, tells the Kubelet to pull images one at a time.
SerializeImagePulls *bool `json:"serializeImagePulls,omitempty" flag:"serialize-image-pulls"`
// NodeLabels to add when registering the node in the cluster.
NodeLabels map[string]string `json:"nodeLabels,omitempty" flag:"node-labels"`
@ -184,8 +181,9 @@ type KubeletConfigSpec struct {
AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty" flag:"allowed-unsafe-sysctls"`
// StreamingConnectionIdleTimeout is the maximum time a streaming connection can be idle before the connection is automatically closed
StreamingConnectionIdleTimeout *metav1.Duration `json:"streamingConnectionIdleTimeout,omitempty" flag:"streaming-connection-idle-timeout"`
// DockerDisableSharedPID uses a shared PID namespace for containers in a pod.
DockerDisableSharedPID *bool `json:"dockerDisableSharedPID,omitempty" flag:"docker-disable-shared-pid"`
// DockerDisableSharedPID was removed.
// +k8s:conversion-gen=false
DockerDisableSharedPID *bool `json:"-"`
// RootDir is the directory path for managing kubelet files (volume mounts,etc)
RootDir string `json:"rootDir,omitempty" flag:"root-dir"`
// AuthenticationTokenWebhook uses the TokenReview API to determine authentication for bearer tokens.
@ -284,7 +282,7 @@ type KubeProxyConfig struct {
// KubeAPIServerConfig defines the configuration for the kube api
type KubeAPIServerConfig struct {
// Image is the docker container used
// Image is the container image used.
Image string `json:"image,omitempty"`
// DisableBasicAuth removes the --basic-auth-file flag
DisableBasicAuth *bool `json:"disableBasicAuth,omitempty"`
@ -544,7 +542,7 @@ type KubeControllerManagerConfig struct {
LogLevel int32 `json:"logLevel,omitempty" flag:"v" flag-empty:"0"`
// ServiceAccountPrivateKeyFile is the location of the private key for service account token signing.
ServiceAccountPrivateKeyFile string `json:"serviceAccountPrivateKeyFile,omitempty" flag:"service-account-private-key-file"`
// Image is the docker image to use
// Image is the container image to use.
Image string `json:"image,omitempty"`
// CloudProvider is the provider for cloud services.
CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"`
@ -723,7 +721,7 @@ type KubeSchedulerConfig struct {
LogFormat string `json:"logFormat,omitempty" flag:"logging-format" flag-empty:"text"`
// LogLevel is the logging level
LogLevel int32 `json:"logLevel,omitempty" flag:"v"`
// Image is the docker image to use
// Image is the container image to use.
Image string `json:"image,omitempty"`
// LeaderElection defines the configuration of leader election client.
LeaderElection *LeaderElectionConfiguration `json:"leaderElection,omitempty"`
@ -977,7 +975,7 @@ type NodeProblemDetectorConfig struct {
// Enabled enables the NodeProblemDetector.
// Default: false
Enabled *bool `json:"enabled,omitempty"`
// Image is the NodeProblemDetector docker container used.
// Image is the NodeProblemDetector container image used.
Image *string `json:"image,omitempty"`
// MemoryRequest of NodeProblemDetector container.
@ -1038,7 +1036,7 @@ type ClusterAutoscalerConfig struct {
// CordonNodeBeforeTerminating should CA cordon nodes before terminating during downscale process
// Default: false
CordonNodeBeforeTerminating *bool `json:"cordonNodeBeforeTerminating,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`
// MemoryRequest of cluster autoscaler container.
@ -1065,7 +1063,7 @@ type MetricsServerConfig struct {
// Enabled enables the metrics server.
// Default: false
Enabled *bool `json:"enabled,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`
// Insecure determines if API server will validate metrics server TLS cert.
@ -1083,7 +1081,7 @@ type CertManagerConfig struct {
// The deployment of cert-manager is skipped if this is set to false.
Managed *bool `json:"managed,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`

View File

@ -63,7 +63,7 @@ type ClusterSpec struct {
LegacyCloudProvider string `json:"cloudProvider,omitempty"`
// GossipConfig for the cluster assuming the use of gossip DNS
GossipConfig *GossipConfig `json:"gossipConfig,omitempty"`
// Container runtime to use for Kubernetes
// ContainerRuntime was removed.
ContainerRuntime string `json:"containerRuntime,omitempty"`
// The version of kubernetes to install (optional, and can be a "spec" like stable)
KubernetesVersion string `json:"kubernetesVersion,omitempty"`
@ -237,7 +237,7 @@ type ClusterSpec struct {
SysctlParameters []string `json:"sysctlParameters,omitempty"`
// RollingUpdate defines the default rolling-update settings for instance groups
RollingUpdate *RollingUpdate `json:"rollingUpdate,omitempty"`
// ClusterAutoscaler defines the cluaster autoscaler configuration.
// ClusterAutoscaler defines the cluster autoscaler configuration.
ClusterAutoscaler *ClusterAutoscalerConfig `json:"clusterAutoscaler,omitempty"`
// WarmPool defines the default warm pool settings for instance groups (AWS only).
// +k8s:conversion-gen=false
@ -409,7 +409,7 @@ func (s *AuthenticationSpec) IsEmpty() bool {
type KopeioAuthenticationSpec struct{}
type AWSAuthenticationSpec struct {
// Image is the AWS IAM Authenticator docker image to uses
// Image is the AWS IAM Authenticator container image to use.
Image string `json:"image,omitempty"`
// BackendMode is the AWS IAM Authenticator backend to use. Default MountedFile
BackendMode string `json:"backendMode,omitempty"`

View File

@ -116,10 +116,7 @@ type KubeletConfigSpec struct {
ReconcileCIDR *bool `json:"reconcileCIDR,omitempty" flag:"reconcile-cidr"`
// registerSchedulable tells the kubelet to register the node as schedulable. No-op if register-node is false.
RegisterSchedulable *bool `json:"registerSchedulable,omitempty" flag:"register-schedulable"`
//// SerializeImagePulls when enabled, tells the Kubelet to pull images one
//// at a time. We recommend *not* changing the default value on nodes that
//// run docker daemon with version < 1.9 or an Aufs storage backend.
//// Issue #10959 has more details.
// SerializeImagePulls when enabled, tells the Kubelet to pull images one at a time.
SerializeImagePulls *bool `json:"serializeImagePulls,omitempty" flag:"serialize-image-pulls"`
// NodeLabels to add when registering the node in the cluster.
NodeLabels map[string]string `json:"nodeLabels,omitempty" flag:"node-labels"`
@ -184,7 +181,7 @@ type KubeletConfigSpec struct {
AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty" flag:"allowed-unsafe-sysctls"`
// StreamingConnectionIdleTimeout is the maximum time a streaming connection can be idle before the connection is automatically closed
StreamingConnectionIdleTimeout *metav1.Duration `json:"streamingConnectionIdleTimeout,omitempty" flag:"streaming-connection-idle-timeout"`
// DockerDisableSharedPID uses a shared PID namespace for containers in a pod.
// DockerDisableSharedPID was removed.
DockerDisableSharedPID *bool `json:"dockerDisableSharedPID,omitempty" flag:"docker-disable-shared-pid"`
// RootDir is the directory path for managing kubelet files (volume mounts,etc)
RootDir string `json:"rootDir,omitempty" flag:"root-dir"`
@ -284,7 +281,7 @@ type KubeProxyConfig struct {
// KubeAPIServerConfig defines the configuration for the kube api
type KubeAPIServerConfig struct {
// Image is the docker container used
// Image is the container image used.
Image string `json:"image,omitempty"`
// DisableBasicAuth removes the --basic-auth-file flag
DisableBasicAuth *bool `json:"disableBasicAuth,omitempty"`
@ -551,7 +548,7 @@ type KubeControllerManagerConfig struct {
LogLevel int32 `json:"logLevel,omitempty" flag:"v" flag-empty:"0"`
// ServiceAccountPrivateKeyFile is the location of the private key for service account token signing.
ServiceAccountPrivateKeyFile string `json:"serviceAccountPrivateKeyFile,omitempty" flag:"service-account-private-key-file"`
// Image is the docker image to use
// Image is the container image to use.
Image string `json:"image,omitempty"`
// CloudProvider is the provider for cloud services.
CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"`
@ -729,7 +726,7 @@ type KubeSchedulerConfig struct {
LogFormat string `json:"logFormat,omitempty" flag:"logging-format" flag-empty:"text"`
// LogLevel is the logging level
LogLevel int32 `json:"logLevel,omitempty" flag:"v"`
// Image is the docker image to use
// Image is the container image to use.
Image string `json:"image,omitempty"`
// LeaderElection defines the configuration of leader election client.
LeaderElection *LeaderElectionConfiguration `json:"leaderElection,omitempty"`
@ -1040,7 +1037,7 @@ type NodeProblemDetectorConfig struct {
// Enabled enables the NodeProblemDetector.
// Default: false
Enabled *bool `json:"enabled,omitempty"`
// Image is the NodeProblemDetector docker container used.
// Image is the NodeProblemDetector container image used.
Image *string `json:"image,omitempty"`
// MemoryRequest of NodeProblemDetector container.
@ -1101,7 +1098,7 @@ type ClusterAutoscalerConfig struct {
// CordonNodeBeforeTerminating should CA cordon nodes before terminating during downscale process
// Default: false
CordonNodeBeforeTerminating *bool `json:"cordonNodeBeforeTerminating,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`
// MemoryRequest of cluster autoscaler container.
@ -1128,7 +1125,7 @@ type MetricsServerConfig struct {
// Enabled enables the metrics server.
// Default: false
Enabled *bool `json:"enabled,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`
// Insecure determines if API server will validate metrics server TLS cert.
@ -1146,7 +1143,7 @@ type CertManagerConfig struct {
// The deployment of cert-manager is skipped if this is set to false.
Managed *bool `json:"managed,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`

View File

@ -2714,7 +2714,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec,
} else {
out.GossipConfig = nil
}
out.ContainerRuntime = in.ContainerRuntime
// INFO: in.ContainerRuntime opted out of conversion generation
out.KubernetesVersion = in.KubernetesVersion
out.DNSZone = in.DNSZone
if in.DNSControllerGossipConfig != nil {
@ -2764,15 +2764,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec,
} else {
out.Containerd = nil
}
if in.Docker != nil {
in, out := &in.Docker, &out.Docker
*out = new(DockerConfig)
if err := Convert_kops_DockerConfig_To_v1alpha2_DockerConfig(*in, *out, s); err != nil {
return err
}
} else {
out.Docker = nil
}
// INFO: in.Docker opted out of conversion generation
if in.KubeDNS != nil {
in, out := &in.KubeDNS, &out.KubeDNS
*out = new(KubeDNSConfig)
@ -5478,7 +5470,7 @@ func autoConvert_kops_KubeletConfigSpec_To_v1alpha2_KubeletConfigSpec(in *kops.K
out.ExperimentalAllowedUnsafeSysctls = in.ExperimentalAllowedUnsafeSysctls
out.AllowedUnsafeSysctls = in.AllowedUnsafeSysctls
out.StreamingConnectionIdleTimeout = in.StreamingConnectionIdleTimeout
out.DockerDisableSharedPID = in.DockerDisableSharedPID
// INFO: in.DockerDisableSharedPID opted out of conversion generation
out.RootDir = in.RootDir
out.AuthenticationTokenWebhook = in.AuthenticationTokenWebhook
out.AuthenticationTokenWebhookCacheTTL = in.AuthenticationTokenWebhookCacheTTL

View File

@ -57,8 +57,9 @@ type ClusterSpec struct {
CloudProvider CloudProviderSpec `json:"cloudProvider,omitempty"`
// GossipConfig for the cluster assuming the use of gossip DNS
GossipConfig *GossipConfig `json:"gossipConfig,omitempty"`
// Container runtime to use for Kubernetes
ContainerRuntime string `json:"containerRuntime,omitempty"`
// ContainerRuntime was removed.
// +k8s:conversion-gen=false
ContainerRuntime string `json:"-"`
// The version of kubernetes to install (optional, and can be a "spec" like stable)
KubernetesVersion string `json:"kubernetesVersion,omitempty"`
// DNSZone is the DNS zone we should use when configuring DNS
@ -93,8 +94,10 @@ type ClusterSpec struct {
// EtcdClusters stores the configuration for each cluster
EtcdClusters []EtcdClusterSpec `json:"etcdClusters,omitempty"`
// Component configurations
Containerd *ContainerdConfig `json:"containerd,omitempty"`
Docker *DockerConfig `json:"docker,omitempty"`
Containerd *ContainerdConfig `json:"containerd,omitempty"`
// Docker was removed.
// +k8s:conversion-gen=false
Docker *DockerConfig `json:"-"`
KubeDNS *KubeDNSConfig `json:"kubeDNS,omitempty"`
KubeAPIServer *KubeAPIServerConfig `json:"kubeAPIServer,omitempty"`
KubeControllerManager *KubeControllerManagerConfig `json:"kubeControllerManager,omitempty"`

View File

@ -115,10 +115,7 @@ type KubeletConfigSpec struct {
ReconcileCIDR *bool `json:"-"`
// registerSchedulable is not admin-configurable.
RegisterSchedulable *bool `json:"-"`
//// SerializeImagePulls when enabled, tells the Kubelet to pull images one
//// at a time. We recommend *not* changing the default value on nodes that
//// run docker daemon with version < 1.9 or an Aufs storage backend.
//// Issue #10959 has more details.
// SerializeImagePulls when enabled, tells the Kubelet to pull images one at a time.
SerializeImagePulls *bool `json:"serializeImagePulls,omitempty" flag:"serialize-image-pulls"`
// NodeLabels is not admin-configurable.
NodeLabels map[string]string `json:"-"`
@ -183,6 +180,7 @@ type KubeletConfigSpec struct {
// StreamingConnectionIdleTimeout is the maximum time a streaming connection can be idle before the connection is automatically closed
StreamingConnectionIdleTimeout *metav1.Duration `json:"streamingConnectionIdleTimeout,omitempty" flag:"streaming-connection-idle-timeout"`
// DockerDisableSharedPID was removed.
// +k8s:conversion-gen=false
DockerDisableSharedPID *bool `json:"-"`
// RootDir is the directory path for managing kubelet files (volume mounts,etc)
RootDir string `json:"rootDir,omitempty" flag:"root-dir"`
@ -282,7 +280,7 @@ type KubeProxyConfig struct {
// KubeAPIServerConfig defines the configuration for the kube api
type KubeAPIServerConfig struct {
// Image is the docker container used
// Image is the container image used.
Image string `json:"image,omitempty"`
// DisableBasicAuth removes the --basic-auth-file flag
DisableBasicAuth *bool `json:"disableBasicAuth,omitempty"`
@ -542,7 +540,7 @@ type KubeControllerManagerConfig struct {
LogLevel int32 `json:"logLevel,omitempty" flag:"v" flag-empty:"0"`
// ServiceAccountPrivateKeyFile is not admin-configurable.
ServiceAccountPrivateKeyFile string `json:"-"`
// Image is the docker image to use
// Image is the container image to use.
Image string `json:"image,omitempty"`
// CloudProvider is the provider for cloud services.
CloudProvider string `json:"cloudProvider,omitempty" flag:"cloud-provider"`
@ -720,7 +718,7 @@ type KubeSchedulerConfig struct {
LogFormat string `json:"logFormat,omitempty" flag:"logging-format" flag-empty:"text"`
// LogLevel is the logging level
LogLevel int32 `json:"logLevel,omitempty" flag:"v"`
// Image is the docker image to use
// Image is the container image to use.
Image string `json:"image,omitempty"`
// LeaderElection defines the configuration of leader election client.
LeaderElection *LeaderElectionConfiguration `json:"leaderElection,omitempty"`
@ -969,7 +967,7 @@ type NodeProblemDetectorConfig struct {
// Enabled enables the NodeProblemDetector.
// Default: false
Enabled *bool `json:"enabled,omitempty"`
// Image is the NodeProblemDetector docker container used.
// Image is the NodeProblemDetector container image used.
Image *string `json:"image,omitempty"`
// MemoryRequest of NodeProblemDetector container.
@ -1030,7 +1028,7 @@ type ClusterAutoscalerConfig struct {
// CordonNodeBeforeTerminating should CA cordon nodes before terminating during downscale process
// Default: false
CordonNodeBeforeTerminating *bool `json:"cordonNodeBeforeTerminating,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`
// MemoryRequest of cluster autoscaler container.
@ -1057,7 +1055,7 @@ type MetricsServerConfig struct {
// Enabled enables the metrics server.
// Default: false
Enabled *bool `json:"enabled,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`
// Insecure determines if API server will validate metrics server TLS cert.
@ -1075,7 +1073,7 @@ type CertManagerConfig struct {
// The deployment of cert-manager is skipped if this is set to false.
Managed *bool `json:"managed,omitempty"`
// Image is the docker container used.
// Image is the container image used.
// Default: the latest supported image for the specified kubernetes version.
Image *string `json:"image,omitempty"`

View File

@ -2605,7 +2605,7 @@ func autoConvert_v1alpha3_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *
} else {
out.GossipConfig = nil
}
out.ContainerRuntime = in.ContainerRuntime
// INFO: in.ContainerRuntime opted out of conversion generation
out.KubernetesVersion = in.KubernetesVersion
out.DNSZone = in.DNSZone
if in.DNSControllerGossipConfig != nil {
@ -2655,15 +2655,7 @@ func autoConvert_v1alpha3_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *
} else {
out.Containerd = nil
}
if in.Docker != nil {
in, out := &in.Docker, &out.Docker
*out = new(kops.DockerConfig)
if err := Convert_v1alpha3_DockerConfig_To_kops_DockerConfig(*in, *out, s); err != nil {
return err
}
} else {
out.Docker = nil
}
// INFO: in.Docker opted out of conversion generation
if in.KubeDNS != nil {
in, out := &in.KubeDNS, &out.KubeDNS
*out = new(kops.KubeDNSConfig)
@ -2938,7 +2930,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha3_ClusterSpec(in *kops.ClusterSpec,
} else {
out.GossipConfig = nil
}
out.ContainerRuntime = in.ContainerRuntime
// INFO: in.ContainerRuntime opted out of conversion generation
out.KubernetesVersion = in.KubernetesVersion
out.DNSZone = in.DNSZone
if in.DNSControllerGossipConfig != nil {
@ -2988,15 +2980,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha3_ClusterSpec(in *kops.ClusterSpec,
} else {
out.Containerd = nil
}
if in.Docker != nil {
in, out := &in.Docker, &out.Docker
*out = new(DockerConfig)
if err := Convert_kops_DockerConfig_To_v1alpha3_DockerConfig(*in, *out, s); err != nil {
return err
}
} else {
out.Docker = nil
}
// INFO: in.Docker opted out of conversion generation
if in.KubeDNS != nil {
in, out := &in.KubeDNS, &out.KubeDNS
*out = new(KubeDNSConfig)
@ -5768,7 +5752,7 @@ func autoConvert_v1alpha3_KubeletConfigSpec_To_kops_KubeletConfigSpec(in *Kubele
out.ExperimentalAllowedUnsafeSysctls = in.ExperimentalAllowedUnsafeSysctls
out.AllowedUnsafeSysctls = in.AllowedUnsafeSysctls
out.StreamingConnectionIdleTimeout = in.StreamingConnectionIdleTimeout
out.DockerDisableSharedPID = in.DockerDisableSharedPID
// INFO: in.DockerDisableSharedPID opted out of conversion generation
out.RootDir = in.RootDir
out.AuthenticationTokenWebhook = in.AuthenticationTokenWebhook
out.AuthenticationTokenWebhookCacheTTL = in.AuthenticationTokenWebhookCacheTTL
@ -5869,7 +5853,7 @@ func autoConvert_kops_KubeletConfigSpec_To_v1alpha3_KubeletConfigSpec(in *kops.K
out.ExperimentalAllowedUnsafeSysctls = in.ExperimentalAllowedUnsafeSysctls
out.AllowedUnsafeSysctls = in.AllowedUnsafeSysctls
out.StreamingConnectionIdleTimeout = in.StreamingConnectionIdleTimeout
out.DockerDisableSharedPID = in.DockerDisableSharedPID
// INFO: in.DockerDisableSharedPID opted out of conversion generation
out.RootDir = in.RootDir
out.AuthenticationTokenWebhook = in.AuthenticationTokenWebhook
out.AuthenticationTokenWebhookCacheTTL = in.AuthenticationTokenWebhookCacheTTL

View File

@ -69,9 +69,6 @@ func ValidateCluster(c *kops.Cluster, strict bool, vfsContext *vfs.VFSContext) f
if strict && c.Spec.KubeProxy == nil {
allErrs = append(allErrs, field.Required(fieldSpec.Child("kubeProxy"), "kubeProxy not configured"))
}
if strict && c.Spec.Docker == nil {
allErrs = append(allErrs, field.Required(fieldSpec.Child("docker"), "docker not configured"))
}
var nonMasqueradeCIDR *net.IPNet
var serviceClusterIPRange *net.IPNet

View File

@ -188,18 +188,10 @@ func validateClusterSpec(spec *kops.ClusterSpec, c *kops.Cluster, fieldPath *fie
}
}
if spec.ContainerRuntime != "" {
allErrs = append(allErrs, validateContainerRuntime(c, spec.ContainerRuntime, fieldPath.Child("containerRuntime"))...)
}
if spec.Containerd != nil {
allErrs = append(allErrs, validateContainerdConfig(spec, spec.Containerd, fieldPath.Child("containerd"), true)...)
}
if spec.Docker != nil {
allErrs = append(allErrs, validateDockerConfig(spec.Docker, fieldPath.Child("docker"))...)
}
if spec.Assets != nil {
if spec.Assets.ContainerProxy != nil && spec.Assets.ContainerRegistry != nil {
allErrs = append(allErrs, field.Forbidden(fieldPath.Child("assets", "containerProxy"), "containerProxy cannot be used in conjunction with containerRegistry"))
@ -1652,19 +1644,6 @@ func validateCalicoEncapsulationMode(mode string, fldPath *field.Path) field.Err
return allErrs
}
func validateContainerRuntime(c *kops.Cluster, runtime string, fldPath *field.Path) field.ErrorList {
valid := []string{"containerd", "docker"}
allErrs := field.ErrorList{}
allErrs = append(allErrs, IsValidValue(fldPath, &runtime, valid)...)
if runtime == "docker" {
allErrs = append(allErrs, field.Forbidden(fldPath, "Docker CRI support was removed in Kubernetes 1.24: https://kubernetes.io/blog/2020/12/02/dockershim-faq"))
}
return allErrs
}
func validateContainerdConfig(spec *kops.ClusterSpec, config *kops.ContainerdConfig, fldPath *field.Path, inClusterConfig bool) field.ErrorList {
allErrs := field.ErrorList{}
@ -1729,77 +1708,6 @@ func validateContainerdConfig(spec *kops.ClusterSpec, config *kops.ContainerdCon
return allErrs
}
func validateDockerConfig(config *kops.DockerConfig, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if config.Version != nil {
sv, err := semver.ParseTolerant(*config.Version)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version,
fmt.Sprintf("unable to parse version string: %s", err.Error())))
}
if sv.LT(semver.MustParse("1.14.0")) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version,
"version is no longer available: https://www.docker.com/blog/changes-dockerproject-org-apt-yum-repositories"))
} else if sv.LT(semver.MustParse("17.3.0")) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("version"), config.Version,
"unsupported legacy version"))
}
}
if config.Packages != nil {
if config.Packages.UrlAmd64 != nil && config.Packages.HashAmd64 != nil {
u := fi.ValueOf(config.Packages.UrlAmd64)
_, err := url.Parse(u)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageUrl"), config.Packages.UrlAmd64,
fmt.Sprintf("unable parse package URL string: %v", err)))
}
h := fi.ValueOf(config.Packages.HashAmd64)
if len(h) > 64 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageHash"), config.Packages.HashAmd64,
"Package hash must be 64 characters long"))
}
} else if config.Packages.UrlAmd64 != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageUrl"), config.Packages.HashAmd64,
"Package hash must also be set"))
} else if config.Packages.HashAmd64 != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageHash"), config.Packages.HashAmd64,
"Package URL must also be set"))
}
if config.Packages.UrlArm64 != nil && config.Packages.HashArm64 != nil {
u := fi.ValueOf(config.Packages.UrlArm64)
_, err := url.Parse(u)
if err != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageUrlArm64"), config.Packages.UrlArm64,
fmt.Sprintf("unable parse package URL string: %v", err)))
}
h := fi.ValueOf(config.Packages.HashArm64)
if len(h) > 64 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageHashArm64"), config.Packages.HashArm64,
"Package hash must be 64 characters long"))
}
} else if config.Packages.UrlArm64 != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageUrlArm64"), config.Packages.HashArm64,
"Package hash must also be set"))
} else if config.Packages.HashArm64 != nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("packageHashArm64"), config.Packages.HashArm64,
"Package URL must also be set"))
}
}
if config.Storage != nil {
valid := []string{"aufs", "btrfs", "devicemapper", "overlay", "overlay2", "zfs"}
values := strings.Split(*config.Storage, ",")
for _, value := range values {
allErrs = append(allErrs, IsValidValue(fldPath.Child("storage"), &value, valid)...)
}
}
return allErrs
}
func validateNvidiaConfig(spec *kops.ClusterSpec, nvidia *kops.NvidiaGPUConfig, fldPath *field.Path, inClusterConfig bool) (allErrs field.ErrorList) {
if !fi.ValueOf(nvidia.Enabled) {
return allErrs
@ -1807,9 +1715,6 @@ func validateNvidiaConfig(spec *kops.ClusterSpec, nvidia *kops.NvidiaGPUConfig,
if spec.GetCloudProvider() != kops.CloudProviderAWS && spec.GetCloudProvider() != kops.CloudProviderOpenstack {
allErrs = append(allErrs, field.Forbidden(fldPath, "Nvidia is only supported on AWS and OpenStack"))
}
if spec.ContainerRuntime != "" && spec.ContainerRuntime != "containerd" {
allErrs = append(allErrs, field.Forbidden(fldPath, "Nvidia is only supported using containerd"))
}
if spec.GetCloudProvider() == kops.CloudProviderOpenstack && inClusterConfig {
allErrs = append(allErrs, field.Forbidden(fldPath, "OpenStack supports nvidia configuration only in instance group"))
}

View File

@ -339,27 +339,6 @@ func TestValidateKubeAPIServer(t *testing.T) {
}
}
func Test_Validate_DockerConfig_Storage(t *testing.T) {
for _, name := range []string{"aufs", "zfs", "overlay"} {
config := &kops.DockerConfig{Storage: &name}
errs := validateDockerConfig(config, field.NewPath("docker"))
if len(errs) != 0 {
t.Fatalf("Unexpected errors validating DockerConfig %q", errs)
}
}
for _, name := range []string{"overlayfs", "", "au"} {
config := &kops.DockerConfig{Storage: &name}
errs := validateDockerConfig(config, field.NewPath("docker"))
if len(errs) != 1 {
t.Fatalf("Expected errors validating DockerConfig %+v", config)
}
if errs[0].Field != "docker.storage" || errs[0].Type != field.ErrorTypeNotSupported {
t.Fatalf("Not the expected error validating DockerConfig %q", errs)
}
}
}
func Test_Validate_Networking_Flannel(t *testing.T) {
grid := []struct {
Input kops.FlannelNetworkingSpec
@ -1451,7 +1430,6 @@ func Test_Validate_Nvidia_Cluster(t *testing.T) {
CloudProvider: kops.CloudProviderSpec{
AWS: &kops.AWSSpec{},
},
ContainerRuntime: "containerd",
},
},
{
@ -1464,7 +1442,6 @@ func Test_Validate_Nvidia_Cluster(t *testing.T) {
CloudProvider: kops.CloudProviderSpec{
Openstack: &kops.OpenstackSpec{},
},
ContainerRuntime: "containerd",
},
ExpectedErrors: []string{"Forbidden::containerd.nvidiaGPU"},
},
@ -1478,21 +1455,6 @@ func Test_Validate_Nvidia_Cluster(t *testing.T) {
CloudProvider: kops.CloudProviderSpec{
GCE: &kops.GCESpec{},
},
ContainerRuntime: "containerd",
},
ExpectedErrors: []string{"Forbidden::containerd.nvidiaGPU"},
},
{
Input: kops.ClusterSpec{
Containerd: &kops.ContainerdConfig{
NvidiaGPU: &kops.NvidiaGPUConfig{
Enabled: fi.PtrTo(true),
},
},
CloudProvider: kops.CloudProviderSpec{
AWS: &kops.AWSSpec{},
},
ContainerRuntime: "docker",
},
ExpectedErrors: []string{"Forbidden::containerd.nvidiaGPU"},
},
@ -1518,7 +1480,6 @@ func Test_Validate_Nvidia_Ig(t *testing.T) {
CloudProvider: kops.CloudProviderSpec{
AWS: &kops.AWSSpec{},
},
ContainerRuntime: "containerd",
},
},
{
@ -1531,7 +1492,6 @@ func Test_Validate_Nvidia_Ig(t *testing.T) {
CloudProvider: kops.CloudProviderSpec{
Openstack: &kops.OpenstackSpec{},
},
ContainerRuntime: "containerd",
},
},
{
@ -1544,21 +1504,6 @@ func Test_Validate_Nvidia_Ig(t *testing.T) {
CloudProvider: kops.CloudProviderSpec{
GCE: &kops.GCESpec{},
},
ContainerRuntime: "containerd",
},
ExpectedErrors: []string{"Forbidden::containerd.nvidiaGPU"},
},
{
Input: kops.ClusterSpec{
Containerd: &kops.ContainerdConfig{
NvidiaGPU: &kops.NvidiaGPUConfig{
Enabled: fi.PtrTo(true),
},
},
CloudProvider: kops.CloudProviderSpec{
AWS: &kops.AWSSpec{},
},
ContainerRuntime: "docker",
},
ExpectedErrors: []string{"Forbidden::containerd.nvidiaGPU"},
},

View File

@ -88,12 +88,8 @@ type Config struct {
FileAssets []kops.FileAssetSpec `json:",omitempty"`
// Hooks are for custom actions, for example on first installation.
Hooks [][]kops.HookSpec
// ContainerRuntime is the container runtime to use for Kubernetes.
ContainerRuntime string
// ContainerdConfig holds the configuration for containerd.
ContainerdConfig *kops.ContainerdConfig `json:"containerdConfig,omitempty"`
// Docker holds the configuration for docker.
Docker *kops.DockerConfig `json:"docker,omitempty"`
// APIServerConfig is additional configuration for nodes running an APIServer.
APIServerConfig *APIServerConfig `json:",omitempty"`
@ -172,7 +168,7 @@ type ConfigServerOptions struct {
CACertificates string
}
// Image is a docker image we should pre-load
// Image is a container image we should pre-load
type Image struct {
// This is the name we would pass to "docker run", whereas source could be a URL from which we would download an image.
Name string `json:"name,omitempty"`
@ -236,8 +232,6 @@ func NewConfig(cluster *kops.Cluster, instanceGroup *kops.InstanceGroup) (*Confi
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,
UsesLegacyGossip: cluster.UsesLegacyGossip(),
UsesNoneDNS: cluster.UsesNoneDNS(),
}

View File

@ -97,16 +97,6 @@ func TestSetClusterFields(t *testing.T) {
},
},
},
{
Fields: []string{"spec.docker.selinuxEnabled=true"},
Output: kops.Cluster{
Spec: kops.ClusterSpec{
Docker: &kops.DockerConfig{
SelinuxEnabled: fi.PtrTo(true),
},
},
},
},
{
Fields: []string{"spec.kubernetesVersion=v1.2.3"},
Output: kops.Cluster{

View File

@ -107,21 +107,6 @@ func TestUnsetClusterFields(t *testing.T) {
},
},
},
{
Fields: []string{"spec.docker.selinuxEnabled"},
Input: kops.Cluster{
Spec: kops.ClusterSpec{
Docker: &kops.DockerConfig{
SelinuxEnabled: fi.PtrTo(true),
},
},
},
Output: kops.Cluster{
Spec: kops.ClusterSpec{
Docker: &kops.DockerConfig{},
},
},
},
{
Fields: []string{"spec.kubernetesVersion"},
Input: kops.Cluster{

View File

@ -241,13 +241,9 @@ func makeTestCluster(hookSpecRoles []kops.InstanceGroupRole, fileAssetSpecRoles
Image: "gcr.io/etcd-development/etcd:v3.1.11",
},
},
ContainerRuntime: "docker",
Containerd: &kops.ContainerdConfig{
LogLevel: fi.PtrTo("info"),
},
Docker: &kops.DockerConfig{
LogLevel: fi.PtrTo("INFO"),
},
KubeAPIServer: &kops.KubeAPIServerConfig{
Image: "CoreOS",
},

View File

@ -39,39 +39,34 @@ func (b *ContainerdOptionsBuilder) BuildOptions(o interface{}) error {
containerd := clusterSpec.Containerd
if clusterSpec.ContainerRuntime == "containerd" {
// Set version based on Kubernetes version
if fi.ValueOf(containerd.Version) == "" {
switch {
case b.IsKubernetesLT("1.24.14"):
fallthrough
case b.IsKubernetesGTE("1.25") && b.IsKubernetesLT("1.25.10"):
fallthrough
case b.IsKubernetesGTE("1.26") && b.IsKubernetesLT("1.26.5"):
fallthrough
case b.IsKubernetesGTE("1.27") && b.IsKubernetesLT("1.27.2"):
containerd.Version = fi.PtrTo("1.6.20")
containerd.Runc = &kops.Runc{
Version: fi.PtrTo("1.1.5"),
}
case b.IsKubernetesGTE("1.27.2"):
containerd.Version = fi.PtrTo("1.7.2")
containerd.Runc = &kops.Runc{
Version: fi.PtrTo("1.1.7"),
}
default:
containerd.Version = fi.PtrTo("1.6.21")
containerd.Runc = &kops.Runc{
Version: fi.PtrTo("1.1.7"),
}
// Set version based on Kubernetes version
if fi.ValueOf(containerd.Version) == "" {
switch {
case b.IsKubernetesLT("1.24.14"):
fallthrough
case b.IsKubernetesGTE("1.25") && b.IsKubernetesLT("1.25.10"):
fallthrough
case b.IsKubernetesGTE("1.26") && b.IsKubernetesLT("1.26.5"):
fallthrough
case b.IsKubernetesGTE("1.27") && b.IsKubernetesLT("1.27.2"):
containerd.Version = fi.PtrTo("1.6.20")
containerd.Runc = &kops.Runc{
Version: fi.PtrTo("1.1.5"),
}
case b.IsKubernetesGTE("1.27.2"):
containerd.Version = fi.PtrTo("1.7.2")
containerd.Runc = &kops.Runc{
Version: fi.PtrTo("1.1.7"),
}
default:
containerd.Version = fi.PtrTo("1.6.21")
containerd.Runc = &kops.Runc{
Version: fi.PtrTo("1.1.7"),
}
}
// Set default log level to INFO
containerd.LogLevel = fi.PtrTo("info")
} else {
// Unknown container runtime, should not install containerd
containerd.SkipInstall = true
}
// Set default log level to INFO
containerd.LogLevel = fi.PtrTo("info")
if containerd.NvidiaGPU != nil && fi.ValueOf(containerd.NvidiaGPU.Enabled) && containerd.NvidiaGPU.DriverPackage == "" {
containerd.NvidiaGPU.DriverPackage = kops.NvidiaDefaultDriverPackage

View File

@ -45,7 +45,6 @@ func Test_Build_Containerd_Supported_Version(t *testing.T) {
for _, v := range kubernetesVersions {
c := buildContainerdCluster(v)
c.Spec.ContainerRuntime = "containerd"
b := assets.NewAssetBuilder(vfs.Context, c.Spec.Assets, c.Spec.KubernetesVersion, false)
version, err := util.ParseKubernetesVersion(v)

View File

@ -36,13 +36,5 @@ func (b *DefaultsOptionsBuilder) BuildOptions(o interface{}) error {
options.ClusterDNSDomain = "cluster.local"
}
if options.ContainerRuntime == "" {
if options.Docker != nil {
options.ContainerRuntime = "docker"
} else {
options.ContainerRuntime = "containerd"
}
}
return nil
}

View File

@ -1,89 +0,0 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package components
import (
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/loader"
)
// DockerOptionsBuilder adds options for docker to the model
type DockerOptionsBuilder struct {
*OptionsContext
}
var _ loader.OptionsBuilder = &DockerOptionsBuilder{}
// BuildOptions is responsible for filling in the default setting for docker daemon
func (b *DockerOptionsBuilder) BuildOptions(o interface{}) error {
clusterSpec := o.(*kops.ClusterSpec)
if clusterSpec.Docker == nil {
clusterSpec.Docker = &kops.DockerConfig{}
}
docker := clusterSpec.Docker
// Container runtime is not Docker, should not install
if clusterSpec.ContainerRuntime != "docker" {
docker.SkipInstall = true
return nil
}
// Set the Docker version for known Kubernetes versions
if fi.ValueOf(clusterSpec.Docker.Version) == "" {
docker.Version = fi.PtrTo("20.10.17")
}
if len(clusterSpec.Docker.LogOpt) == 0 && clusterSpec.Docker.LogDriver == nil {
// Use built-in docker logging, if not configured otherwise (by the user)
logDriver := "json-file"
clusterSpec.Docker.LogDriver = &logDriver
clusterSpec.Docker.LogOpt = append(clusterSpec.Docker.LogOpt, "max-size=10m")
clusterSpec.Docker.LogOpt = append(clusterSpec.Docker.LogOpt, "max-file=5")
}
docker.LogLevel = fi.PtrTo("info")
docker.IPTables = fi.PtrTo(false)
docker.IPMasq = fi.PtrTo(false)
// Note the alternative syntax... with a comma nodeup will try each of the filesystems in turn
// TODO(justinsb): The ContainerOS image now has docker configured to use overlay2 out-of-the-box
// and it is an error to specify the flag twice.
docker.Storage = fi.PtrTo("overlay2,overlay,aufs")
// Set systemd as the default cgroup driver in docker from k8s 1.20.
if getDockerCgroupDriver(docker.ExecOpt) == "" {
docker.ExecOpt = append(docker.ExecOpt, "native.cgroupdriver=systemd")
}
return nil
}
// checks if cgroup-driver is configured or not for docker or not.
func getDockerCgroupDriver(execOpts []string) string {
for _, value := range execOpts {
if value == "native.cgroupdriver=systemd" {
return "systemd"
} else if value == "native.cgroupdriver=cgroupfs" {
return "cgroupfs"
}
}
return ""
}

View File

@ -33,7 +33,6 @@ func BuildMinimalCluster(clusterName string) *kops.Cluster {
{Name: "subnet-us-test-1a", Zone: "us-test-1a", CIDR: "172.20.1.0/24", Type: kops.SubnetTypePrivate},
}
c.Spec.ContainerRuntime = "containerd"
c.Spec.Containerd = &kops.ContainerdConfig{}
c.Spec.API.PublicName = fmt.Sprintf("api.%v", clusterName)

View File

@ -1080,41 +1080,24 @@ func (c *ApplyClusterCmd) addFileAssets(assetBuilder *assets.AssetBuilder) error
c.Assets[arch] = append(c.Assets[arch], mirrors.BuildMirroredAsset(cniAsset, cniAssetHash))
}
switch c.Cluster.Spec.ContainerRuntime {
case "docker":
if c.Cluster.Spec.Docker != nil && c.Cluster.Spec.Docker.SkipInstall {
break
}
if c.Cluster.Spec.Containerd != nil && c.Cluster.Spec.Containerd.SkipInstall {
break
}
dockerAssetUrl, dockerAssetHash, err := findDockerAsset(c.Cluster, assetBuilder, arch)
if err != nil {
return err
}
if dockerAssetUrl != nil && dockerAssetHash != nil {
c.Assets[arch] = append(c.Assets[arch], mirrors.BuildMirroredAsset(dockerAssetUrl, dockerAssetHash))
}
case "containerd":
if c.Cluster.Spec.Containerd != nil && c.Cluster.Spec.Containerd.SkipInstall {
break
}
containerdAssetUrl, containerdAssetHash, err := findContainerdAsset(c.Cluster, assetBuilder, arch)
if err != nil {
return err
}
if containerdAssetUrl != nil && containerdAssetHash != nil {
c.Assets[arch] = append(c.Assets[arch], mirrors.BuildMirroredAsset(containerdAssetUrl, containerdAssetHash))
}
containerdAssetUrl, containerdAssetHash, err := findContainerdAsset(c.Cluster, assetBuilder, arch)
if err != nil {
return err
}
if containerdAssetUrl != nil && containerdAssetHash != nil {
c.Assets[arch] = append(c.Assets[arch], mirrors.BuildMirroredAsset(containerdAssetUrl, containerdAssetHash))
}
runcAssetUrl, runcAssetHash, err := findRuncAsset(c.Cluster, assetBuilder, arch)
if err != nil {
return err
}
if runcAssetUrl != nil && runcAssetHash != nil {
c.Assets[arch] = append(c.Assets[arch], mirrors.BuildMirroredAsset(runcAssetUrl, runcAssetHash))
}
default:
return fmt.Errorf("unknown container runtime: %q", c.Cluster.Spec.ContainerRuntime)
runcAssetUrl, runcAssetHash, err := findRuncAsset(c.Cluster, assetBuilder, arch)
if err != nil {
return err
}
if runcAssetUrl != nil && runcAssetHash != nil {
c.Assets[arch] = append(c.Assets[arch], mirrors.BuildMirroredAsset(runcAssetUrl, runcAssetHash))
}
asset, err := NodeUpAsset(assetBuilder, arch)

View File

@ -108,3 +108,22 @@ func findContainerdVersionUrl(arch architectures.Architecture, version string) (
return u, nil
}
func findAssetsUrlHash(assetBuilder *assets.AssetBuilder, assetUrl string, assetHash string) (*url.URL, *hashing.Hash, error) {
u, err := url.Parse(assetUrl)
if err != nil {
return nil, nil, fmt.Errorf("unable to parse asset URL %q: %v", assetUrl, err)
}
h, err := hashing.FromString(assetHash)
if err != nil {
return nil, nil, fmt.Errorf("unable to parse asset hash %q: %v", assetHash, err)
}
u, err = assetBuilder.RemapFileAndSHAValue(u, assetHash)
if err != nil {
return nil, nil, fmt.Errorf("unable to remap asset: %v", err)
}
return u, h, nil
}

View File

@ -1,295 +0,0 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloudup
import (
"fmt"
"net/url"
"github.com/blang/semver/v4"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/pkg/assets"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/util/pkg/architectures"
"k8s.io/kops/util/pkg/hashing"
)
const (
// Docker packages URLs for v18.09.0+
dockerVersionUrlAmd64 = "https://download.docker.com/linux/static/stable/x86_64/docker-%s.tgz"
dockerVersionUrlArm64 = "https://download.docker.com/linux/static/stable/aarch64/docker-%s.tgz"
// Docker legacy AMD64 packages URLs for v17.03.0 to v18.06.3
dockerLegacyUrlAmd64 = "https://download.docker.com/linux/static/stable/x86_64/docker-%s-ce.tgz"
// Docker legacy ARM64 packages URLs for v17.09.0 to v18.06.3
dockerLegacyUrlArm64 = "https://download.docker.com/linux/static/stable/aarch64/docker-%s-ce.tgz"
// Docker version that is available for both AMD64 and ARM64, used in case the selected version is too old and not available for ARM64
dockerFallbackVersion = "17.09.0"
)
func findDockerAsset(c *kops.Cluster, assetBuilder *assets.AssetBuilder, arch architectures.Architecture) (*url.URL, *hashing.Hash, error) {
if c.Spec.Docker == nil {
return nil, nil, fmt.Errorf("unable to find Docker config")
}
docker := c.Spec.Docker
if docker.Packages != nil {
if arch == architectures.ArchitectureAmd64 && docker.Packages.UrlAmd64 != nil && docker.Packages.HashAmd64 != nil {
assetUrl := fi.ValueOf(docker.Packages.UrlAmd64)
assetHash := fi.ValueOf(docker.Packages.HashAmd64)
return findAssetsUrlHash(assetBuilder, assetUrl, assetHash)
}
if arch == architectures.ArchitectureArm64 && docker.Packages.UrlArm64 != nil && docker.Packages.HashArm64 != nil {
assetUrl := fi.ValueOf(docker.Packages.UrlArm64)
assetHash := fi.ValueOf(docker.Packages.HashArm64)
return findAssetsUrlHash(assetBuilder, assetUrl, assetHash)
}
}
version := fi.ValueOf(docker.Version)
if version == "" {
return nil, nil, fmt.Errorf("unable to find Docker version")
}
assetUrl, assetHash, err := findDockerVersionUrlHash(arch, version)
if err != nil {
return nil, nil, err
}
return findAssetsUrlHash(assetBuilder, assetUrl, assetHash)
}
func findDockerVersionUrlHash(arch architectures.Architecture, version string) (u string, h string, e error) {
dockerAssetUrl, err := findDockerVersionUrl(arch, version)
if err != nil {
return "", "", err
}
dockerAssetHash, err := findDockerVersionHash(arch, version)
if err != nil {
return "", "", err
}
return dockerAssetUrl, dockerAssetHash, nil
}
func findDockerVersionUrl(arch architectures.Architecture, version string) (string, error) {
sv, err := semver.ParseTolerant(version)
if err != nil {
return "", fmt.Errorf("unable to parse version string: %q", version)
}
if sv.LT(semver.MustParse("17.3.0")) {
return "", fmt.Errorf("unsupported legacy Docker version: %q", version)
}
var u string
switch arch {
case architectures.ArchitectureAmd64:
if sv.GTE(semver.MustParse("18.9.0")) {
u = fmt.Sprintf(dockerVersionUrlAmd64, version)
} else {
u = fmt.Sprintf(dockerLegacyUrlAmd64, version)
}
case architectures.ArchitectureArm64:
if sv.GTE(semver.MustParse("18.9.0")) {
u = fmt.Sprintf(dockerVersionUrlArm64, version)
} else if sv.GTE(semver.MustParse("17.9.0")) {
u = fmt.Sprintf(dockerLegacyUrlArm64, version)
} else {
u = fmt.Sprintf(dockerLegacyUrlArm64, dockerFallbackVersion)
}
default:
return "", fmt.Errorf("unknown arch: %q", arch)
}
return u, nil
}
func findDockerVersionHash(arch architectures.Architecture, version string) (string, error) {
sv, err := semver.ParseTolerant(version)
if err != nil {
return "", fmt.Errorf("unable to parse version string: %q", version)
}
if sv.LT(semver.MustParse("17.3.0")) {
return "", fmt.Errorf("unsupported legacy Docker version: %q", version)
}
var h string
switch arch {
case architectures.ArchitectureAmd64:
h = findAllDockerHashesAmd64()[version]
case architectures.ArchitectureArm64:
if sv.GTE(semver.MustParse("17.9.0")) {
h = findAllDockerHashesArm64()[version]
} else {
h = findAllDockerHashesArm64()[dockerFallbackVersion]
}
default:
return "", fmt.Errorf("unknown arch: %q", arch)
}
if h == "" {
return "", fmt.Errorf("unknown hash for Docker version: %s - %s", arch, version)
}
return h, nil
}
func findAllDockerHashesAmd64() map[string]string {
hashes := map[string]string{
"17.03.0": "aac08524db82d3fdc8fc092f495e1174f5e1dd774b95a6d081544997d34b4855",
"17.03.1": "3e070e7b34e99cf631f44d0ff5cf9a127c0b8af5c53dfc3e1fce4f9615fbf603",
"17.03.2": "183b31b001e7480f3c691080486401aa519101a5cfe6e05ad01b9f5521c4112d",
"17.06.0": "e582486c9db0f4229deba9f8517145f8af6c5fae7a1243e6b07876bd3e706620",
"17.06.1": "e35fe12806eadbb7eb8aa63e3dfb531bda5f901cd2c14ac9cdcd54df6caed697",
"17.06.2": "a15f62533e773c40029a61784a5a1c5bc7dd21e0beb5402fda109f80e1f2994d",
"17.09.0": "a9e90a73c3cdfbf238f148e1ec0eaff5eb181f92f35bdd938fd7dab18e1c4647",
"17.09.1": "77d3eaa72f2b63c94ea827b548f4a8b572b754a431c59258e3f2730411f64be7",
"17.12.0": "692e1c72937f6214b1038def84463018d8e320c8eaf8530546c84c2f8f9c767d",
"17.12.1": "1270dce1bd7e1838d62ae21d2505d87f16efc1d9074645571daaefdfd0c14054",
"18.03.0": "e5dff6245172081dbf14285dafe4dede761f8bc1750310156b89928dbf56a9ee",
"18.03.1": "0e245c42de8a21799ab11179a4fce43b494ce173a8a2d6567ea6825d6c5265aa",
"18.06.0": "1c2fa625496465c68b856db0ba850eaad7a16221ca153661ca718de4a2217705",
"18.06.1": "83be159cf0657df9e1a1a4a127d181725a982714a983b2bdcc0621244df93687",
"18.06.2": "a979d9a952fae474886c7588da692ee00684cb2421d2c633c7ed415948cf0b10",
"18.06.3": "346f9394393ee8db5f8bd1e229ee9d90e5b36931bdd754308b2ae68884dd6822",
"18.09.0": "08795696e852328d66753963249f4396af2295a7fe2847b839f7102e25e47cb9",
"18.09.1": "c9959e42b637fb7362899ac1d1aeef2a966fa0ea85631da91f4c4a7a9ec29644",
"18.09.2": "183e10448f0c3a0dc82c9d504c5280c29527b89af0fc71cb27115d684b26c8bd",
"18.09.3": "8b886106cfc362f1043debfe178c35b6f73ec42380b034a3919a235fe331e053",
"18.09.4": "7baf380a9d503286b3745114e0d8e265897edd9642747b1992459e550fc5c827",
"18.09.5": "99ca9395e9c7ffbf75537de71aa828761f492491d02bc6e29db2920fa582c6c5",
"18.09.6": "1f3f6774117765279fce64ee7f76abbb5f260264548cf80631d68fb2d795bb09",
"18.09.7": "e106ccfa2b1f60794faaa6bae57a2dac9dc4cb33e5541fad6a826ea525d01cc4",
"18.09.8": "12277eff64363f51ba2f20dd258bdc2c3248022996c0251921193ec6fd179e52",
"18.09.9": "82a362af7689038c51573e0fd0554da8703f0d06f4dfe95dd5bda5acf0ae45fb",
"19.03.0": "b7bb0c3610b3f6ee87457dfb440968dbcc3537198c3d6e2468fcf90819855d6f",
"19.03.1": "6e7d8e24ee46b13d7547d751696d01607d19c8224c1b2c867acc8c779e77734b",
"19.03.2": "865038730c79ab48dfed1365ee7627606405c037f46c9ae17c5ec1f487da1375",
"19.03.3": "c3c8833e227b61fe6ce0bc5c17f97fa547035bef4ef17cf6601f30b0f20f4ce5",
"19.03.4": "efef2ad32d262674501e712351be0df9dd31d6034b175d0020c8f5d5c9c3fd10",
"19.03.5": "50cdf38749642ec43d6ac50f4a3f1f7f6ac688e8d8b4e1c5b7be06e1a82f06e9",
"19.03.6": "34ff89ce917796594cd81149b1777d07786d297ffd0fef37a796b5897052f7cc",
"19.03.7": "033e97ae6b31e21c598fd089ea034c08d75dc744ceb787898d63dfc4e45ead03",
"19.03.8": "7f4115dc6a3c19c917f8b9664d7b51c904def1c984e082c4600097433323cf6f",
"19.03.9": "1c03c78be198d9085e7dd6806fc5d93264baaf0c7ea17f584d00af48eae508ee",
"19.03.10": "7c1576a0bc749418d1423d2b78c8920b5d61f849789904612862dd118742e82b",
"19.03.11": "0f4336378f61ed73ed55a356ac19e46699a995f2aff34323ba5874d131548b9e",
"19.03.12": "88de1b87b8a2582fe827154899475a72fb707c5793cfb39d2a24813ba1f31197",
"19.03.13": "ddb13aff1fcdcceb710bf71a210169b9c1abfd7420eeaf42cf7975f8fae2fcc8",
"19.03.14": "9f1ec28e357a8f18e9561129239caf9c0807d74756e21cc63637c7fdeaafe847",
"19.03.15": "5504d190eef37355231325c176686d51ade6e0cabe2da526d561a38d8611506f",
"20.10.0": "02936a3585f12f13b21b95e02ae722d74eaf1870b536997e914659ee307b2ac4",
"20.10.1": "8790f3b94ee07ca69a9fdbd1310cbffc729af0a07e5bf9f34a79df1e13d2e50e",
"20.10.2": "97017e32a8ecbdd1826bb3c7b1424303ee0dea3f900d33591b1df5e394ed4eed",
"20.10.3": "47065a47f0692cd5af03073c7386fe090d9ef5ac88a7d8455a884d8e15809be5",
"20.10.4": "6ec28b6a251e093f5cf32569c4bfce4821eda02923b33c060694e6ca2c851daa",
"20.10.5": "3f18edc66e1faae607d428349e77f9800bdea554528521f0f6c49fc3f1de6abf",
"20.10.6": "e3b6c3b11518281a51fb0eee73138482b83041e908f01adf8abd3a24b34ea21e",
"20.10.7": "34ad50146fce29b28e5115a1e8510dd5232459c9a4a9f28f65909f92cca314d9",
"20.10.8": "7ea11ecb100fdc085dbfd9ab1ff380e7f99733c890ed815510a5952e5d6dd7e0",
"20.10.9": "caf74e54b58c0b38bb4d96c8f87665f29b684371c9a325562a3904b8c389995e",
"20.10.10": "1719446f99cd56e87d0c67019996af4ea859f11891bfd89de2252d6c916ccaaa",
"20.10.11": "dd6ff72df1edfd61ae55feaa4aadb88634161f0aa06dbaaf291d1be594099ff3",
"20.10.12": "ee9b5be14e54bf92f48c82c2e6a83fbdd1c5329e8f247525a9ed2fe90d9f89a5",
"20.10.13": "39edf7c8d773939ff5e4d318ae565691a9c7e754ed768e172757e58898fb7079",
"20.10.14": "7ca4aeeed86619909ae584ce3405da3766d495f98904ffbd9d859add26b83af5",
"20.10.15": "9ccfc39305ae1d8882d18c9c431544fca82913d6df717409ac2244ac58c4f070",
"20.10.16": "b43ac6c4d2f0b64e445c6564860e4fccd6331f4a61815a60642c7748b53c59ff",
"20.10.17": "969210917b5548621a2b541caf00f86cc6963c6cf0fb13265b9731c3b98974d9",
}
return hashes
}
func findAllDockerHashesArm64() map[string]string {
hashes := map[string]string{
"17.09.0": "2af5d112ab514d9b0b84d9e7360a5e7633e88b7168d1bbfc16c6532535cb0123",
"17.09.1": "a254b0f7d6fb32c786e272f7b042e010e9cae8e168ad34f7f7cca146f07e03e9",
"17.12.0": "b740a4475205ba8a0eb74262171be91f5a18f75554d5922d8247bf40e551f013",
"17.12.1": "79ec237e1ae7e2194aa13908b37fd8ccddaf2f2039d26a0be1a7bbd5d4ea3dff",
"18.03.0": "096522d1c9979dab76458bb443e9266d9f77c7c725fe6cffe3de31aca19c08f9",
"18.03.1": "483a25771d859a492ff253070471c75e062c1b43e5c3a4961fe1ac508e1ffe2c",
"18.06.0": "3cb454a5a5d999dff2daac0bb5d060c1fb9cf7beab3327a44e446b09f14cca58",
"18.06.1": "57582655ee7fe05913ffa347518c82f126321e7d71945bb6440d6f059e21528c",
"18.06.2": "6e7875fef7e96146c4f8994fcc24be028ec72f9f8f9ee2a832b3972dbc51d406",
"18.06.3": "defb2ccc95c0825833216c8b9e0e15baaa51bcedb3efc1f393f5352d184dead4",
"18.09.0": "c5e20dccb8ac02f2da30755ece2f4a29497afc274685835e7a6093f0cb813565",
"18.09.1": "3b94859ca5aa735292d31e32d7e5e33710da92de332b68348967565fc6d8d345",
"18.09.2": "458968bc8a4d4d3003097924c27fcfff0abdf8e52b7d3e9f6e09072c1dd42095",
"18.09.3": "b80971843aed5b0fdc478de6886499cdac7b34df059b7b46606643d1bdb64fc7",
"18.09.4": "177582a220a0a674ea5ebf6c770db6527d7f5cfb1c3811c6118bd2aed7fbc826",
"18.09.5": "549ea10709d9ed22b6435a072ea2d9dd7fc14950eb141cfbdd4653d0c12a54e2",
"18.09.6": "c4857639514471e2d1aa6d567880b7fc226437ede462021ed44157d4dcd11dc8",
"18.09.7": "961bbf1f826565e17dbcf5f89e8707ab4300139337920f8db1306dac5a9b6bb7",
"18.09.8": "243f74025612ca940f7c4c151f98a87f87a71da7e6fdce92794401906ddbffc8",
"18.09.9": "c6f4cfe1bef71c339d5127c6c79169479bcb7830c6fb0185139d32ab726e038e",
"19.03.0": "88bcbe5898b999d67cf158d5d57dd8e3d905a6cdbca669e696b6ff7554057d21",
"19.03.1": "44158b9fe44e8b5d3c1226a5d880425850d6f8ec383e4cf053f401e1a8fc269d",
"19.03.2": "3bd1bbd2e2eebf0083d684f02217e9215c1475f4ffecd28f824efc2e8585d670",
"19.03.3": "d6abb961d5c71a9a15b067de796c581f6ae8ee79044a6d98d529912095853ea7",
"19.03.4": "03c10ddd2862234d47c434455af7d27979c91448445ed3658cf383455b56e1a2",
"19.03.5": "0deddac5ae6f18ff0e6ce6a143c2cfd99c56dfb58be507770d840240fc9c51a9",
"19.03.6": "3840f64aad8f4d63851ef2d3401eb08471f8a46fb13382ae0d49913eac196f1f",
"19.03.7": "730058a50102dbf9278e5d164c385a437016c8c8201d6d19195d9321d0a70ec9",
"19.03.8": "b19da81ca82123aa0b9191c1f19c0c2632cc50d5f8c2cdb04e5b5976e3268b3b",
"19.03.9": "5d6ede3368eac8e74ead70489aa7e4e663fe1ccfbb9763a6ac55991d55b70354",
"19.03.10": "c949aef8c40beea732ec497d27b8d203799ee0f34b0d330c7001d57601e5c34d",
"19.03.11": "9cd49fe82f6b7ec413b04daef35bc0c87b01d6da67611e5beef36291538d3145",
"19.03.12": "bc7810d58e32360652abfddc9cb43405feee4ed9592aedc1132fb35eede9fa9e",
"19.03.13": "bdf080af7d6f383ad80e415e9c1952a63c7038c149dc673b7598bfca4d3311ec",
"19.03.14": "8350eaa0c0965bb8eb9d45a014f4b6728c985715f56466077dfe6feb271d9518",
"19.03.15": "264f3396630507606a8646fda6a28a98d3ced8927df84be8ee9a74ab73cc1566",
"20.10.0": "6e3f80e8451ecbe7b3559247721c3e226be6b228acaadee7e13683f80c20e81c",
"20.10.1": "ec2a42e52614e835b373f3f5c090e2f6a8a333ea52fa02ab9d8f4ac74a2f90d5",
"20.10.2": "9ea59f249ae92bbaa9831a22f2affa2edc9e824f9daaba831ca51d6d22ef2df5",
"20.10.3": "4dcd105f721297f314bb53622e67dd981a743d72f4b2bfe4f42a8790e0892c82",
"20.10.4": "bd9fb2f770eb508b3273237c5604266b6cd93789d048069bd6b16efbf8919fca",
"20.10.5": "83157b92d7469117c2720fc44074749e080b3c510ae35b8a57c66a016cf07dd5",
"20.10.6": "998b3b6669335f1a1d8c475fb7c211ed1e41c2ff37275939e2523666ccb7d910",
"20.10.7": "be8c9a5a06ebec8fb1d36e867cd00fb5777746a9812a0cae2966778ff899c525",
"20.10.8": "4eb9d5e2adf718cd7ee59f6951715f3113c9c4ee49c75c9efb9747f2c3457b2b",
"20.10.9": "0259f8b6572f02cf0dafd7388ca0e4adfdbbfaba81cfb1b7443e89fccbed22c7",
"20.10.10": "8db47cdcd7ac6e082c9ce83347d8fb99eaa01e04b0c8d94851e8d58f350a3633",
"20.10.11": "87a4219c54552797ffd38790b72832372a90eceb7c8e451c36a682093d57dae6",
"20.10.12": "e1f964e9a7a824bbe2164560c0eb335fab9cc7ee9eb90da36c250c073459cf17",
"20.10.13": "debed306ed9a4e70dcbcb228a0b3898f9730099e324f34bb0e76abbaddf7a6a7",
"20.10.14": "ea971edc1179088bfd25edd04a0c12848143d15cb8202ebb93a6a08973464fd0",
"20.10.15": "46102273fab8d6b8a7cf248a928ebaa4bee43114001c593b0d07092a34a439e1",
"20.10.16": "2f35d8d422b63a59279084c159c9092b63b6d974a7fcd868167aee4cc5f79f3b",
"20.10.17": "249244024b507a6599084522cc73e73993349d13264505b387593f2b2ed603e6",
}
return hashes
}
func findAssetsUrlHash(assetBuilder *assets.AssetBuilder, assetUrl string, assetHash string) (*url.URL, *hashing.Hash, error) {
u, err := url.Parse(assetUrl)
if err != nil {
return nil, nil, fmt.Errorf("unable to parse asset URL %q: %v", assetUrl, err)
}
h, err := hashing.FromString(assetHash)
if err != nil {
return nil, nil, fmt.Errorf("unable to parse asset hash %q: %v", assetHash, err)
}
u, err = assetBuilder.RemapFileAndSHAValue(u, assetHash)
if err != nil {
return nil, nil, fmt.Errorf("unable to remap asset: %v", err)
}
return u, h, nil
}

View File

@ -1,292 +0,0 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloudup
import (
"fmt"
"os"
"path"
"path/filepath"
"reflect"
"testing"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/util/pkg/architectures"
)
func TestDockerVersionUrlHash(t *testing.T) {
tests := []struct {
version string
arch architectures.Architecture
hash string
url string
err error
}{
{
arch: architectures.ArchitectureAmd64,
version: "19.03.13",
url: "https://download.docker.com/linux/static/stable/x86_64/docker-19.03.13.tgz",
hash: "ddb13aff1fcdcceb710bf71a210169b9c1abfd7420eeaf42cf7975f8fae2fcc8",
err: nil,
},
{
arch: architectures.ArchitectureArm64,
version: "19.03.13",
url: "https://download.docker.com/linux/static/stable/aarch64/docker-19.03.13.tgz",
hash: "bdf080af7d6f383ad80e415e9c1952a63c7038c149dc673b7598bfca4d3311ec",
err: nil,
},
{
arch: architectures.ArchitectureAmd64,
version: "18.06.3",
url: "https://download.docker.com/linux/static/stable/x86_64/docker-18.06.3-ce.tgz",
hash: "346f9394393ee8db5f8bd1e229ee9d90e5b36931bdd754308b2ae68884dd6822",
err: nil,
},
{
arch: architectures.ArchitectureArm64,
version: "18.06.3",
url: "https://download.docker.com/linux/static/stable/aarch64/docker-18.06.3-ce.tgz",
hash: "defb2ccc95c0825833216c8b9e0e15baaa51bcedb3efc1f393f5352d184dead4",
err: nil,
},
{
arch: architectures.ArchitectureAmd64,
version: "17.03.1",
url: "https://download.docker.com/linux/static/stable/x86_64/docker-17.03.1-ce.tgz",
hash: "3e070e7b34e99cf631f44d0ff5cf9a127c0b8af5c53dfc3e1fce4f9615fbf603",
err: nil,
},
{
arch: architectures.ArchitectureArm64,
version: "17.03.1",
url: "https://download.docker.com/linux/static/stable/aarch64/docker-17.09.0-ce.tgz",
hash: "2af5d112ab514d9b0b84d9e7360a5e7633e88b7168d1bbfc16c6532535cb0123",
err: nil,
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%s-%s", test.version, test.arch), func(t *testing.T) {
url, hash, err := findDockerVersionUrlHash(test.arch, test.version)
if !reflect.DeepEqual(err, test.err) {
t.Errorf("actual error %q differs from expected error %q", err, test.err)
return
}
if url != test.url {
t.Errorf("actual url %q differs from expected url %q", url, test.url)
return
}
if hash != test.hash {
t.Errorf("actual hash %q differs from expected hash %q", hash, test.hash)
return
}
})
}
}
func TestDockerVersionUrl(t *testing.T) {
tests := []struct {
version string
arch architectures.Architecture
url string
err error
}{
{
arch: "",
version: "19.03.13",
url: "",
err: fmt.Errorf("unknown arch: \"\""),
},
{
arch: "arm",
version: "19.03.13",
url: "",
err: fmt.Errorf("unknown arch: \"arm\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "",
url: "",
err: fmt.Errorf("unable to parse version string: \"\""),
},
{
arch: architectures.ArchitectureArm64,
version: "",
url: "",
err: fmt.Errorf("unable to parse version string: \"\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "18.06.3",
url: "https://download.docker.com/linux/static/stable/x86_64/docker-18.06.3-ce.tgz",
err: nil,
},
{
arch: architectures.ArchitectureArm64,
version: "18.06.3",
url: "https://download.docker.com/linux/static/stable/aarch64/docker-18.06.3-ce.tgz",
err: nil,
},
{
arch: architectures.ArchitectureAmd64,
version: "19.03.13",
url: "https://download.docker.com/linux/static/stable/x86_64/docker-19.03.13.tgz",
err: nil,
},
{
arch: architectures.ArchitectureArm64,
version: "19.03.13",
url: "https://download.docker.com/linux/static/stable/aarch64/docker-19.03.13.tgz",
err: nil,
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%s-%s", test.version, test.arch), func(t *testing.T) {
url, err := findDockerVersionUrl(test.arch, test.version)
if !reflect.DeepEqual(err, test.err) {
t.Errorf("actual error %q differs from expected error %q", err, test.err)
return
}
if url != test.url {
t.Errorf("actual url %q differs from expected url %q", url, test.url)
return
}
})
}
}
func TestDockerVersionHash(t *testing.T) {
tests := []struct {
version string
arch architectures.Architecture
hash string
err error
}{
{
arch: "",
version: "19.03.13",
hash: "",
err: fmt.Errorf("unknown arch: \"\""),
},
{
arch: "arm",
version: "19.03.13",
hash: "",
err: fmt.Errorf("unknown arch: \"arm\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "",
hash: "",
err: fmt.Errorf("unable to parse version string: \"\""),
},
{
arch: architectures.ArchitectureArm64,
version: "",
hash: "",
err: fmt.Errorf("unable to parse version string: \"\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "1.1.1",
hash: "",
err: fmt.Errorf("unsupported legacy Docker version: \"1.1.1\""),
},
{
arch: architectures.ArchitectureArm64,
version: "1.1.1",
hash: "",
err: fmt.Errorf("unsupported legacy Docker version: \"1.1.1\""),
},
{
arch: architectures.ArchitectureAmd64,
version: "19.03.13",
hash: "ddb13aff1fcdcceb710bf71a210169b9c1abfd7420eeaf42cf7975f8fae2fcc8",
err: nil,
},
{
arch: architectures.ArchitectureArm64,
version: "19.03.13",
hash: "bdf080af7d6f383ad80e415e9c1952a63c7038c149dc673b7598bfca4d3311ec",
err: nil,
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%s-%s", test.version, test.arch), func(t *testing.T) {
hash, err := findDockerVersionHash(test.arch, test.version)
if !reflect.DeepEqual(err, test.err) {
t.Errorf("actual error %q differs from expected error %q", err, test.err)
return
}
if hash != test.hash {
t.Errorf("actual hash %q differs from expected hash %q", hash, test.hash)
return
}
})
}
}
func TestDockerVersionsHashesAmd64(t *testing.T) {
if os.Getenv("VERIFY_HASHES") == "" {
t.Skip("VERIFY_HASHES not set, won't download & verify docker hashes")
}
for version, hash := range findAllDockerHashesAmd64() {
t.Run(version+"-amd64", func(t *testing.T) {
url, _ := findDockerVersionUrl(architectures.ArchitectureAmd64, version)
if err := verifyPackageHash(url, hash); err != nil {
t.Errorf("error verifying package %q: %v", url, err)
}
})
}
}
func TestDockerVersionsHashesArm64(t *testing.T) {
if os.Getenv("VERIFY_HASHES") == "" {
t.Skip("VERIFY_HASHES not set, won't download & verify docker hashes")
}
for version, hash := range findAllDockerHashesArm64() {
t.Run(version+"-arm64", func(t *testing.T) {
url, _ := findDockerVersionUrl(architectures.ArchitectureArm64, version)
if err := verifyPackageHash(url, hash); err != nil {
t.Errorf("error verifying package %q: %v", url, err)
}
})
}
}
func verifyPackageHash(u string, h string) error {
name := fmt.Sprintf("%s-%s", h, path.Base(u))
path := filepath.Join("/tmp", name)
actualHash, err := fi.DownloadURL(u, path, nil)
if err != nil {
return err
}
err = os.Remove(path)
if err != nil {
return err
}
if h != actualHash.Hex() {
return fmt.Errorf("actual hash %q differs from expected hash %q", actualHash.Hex(), h)
}
return nil
}

View File

@ -314,7 +314,6 @@ func (c *populateClusterSpec) run(ctx context.Context, clientset simple.Clientse
codeModels = append(codeModels, &components.EtcdOptionsBuilder{OptionsContext: optionsContext})
codeModels = append(codeModels, &etcdmanager.EtcdManagerOptionsBuilder{OptionsContext: optionsContext})
codeModels = append(codeModels, &components.KubeAPIServerOptionsBuilder{OptionsContext: optionsContext})
codeModels = append(codeModels, &components.DockerOptionsBuilder{OptionsContext: optionsContext})
codeModels = append(codeModels, &components.ContainerdOptionsBuilder{OptionsContext: optionsContext})
codeModels = append(codeModels, &components.NetworkingOptionsBuilder{Context: optionsContext})
codeModels = append(codeModels, &components.KubeDnsOptionsBuilder{Context: optionsContext})

View File

@ -119,49 +119,6 @@ func mockedPopulateClusterSpec(ctx context.Context, c *kopsapi.Cluster, cloud fi
return PopulateClusterSpec(ctx, clientset, c, nil, cloud, assetBuilder)
}
func TestPopulateCluster_Docker_Spec(t *testing.T) {
ctx := context.TODO()
cloud, c := buildMinimalCluster()
c.Spec.Docker = &kopsapi.DockerConfig{
MTU: fi.PtrTo(int32(5678)),
InsecureRegistry: fi.PtrTo("myregistry.com:1234"),
InsecureRegistries: []string{"myregistry.com:1234", "myregistry2.com:1234"},
RegistryMirrors: []string{"https://registry.example.com"},
LogOpt: []string{"env=FOO"},
}
err := PerformAssignments(c, vfs.Context, cloud)
if err != nil {
t.Fatalf("error from PerformAssignments: %v", err)
}
full, err := mockedPopulateClusterSpec(ctx, c, cloud)
if err != nil {
t.Fatalf("Unexpected error from PopulateCluster: %v", err)
}
if fi.ValueOf(full.Spec.Docker.MTU) != 5678 {
t.Fatalf("Unexpected Docker MTU: %v", full.Spec.Docker.MTU)
}
if fi.ValueOf(full.Spec.Docker.InsecureRegistry) != "myregistry.com:1234" {
t.Fatalf("Unexpected Docker InsecureRegistry: %v", full.Spec.Docker.InsecureRegistry)
}
if strings.Join(full.Spec.Docker.InsecureRegistries, "!") != "myregistry.com:1234!myregistry2.com:1234" {
t.Fatalf("Unexpected Docker InsecureRegistries: %v", full.Spec.Docker.InsecureRegistries)
}
if strings.Join(full.Spec.Docker.RegistryMirrors, "!") != "https://registry.example.com" {
t.Fatalf("Unexpected Docker RegistryMirrors: %v", full.Spec.Docker.RegistryMirrors)
}
if strings.Join(full.Spec.Docker.LogOpt, "!") != "env=FOO" {
t.Fatalf("Unexpected Docker LogOpt: %v", full.Spec.Docker.LogOpt)
}
}
func TestPopulateCluster_StorageDefault(t *testing.T) {
ctx := context.TODO()
cloud, c := buildMinimalCluster()

View File

@ -19,9 +19,12 @@ package cloudup
import (
"fmt"
"os"
"path"
"path/filepath"
"reflect"
"testing"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/util/pkg/architectures"
)
@ -264,3 +267,24 @@ func TestRuncVersionsHashesArm64(t *testing.T) {
})
}
}
func verifyPackageHash(u string, h string) error {
name := fmt.Sprintf("%s-%s", h, path.Base(u))
path := filepath.Join("/tmp", name)
actualHash, err := fi.DownloadURL(u, path, nil)
if err != nil {
return err
}
err = os.Remove(path)
if err != nil {
return err
}
if h != actualHash.Hex() {
return fmt.Errorf("actual hash %q differs from expected hash %q", actualHash.Hex(), h)
}
return nil
}

View File

@ -325,7 +325,6 @@ func (c *NodeUpCommand) Run(out io.Writer) error {
taskMap["LoadImage."+strconv.Itoa(i)] = &nodetasks.LoadImageTask{
Sources: image.Sources,
Hash: image.Hash,
Runtime: nodeupConfig.ContainerRuntime,
}
}
// Protokube load image task is in ProtokubeBuilder

View File

@ -27,8 +27,7 @@ import (
// PullImageTask is responsible for pulling a docker image
type PullImageTask struct {
Name string
Runtime string
Name string
}
var (
@ -45,9 +44,6 @@ func (t *PullImageTask) GetDependencies(tasks map[string]fi.NodeupTask) []fi.Nod
if svc, ok := v.(*Service); ok && svc.Name == containerdService {
deps = append(deps, v)
}
if svc, ok := v.(*Service); ok && svc.Name == dockerService {
deps = append(deps, v)
}
}
return deps
}
@ -60,21 +56,8 @@ func (t *PullImageTask) GetName() *string {
}
func (e *PullImageTask) Run(c *fi.NodeupContext) error {
runtime := e.Runtime
if runtime != "docker" && runtime != "containerd" {
return fmt.Errorf("no runtime specified")
}
// Pull the container image
var args []string
switch runtime {
case "docker":
args = []string{"docker", "pull", e.Name}
case "containerd":
args = []string{"ctr", "--namespace", "k8s.io", "images", "pull", e.Name}
default:
return fmt.Errorf("unknown container runtime: %s", runtime)
}
args := []string{"ctr", "--namespace", "k8s.io", "images", "pull", e.Name}
human := strings.Join(args, " ")
klog.Infof("running command %s", human)