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

download crictl at preload and runtime #18362

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
19 changes: 19 additions & 0 deletions hack/preload-images/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ limitations under the License.
package main

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"time"

"github.com/pkg/errors"
"k8s.io/klog/v2"
"k8s.io/minikube/hack/update"
"k8s.io/minikube/pkg/drivers/kic"
"k8s.io/minikube/pkg/drivers/kic/oci"
"k8s.io/minikube/pkg/minikube/bootstrapper/bsutil"
Expand Down Expand Up @@ -127,6 +130,22 @@ func generateTarball(kubernetesVersion, containerRuntime, tarballFilename string
if err := bsutil.TransferBinaries(kcfg, runner, sm, ""); err != nil {
return errors.Wrap(err, "transferring k8s binaries")
}
// download crictl if needed
// first we need to check the version of crictl we are going to download
crictlVersion := ""
if stable, _, _, err := update.GHReleasesWithCondition(context.TODO(), "kubernetes-sigs", "cri-tools", func(crictlVersion string) bool {
ComradeProgrammer marked this conversation as resolved.
Show resolved Hide resolved
k8sVer, _ := util.ParseKubernetesVersion(kubernetesVersion)
crictlVer, _ := util.ParseKubernetesVersion(crictlVersion)
return k8sVer.Major == crictlVer.Major && k8sVer.Minor == crictlVer.Minor
}); err != nil {
klog.Error("failed to get the newest version tag pf crictl from github")
} else {
crictlVersion = stable.Tag
}

ComradeProgrammer marked this conversation as resolved.
Show resolved Hide resolved
if err := bsutil.TransferCrictl(kcfg, runner, crictlVersion); err != nil {
return errors.Wrap(err, "transferring crictl")
}
// Create image tarball
if err := createImageTarball(tarballFilename, containerRuntime); err != nil {
return errors.Wrap(err, "create tarball")
Expand Down
12 changes: 12 additions & 0 deletions hack/update/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ type Release struct {
// GHReleases returns greatest current stable release and greatest latest rc or beta pre-release from GitHub owner/repo repository, and any error occurred.
// If latest pre-release version is lower than the current stable release, then it will return current stable release for both.
func GHReleases(ctx context.Context, owner, repo string) (stable, latest, edge Release, err error) {
return GHReleasesWithCondition(ctx, owner, repo, nil)
}

// GHReleasesWithCondition returns greatest current stable release and greatest
// latest rc or beta pre-release from GitHub owner/repo repository whose version
// number satisfy the condition given in the parameter, and any error occurred.
// If latest pre-release version is lower than the current stable release, then
// it will return current stable release for both.
func GHReleasesWithCondition(ctx context.Context, owner, repo string, condition func(string) bool) (stable, latest, edge Release, err error) {
ghc := github.NewClient(nil)

// walk through the paginated list of up to ghSearchLimit newest releases
Expand All @@ -61,6 +70,9 @@ func GHReleases(ctx context.Context, owner, repo string) (stable, latest, edge R
continue
}
}
if condition != nil && !condition(ver) {
continue
}
// check if ver version is release (ie, 'v1.19.2') or pre-release (ie, 'v1.19.3-rc.0' or 'v1.19.0-beta.2')
prerls := semver.Prerelease(ver)
if prerls == "" {
Expand Down
17 changes: 17 additions & 0 deletions pkg/minikube/bootstrapper/bsutil/binaries.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ import (
"k8s.io/minikube/pkg/minikube/vmpath"
)

// TransferCrictl transfers the crictl binary to the machine to replace /usr/bin/crictl
func TransferCrictl(cfg config.KubernetesConfig, c command.Runner, crictlVersion string) error {
src, err := download.CrictlBinary(cfg.KubernetesVersion, crictlVersion)
if err != nil {
if strings.Contains(err.Error(), "response code: 404") {
klog.Warning("Failed to download crictl with matching version. Using whatever version is already on the image")
ComradeProgrammer marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
return errors.Wrapf(err, "downloading crictl")
}
dst := "/usr/bin/crictl"
if err := machine.CopyBinary(c, src, dst); err != nil {
return errors.Wrapf(err, "copybinary %s -> %s", src, dst)
}
return nil
}

// TransferBinaries transfers all required Kubernetes binaries
func TransferBinaries(cfg config.KubernetesConfig, c command.Runner, sm sysinit.Manager, binariesURL string) error {
ok, err := binariesExist(cfg, c)
Expand Down
25 changes: 23 additions & 2 deletions pkg/minikube/bootstrapper/kubeadm/kubeadm.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/docker/machine/libmachine"
"github.com/docker/machine/libmachine/state"
"github.com/pkg/errors"
"github.com/spf13/viper"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
Expand Down Expand Up @@ -945,6 +946,27 @@ func (k *Bootstrapper) UpdateNode(cfg config.ClusterConfig, n config.Node, r cru

klog.Infof("kubelet %s config:\n%+v", kubeletCfg, cfg.KubernetesConfig)

sm := sysinit.New(k.c)

if err := bsutil.TransferBinaries(cfg.KubernetesConfig, k.c, sm, cfg.BinaryMirror); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this is added ? I thought this was downloading critctl, why this was needed to be added here?

return errors.Wrap(err, "downloading binaries")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldnt this be tranferring crictlc? make it more specific, so when the error bubles up we find it easier

}
// download crictl if needed.
// since Kubernetes v1.29 we need to have matching crictl and Kubernetes version.
version, err := util.ParseKubernetesVersion(cfg.KubernetesConfig.KubernetesVersion)
if err != nil {
return errors.Wrap(err, "parsing Kubernetes version")
}
crictlVersion, err := cruntime.CrictlVersion(k.c)
// when preload is enabled
// if we failed to get the crictl version or the version does not match the K8s version
// then we download it
if !viper.GetBool("preload") && (err != nil || crictlVersion.Major != version.Major || crictlVersion.Minor != version.Minor) {
if err := bsutil.TransferCrictl(cfg.KubernetesConfig, k.c, ""); err != nil {
return errors.Wrap(err, "transferring crictl")
}
}

files := []assets.CopyableFile{
assets.NewMemoryAssetTarget(kubeletCfg, bsutil.KubeletSystemdConfFile, "0644"),
assets.NewMemoryAssetTarget(kubeletService, bsutil.KubeletServiceFile, "0644"),
Expand Down Expand Up @@ -980,8 +1002,7 @@ func (k *Bootstrapper) UpdateNode(cfg config.ClusterConfig, n config.Node, r cru
}
}

sm := sysinit.New(k.c)

sm = sysinit.New(k.c)
if err := bsutil.TransferBinaries(cfg.KubernetesConfig, k.c, sm, cfg.BinaryMirror); err != nil {
return errors.Wrap(err, "downloading binaries")
}
Expand Down
20 changes: 20 additions & 0 deletions pkg/minikube/cruntime/cri.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ import (
"os"
"os/exec"
"path"
"regexp"
"strings"

"github.com/blang/semver/v4"
"github.com/pkg/errors"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/util"
)

// container maps to 'runc list -f json'
Expand All @@ -49,6 +51,24 @@ type crictlImages struct {
} `json:"images"`
}

func CrictlVersion(c CommandRunner) (*semver.Version, error) {
rr, err := c.RunCmd(exec.Command("sudo", "crictl", "--version"))
if err != nil {
return nil, err
}
stdout := rr.Stdout.String()
reg := regexp.MustCompile(`crictl\s*version\s*(v\d+\.\d+.\d+)`)
subMatches := reg.FindStringSubmatch(stdout)
if len(subMatches) < 2 {
return nil, fmt.Errorf("failed to find the crictl version")
}
version, err := util.ParseKubernetesVersion(subMatches[1])
if err != nil {
return nil, err
}
return &version, nil
}

// crictlList returns the output of 'crictl ps' in an efficient manner
func crictlList(cr CommandRunner, root string, o ListContainersOptions) (*command.RunResult, error) {
klog.Infof("listing CRI containers in root %s: %+v", root, o)
Expand Down
30 changes: 30 additions & 0 deletions pkg/minikube/download/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/pkg/errors"
"k8s.io/klog/v2"
"k8s.io/minikube/pkg/minikube/localpath"
"k8s.io/minikube/pkg/util"
)

// DefaultKubeBinariesURL returns a URL to kube binaries
Expand Down Expand Up @@ -86,3 +87,32 @@ func Binary(binary, version, osName, archName, binaryURL string) (string, error)
}
return targetFilepath, nil
}

// CrictlBinary download the crictl tar archive to the cache folder and untar it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this for only when --preload is false? if yes please add it to the comment

func CrictlBinary(k8sversion string, crictlVersion string) (string, error) {
// first we check whether crictl exists
targetDir := localpath.MakeMiniPath("cache", "linux", runtime.GOARCH, k8sversion)
ComradeProgrammer marked this conversation as resolved.
Show resolved Hide resolved
targetPath := path.Join(targetDir, "crictl")
if _, err := checkCache(targetPath); err == nil {
klog.Infof("crictl found in cache: %s", targetPath)
return targetPath, nil
}

// if we don't know the exact patch number of crictl then use 0.
// This definitely exists
if crictlVersion == "" {
v, err := util.ParseKubernetesVersion(k8sversion)
if err != nil {
return "", err
}
crictlVersion = fmt.Sprintf("v%d.%d.0", v.Major, v.Minor)
}
url := fmt.Sprintf(
"https://github.com/kubernetes-sigs/cri-tools/releases/download/%s/crictl-%s-linux-%s.tar.gz",
crictlVersion, crictlVersion, runtime.GOARCH)
if err := download(url, targetPath); err != nil {
ComradeProgrammer marked this conversation as resolved.
Show resolved Hide resolved
return "", errors.Wrapf(err, "download failed: %s", url)
}

return targetPath, nil
}
Loading