Skip to content

Commit

Permalink
Merge pull request #19205 from spowelljr/checkKicbaseArch
Browse files Browse the repository at this point in the history
Improvements for using x86 binary on arm64 machine
  • Loading branch information
spowelljr authored Jul 16, 2024
2 parents 444cdab + 23a8c35 commit 4c7fcd0
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 26 deletions.
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
47 changes: 39 additions & 8 deletions pkg/minikube/download/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,44 @@ 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)) {
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 returns true if the image arch is the same as the binary
// arch. This is needed to resolve
// 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 +275,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

0 comments on commit 4c7fcd0

Please sign in to comment.