Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for using x86 binary on arm64 machine #19205

Merged
merged 5 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions pkg/minikube/detect/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,6 @@ func IsAmd64M1Emulation() bool {
return runtime.GOARCH == "amd64" && strings.HasPrefix(cpuid.CPU.BrandName, "VirtualApple")
}

// EffectiveArch return architecture to use in minikube VM/container
// may differ from host arch
func EffectiveArch() string {
if IsAmd64M1Emulation() {
return "arm64"
}
return runtime.GOARCH
}

// MinikubeInstalledViaSnap returns true if the minikube binary path includes "snap".
func MinikubeInstalledViaSnap() bool {
ex, err := os.Executable()
Expand Down
4 changes: 1 addition & 3 deletions pkg/minikube/download/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import (
"path"
"runtime"

"k8s.io/minikube/pkg/minikube/detect"

"github.com/blang/semver/v4"
"github.com/pkg/errors"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -81,7 +79,7 @@ func Binary(binary, version, osName, archName, binaryURL string) (string, error)
return "", errors.Wrapf(err, "download failed: %s", url)
}

if osName == runtime.GOOS && archName == detect.EffectiveArch() {
if osName == runtime.GOOS && archName == runtime.GOARCH {
if err = os.Chmod(targetFilepath, 0755); err != nil {
return "", errors.Wrapf(err, "chmod +x %s", targetFilepath)
}
Expand Down
46 changes: 38 additions & 8 deletions pkg/minikube/download/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,43 @@ func ImageExistsInDaemon(img string) bool {
// Check if image exists locally
klog.Infof("Checking for %s in local docker daemon", img)
cmd := exec.Command("docker", "images", "--format", "{{.Repository}}:{{.Tag}}@{{.Digest}}")
if output, err := cmd.Output(); err == nil {
if strings.Contains(string(output), image.TrimDockerIO(img)) {
klog.Infof("Found %s in local docker daemon, skipping pull", img)
return true
}
output, err := cmd.Output()
if err != nil {
klog.Warningf("failed to list docker images: %v", err)
return false
}
// Else, pull it
return false
if !strings.Contains(string(output), image.TrimDockerIO(img)) {
spowelljr marked this conversation as resolved.
Show resolved Hide resolved
return false
}
correctArch, err := isImageCorrectArch(img)
if err != nil {
klog.Warning(err)
return false
}
if !correctArch {
klog.Warningf("image %s is of wrong architecture", img)
return false
}
klog.Infof("Found %s in local docker daemon, skipping pull", img)
return true
}

// isImageCorrectArch is needed to resolve
spowelljr marked this conversation as resolved.
Show resolved Hide resolved
// https://github.com/kubernetes/minikube/pull/19205
func isImageCorrectArch(img string) (bool, error) {
ref, err := name.ParseReference(img)
if err != nil {
return false, fmt.Errorf("failed to parse reference: %v", err)
}
dImg, err := daemon.Image(ref)
if err != nil {
return false, fmt.Errorf("failed to get image from daemon: %v", err)
}
cfg, err := dImg.ConfigFile()
if err != nil {
return false, fmt.Errorf("failed to get config for %s: %v", img, err)
}
return cfg.Architecture == runtime.GOOS, nil
}

// ImageToCache downloads img (if not present in cache) and writes it to the local cache directory
Expand Down Expand Up @@ -245,7 +274,8 @@ func CacheToDaemon(img string) (string, error) {
return "", err
}

cmd := exec.Command("docker", "pull", "--quiet", img)
platform := fmt.Sprintf("linux/%s", runtime.GOARCH)
cmd := exec.Command("docker", "pull", "--platform", platform, "--quiet", img)
if output, err := cmd.CombinedOutput(); err != nil {
klog.Warningf("failed to pull image digest (expected if offline): %s: %v", output, err)
img = image.Tag(img)
Expand Down
5 changes: 2 additions & 3 deletions pkg/minikube/download/preload.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import (
"os"
"path"
"path/filepath"
"runtime"
"strings"

"cloud.google.com/go/storage"
"google.golang.org/api/option"
"k8s.io/minikube/pkg/minikube/detect"

"github.com/pkg/errors"
"github.com/spf13/viper"
Expand Down Expand Up @@ -64,8 +64,7 @@ func TarballName(k8sVersion, containerRuntime string) string {
} else {
storageDriver = "overlay2"
}
arch := detect.EffectiveArch()
return fmt.Sprintf("preloaded-images-k8s-%s-%s-%s-%s-%s.tar.lz4", PreloadVersion, k8sVersion, containerRuntime, storageDriver, arch)
return fmt.Sprintf("preloaded-images-k8s-%s-%s-%s-%s-%s.tar.lz4", PreloadVersion, k8sVersion, containerRuntime, storageDriver, runtime.GOARCH)
}

// returns the name of the checksum file
Expand Down
4 changes: 2 additions & 2 deletions pkg/minikube/machine/cache_binaries.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ package machine

import (
"path"
"runtime"

"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/bootstrapper"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/detect"
"k8s.io/minikube/pkg/minikube/download"
)

Expand Down Expand Up @@ -53,7 +53,7 @@ func CacheBinariesForBootstrapper(version string, excludeBinaries []string, bina
}
bin := bin // https://go.dev/doc/faq#closures_and_goroutines
g.Go(func() error {
if _, err := download.Binary(bin, version, "linux", detect.EffectiveArch(), binariesURL); err != nil {
if _, err := download.Binary(bin, version, "linux", runtime.GOARCH, binariesURL); err != nil {
return errors.Wrapf(err, "caching binary %s", bin)
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/minikube/node/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func CacheKubectlBinary(k8sVersion, binaryURL string) (string, error) {
binary = "kubectl.exe"
}

return download.Binary(binary, k8sVersion, runtime.GOOS, detect.EffectiveArch(), binaryURL)
return download.Binary(binary, k8sVersion, runtime.GOOS, runtime.GOARCH, binaryURL)
}

// doCacheBinaries caches Kubernetes binaries in the foreground
Expand Down
12 changes: 12 additions & 0 deletions pkg/minikube/registry/drvs/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"k8s.io/minikube/pkg/drivers/kic"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/config"
"k8s.io/minikube/pkg/minikube/detect"
"k8s.io/minikube/pkg/minikube/driver"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/minikube/registry"
Expand Down Expand Up @@ -151,6 +152,17 @@ var dockerVersionOrState = func() (string, registry.State) {
return "", registry.State{Error: err, Installed: false, Healthy: false, Fix: "Install Docker", Doc: docURL}
}

if detect.IsAmd64M1Emulation() {
return "", registry.State{
Reason: "PROVIDER_DOCKER_INCORRECT_ARCH",
Installed: true,
Running: true,
Error: errors.New("Cannot use amd64 minikube binary to start minikube cluster with Docker driver on arm64 machine"),
Fix: "Download and use arm64 version of the minikube binary",
Doc: "https://minikube.sigs.k8s.io/docs/start/",
}
}

ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
defer cancel()

Expand Down
Loading