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

Use preloaded tarball for VMs as well #6898

Merged
merged 13 commits into from
Mar 6, 2020
5 changes: 5 additions & 0 deletions pkg/minikube/cruntime/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,8 @@ func (r *Containerd) ContainerLogCmd(id string, len int, follow bool) string {
func (r *Containerd) SystemLogCmd(len int) string {
return fmt.Sprintf("sudo journalctl -u containerd -n %d", len)
}

// Preload preloads the container runtime with k8s images
func (r *Containerd) Preload(k8sVersion string) error {
return nil
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
}
5 changes: 5 additions & 0 deletions pkg/minikube/cruntime/crio.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,8 @@ func (r *CRIO) ContainerLogCmd(id string, len int, follow bool) string {
func (r *CRIO) SystemLogCmd(len int) string {
return fmt.Sprintf("sudo journalctl -u crio -n %d", len)
}

// Preload preloads the container runtime with k8s images
func (r *CRIO) Preload(k8sVersion string) error {
return nil
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
}
5 changes: 5 additions & 0 deletions pkg/minikube/cruntime/cruntime.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/golang/glog"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/command"
"k8s.io/minikube/pkg/minikube/out"
)
Expand All @@ -46,6 +47,8 @@ func (cs ContainerState) String() string {
// CommandRunner is the subset of command.Runner this package consumes
type CommandRunner interface {
RunCmd(cmd *exec.Cmd) (*command.RunResult, error)
// Copy is a convenience method that runs a command to copy a file
Copy(assets.CopyableFile) error
}

// Manager is a common interface for container runtimes
Expand Down Expand Up @@ -94,6 +97,8 @@ type Manager interface {
ContainerLogCmd(string, int, bool) string
// SystemLogCmd returns the command to return the system logs
SystemLogCmd(int) string
// Preload preloads the container runtime with k8s images
Preload(string) error
}

// Config is runtime configuration
Expand Down
44 changes: 44 additions & 0 deletions pkg/minikube/cruntime/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ package cruntime
import (
"fmt"
"os/exec"
"path/filepath"
"strings"
"time"

"github.com/golang/glog"
"github.com/pkg/errors"
"k8s.io/minikube/pkg/minikube/assets"
"k8s.io/minikube/pkg/minikube/out"
"k8s.io/minikube/pkg/minikube/download"
)

// KubernetesContainerPrefix is the prefix of each kubernetes container
Expand Down Expand Up @@ -93,6 +97,15 @@ func (r *Docker) Enable(disOthers bool) error {
return nil
}

// Restart restarts Docker on a host
func (r *Docker) Restart() error {
c := exec.Command("sudo", "systemctl", "restart", "docker")
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "restarting docker.")
}
return nil
}

// Disable idempotently disables Docker on a host
func (r *Docker) Disable() error {
c := exec.Command("sudo", "systemctl", "stop", "docker", "docker.socket")
Expand Down Expand Up @@ -252,3 +265,34 @@ func (r *Docker) ContainerLogCmd(id string, len int, follow bool) string {
func (r *Docker) SystemLogCmd(len int) string {
return fmt.Sprintf("sudo journalctl -u docker -n %d", len)
}

// Preload preloads docker with k8s images:
// 1. Copy over the preloaded tarball into the VM
// 2. Extract the preloaded tarball to the correct directory
// 3. Remove the tarball within the VM
func (r *Docker) Preload(k8sVersion string) error {
tarballPath := download.TarballPath(k8sVersion)
dest := "/tmp/preloaded.tar"
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved

// Copy over tarball into host
fa, err := assets.NewFileAsset(tarballPath, filepath.Dir(dest), filepath.Base(dest), "0644")
if err != nil {
return errors.Wrap(err, "getting file asset")
}
t := time.Now()
if err := r.Runner.Copy(fa); err != nil {
return errors.Wrap(err, "copying file")
}
glog.Infof("Took %f seconds to copy over tarball", time.Since(t).Seconds())

// extract the tarball to /var in the VM
if rr, err := r.Runner.RunCmd(exec.Command("sudo", "tar", "-I", "lz4", "-C", "/var", "-xvf", dest)); err != nil {
return errors.Wrapf(err, "extracting tarball: %s", rr.Output())
}

// remove the tarball in the VM
if rr, err := r.Runner.RunCmd(exec.Command("sudo", "rm", dest)); err != nil {
priyawadhwa marked this conversation as resolved.
Show resolved Hide resolved
return errors.Wrapf(err, "removing tarball: %s", rr.Output())
}
return r.Restart()
}
21 changes: 10 additions & 11 deletions pkg/minikube/node/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,15 @@ import (
)

// beginCacheKubernetesImages caches images required for kubernetes version in the background
func beginCacheKubernetesImages(g *errgroup.Group, imageRepository string, k8sVersion string) {
func beginCacheKubernetesImages(g *errgroup.Group, imageRepository string, k8sVersion, cRuntime string) {
if download.PreloadExists(k8sVersion, cRuntime) {
g.Go(func() error {
glog.Info("Caching tarball of preloaded images")
return download.Preload(k8sVersion, cRuntime)
})
return
}

if !viper.GetBool("cache-images") {
return
}
Expand Down Expand Up @@ -83,21 +91,12 @@ func doCacheBinaries(k8sVersion string) error {
}

// beginDownloadKicArtifacts downloads the kic image + preload tarball, returns true if preload is available
func beginDownloadKicArtifacts(g *errgroup.Group, k8sVersion, cRuntime string) bool {
func beginDownloadKicArtifacts(g *errgroup.Group) {
glog.Info("Beginning downloading kic artifacts")
g.Go(func() error {
glog.Infof("Downloading %s to local daemon", kic.BaseImage)
return image.WriteImageToDaemon(kic.BaseImage)
})

if download.PreloadExists(k8sVersion, cRuntime) {
g.Go(func() error {
glog.Info("Caching tarball of preloaded images")
return download.Preload(k8sVersion, cRuntime)
})
return true
}
return false
}

func waitDownloadKicArtifacts(g *errgroup.Group) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/minikube/node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ func configureRuntimes(runner cruntime.CommandRunner, drvName string, k8s config
if driver.BareMetal(drvName) {
disableOthers = false
}
if err := cr.Preload(k8s.KubernetesVersion); err != nil {
glog.Infof("Failed to preload container runtime %s: %v", cr.Name(), err)
}
err = cr.Enable(disableOthers)
if err != nil {
exit.WithError("Failed to enable container runtime", err)
Expand Down
14 changes: 4 additions & 10 deletions pkg/minikube/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,14 @@ func Start(mc config.ClusterConfig, n config.Node, primary bool, existingAddons
k8sVersion := mc.KubernetesConfig.KubernetesVersion
driverName := mc.Driver

// See if we can create a volume of preloaded images
// If not, pull images in the background while the VM boots.
// If using kic, make sure we download the kic base image
var kicGroup errgroup.Group
needKubernetesImages := true
if driver.IsKIC(driverName) {
// If we can download a preload tarball, it isn't necessary to pull Kubernetes images
if beginDownloadKicArtifacts(&kicGroup, k8sVersion, mc.KubernetesConfig.ContainerRuntime) {
needKubernetesImages = false
}
beginDownloadKicArtifacts(&kicGroup)
}

var cacheGroup errgroup.Group
if needKubernetesImages {
beginCacheKubernetesImages(&cacheGroup, mc.KubernetesConfig.ImageRepository, k8sVersion)
}
beginCacheKubernetesImages(&cacheGroup, mc.KubernetesConfig.ImageRepository, k8sVersion, mc.KubernetesConfig.ContainerRuntime)

// Abstraction leakage alert: startHost requires the config to be saved, to satistfy pkg/provision/buildroot.
// Hence, saveConfig must be called before startHost, and again afterwards when we know the IP.
Expand All @@ -65,6 +58,7 @@ func Start(mc config.ClusterConfig, n config.Node, primary bool, existingAddons

mRunner, preExists, machineAPI, host := startMachine(&mc, &n)
defer machineAPI.Close()

// configure the runtime (docker, containerd, crio)
cr := configureRuntimes(mRunner, driverName, mc.KubernetesConfig)
showVersionInfo(k8sVersion, cr)
Expand Down