diff --git a/hack/images/kicbase.Dockerfile b/hack/images/kicbase.Dockerfile index 5afbe6e146ad..97a29b73710b 100644 --- a/hack/images/kicbase.Dockerfile +++ b/hack/images/kicbase.Dockerfile @@ -2,7 +2,7 @@ ARG COMMIT_SHA # using base image created by kind https://github.com/kubernetes-sigs/kind/blob/master/images/base/Dockerfile # which is an ubuntu 19.10 with an entry-point that helps running systemd # could be changed to any debian that can run systemd -FROM kindest/base:v20200122-2dfe64b2 as base +FROM kindest/base:v20200317-92225082 as base USER root # specify version of everything explicitly using 'apt-cache policy' RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -19,9 +19,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN sh -c "echo 'deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_19.10/ /' > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list" && \ curl -LO https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/xUbuntu_19.10/Release.key && \ apt-key add - < Release.key && apt-get update && \ - apt-get install -y --no-install-recommends cri-o-1.17=1.17.0-3 + apt-get install -y --no-install-recommends cri-o-1.17=1.17.2~1 # install podman -RUN apt-get install -y --no-install-recommends podman=1.8.2~1 +RUN apt-get install -y --no-install-recommends podman=1.8.2~144 # disable non-docker runtimes by default RUN systemctl disable containerd && systemctl disable crio && rm /etc/crictl.yaml # enable docker which is default diff --git a/pkg/drivers/kic/kic.go b/pkg/drivers/kic/kic.go index 509267f9980d..c0b161b8c111 100644 --- a/pkg/drivers/kic/kic.go +++ b/pkg/drivers/kic/kic.go @@ -361,13 +361,20 @@ func (d *Driver) Stop() error { } if len(containers) > 0 { if err := runtime.StopContainers(containers); err != nil { - glog.Errorf("unable to stop containers : %v", err) + glog.Infof("unable to stop containers : %v", err) + } + if err := runtime.KillContainers(containers); err != nil { + glog.Errorf("unable to kill containers : %v", err) } } glog.Infof("successfully stopped kubernetes!") } + if err := killAPIServerProc(d.exec); err != nil { + glog.Warningf("couldn't stop kube-apiserver proc: %v", err) + } + cmd := exec.Command(d.NodeConfig.OCIBinary, "stop", d.MachineName) if err := cmd.Run(); err != nil { return errors.Wrapf(err, "stopping %s", d.MachineName) @@ -379,3 +386,20 @@ func (d *Driver) Stop() error { func (d *Driver) RunSSHCommandFromDriver() error { return fmt.Errorf("driver does not support RunSSHCommandFromDriver commands") } + +// killAPIServerProc will kill an api server proc if it exists +// to ensure this never happens https://github.com/kubernetes/minikube/issues/7521 +func killAPIServerProc(runner command.Runner) error { + // first check if it exists + rr, err := runner.RunCmd(exec.Command("pgrep", "kube-apiserver")) + if err == nil { // this means we might have a running kube-apiserver + pid, err := strconv.Atoi(rr.Stdout.String()) + if err == nil { // this means we have a valid pid + glog.Warningf("Found a kube-apiserver running with pid %d, will try to kill the proc", pid) + if _, err = runner.RunCmd(exec.Command("pkill", "-9", string(pid))); err != nil { + return errors.Wrap(err, "kill") + } + } + } + return nil +} diff --git a/pkg/drivers/kic/types.go b/pkg/drivers/kic/types.go index d31aac0b850a..2b01019b2ed8 100644 --- a/pkg/drivers/kic/types.go +++ b/pkg/drivers/kic/types.go @@ -30,13 +30,12 @@ const ( DefaultPodCIDR = "10.244.0.0/16" // Version is the current version of kic - Version = "v0.0.8" + Version = "v0.0.9" // SHA of the kic base image - baseImageSHA = "2f3380ebf1bb0c75b0b47160fd4e61b7b8fef0f1f32f9def108d3eada50a7a81" - + baseImageSHA = "82a826cc03c3e59ead5969b8020ca138de98f366c1907293df91fc57205dbb53" // OverlayImage is the cni plugin used for overlay image, created by kind. // CNI plugin image used for kic drivers created by kind. - OverlayImage = "kindest/kindnetd:0.5.3" + OverlayImage = "kindest/kindnetd:0.5.4" ) var ( diff --git a/pkg/minikube/assets/vm_assets.go b/pkg/minikube/assets/vm_assets.go index 3751a85e080c..3d4541d7542c 100644 --- a/pkg/minikube/assets/vm_assets.go +++ b/pkg/minikube/assets/vm_assets.go @@ -93,15 +93,21 @@ func NewMemoryAssetTarget(d []byte, targetPath, permissions string) *MemoryAsset // NewFileAsset creates a new FileAsset func NewFileAsset(src, targetDir, targetName, permissions string) (*FileAsset, error) { glog.V(4).Infof("NewFileAsset: %s -> %s", src, path.Join(targetDir, targetName)) + f, err := os.Open(src) if err != nil { - return nil, errors.Wrapf(err, "Error opening file asset: %s", src) + return nil, errors.Wrap(err, "open") } + info, err := os.Stat(src) if err != nil { - return nil, errors.Wrapf(err, "Error getting info for %s", src) + return nil, errors.Wrapf(err, "stat") } - r := io.NewSectionReader(f, 0, info.Size()) + + if info.Size() == 0 { + glog.Warningf("NewFileAsset: %s is an empty file!", src) + } + return &FileAsset{ BaseAsset: BaseAsset{ SourcePath: src, @@ -109,7 +115,7 @@ func NewFileAsset(src, targetDir, targetName, permissions string) (*FileAsset, e TargetName: targetName, Permissions: permissions, }, - reader: r, + reader: io.NewSectionReader(f, 0, info.Size()), }, nil } @@ -117,6 +123,7 @@ func NewFileAsset(src, targetDir, targetName, permissions string) (*FileAsset, e func (f *FileAsset) GetLength() (flen int) { fi, err := os.Stat(f.SourcePath) if err != nil { + glog.Errorf("stat(%q) failed: %v", f.SourcePath, err) return 0 } return int(fi.Size()) @@ -126,6 +133,7 @@ func (f *FileAsset) GetLength() (flen int) { func (f *FileAsset) GetModTime() (time.Time, error) { fi, err := os.Stat(f.SourcePath) if err != nil { + glog.Errorf("stat(%q) failed: %v", f.SourcePath, err) return time.Time{}, err } return fi.ModTime(), nil diff --git a/pkg/minikube/bootstrapper/bsutil/binaries.go b/pkg/minikube/bootstrapper/bsutil/binaries.go index 341a5b295b7e..3eecdf905c66 100644 --- a/pkg/minikube/bootstrapper/bsutil/binaries.go +++ b/pkg/minikube/bootstrapper/bsutil/binaries.go @@ -60,8 +60,8 @@ func TransferBinaries(cfg config.KubernetesConfig, c command.Runner, sm sysinit. return errors.Wrapf(err, "downloading %s", name) } - if name == "kubelet" { - if err := sm.ForceStop("kubelet"); err != nil { + if name == "kubelet" && sm.Active(name) { + if err := sm.ForceStop(name); err != nil { glog.Errorf("unable to stop kubelet: %v", err) } } diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index b97707a5cf98..735032af120c 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -212,15 +212,18 @@ func (k *Bootstrapper) init(cfg config.ClusterConfig) error { return errors.Wrap(err, "run") } - // this is required for containerd and cri-o runtime. till we close https://github.com/kubernetes/minikube/issues/7428 - if driver.IsKIC(cfg.Driver) && cfg.KubernetesConfig.ContainerRuntime != "docker" { - if err := k.applyKicOverlay(cfg); err != nil { - return errors.Wrap(err, "apply kic overlay") - } - } - var wg sync.WaitGroup - wg.Add(3) + wg.Add(4) + + go func() { + // the overlay is required for containerd and cri-o runtime: see #7428 + if driver.IsKIC(cfg.Driver) && cfg.KubernetesConfig.ContainerRuntime != "docker" { + if err := k.applyKicOverlay(cfg); err != nil { + glog.Errorf("failed to apply kic overlay: %v", err) + } + } + wg.Done() + }() go func() { if err := k.applyNodeLabels(cfg); err != nil { @@ -242,6 +245,7 @@ func (k *Bootstrapper) init(cfg config.ClusterConfig) error { } wg.Done() }() + wg.Wait() return nil } @@ -762,20 +766,30 @@ func startKubeletIfRequired(runner command.Runner, sm sysinit.Manager) error { // applyKicOverlay applies the CNI plugin needed to make kic work func (k *Bootstrapper) applyKicOverlay(cfg config.ClusterConfig) error { - // Allow no more than 5 seconds for apply kic overlay - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() + cmd := exec.CommandContext(ctx, "sudo", path.Join(vmpath.GuestPersistentDir, "binaries", cfg.KubernetesConfig.KubernetesVersion, "kubectl"), "create", fmt.Sprintf("--kubeconfig=%s", path.Join(vmpath.GuestPersistentDir, "kubeconfig")), "-f", "-") + b := bytes.Buffer{} if err := kicCNIConfig.Execute(&b, struct{ ImageName string }{ImageName: kic.OverlayImage}); err != nil { return err } + cmd.Stdin = bytes.NewReader(b.Bytes()) if rr, err := k.c.RunCmd(cmd); err != nil { return errors.Wrapf(err, "cmd: %s output: %s", rr.Command(), rr.Output()) } + + // Inform cri-o that the CNI has changed + if cfg.KubernetesConfig.ContainerRuntime == "crio" { + if err := sysinit.New(k.c).Restart("crio"); err != nil { + return errors.Wrap(err, "restart crio") + } + } + return nil } diff --git a/pkg/minikube/cruntime/cri.go b/pkg/minikube/cruntime/cri.go index 2cf50c78e299..6f05551235c4 100644 --- a/pkg/minikube/cruntime/cri.go +++ b/pkg/minikube/cruntime/cri.go @@ -195,7 +195,7 @@ func stopCRIContainers(cr CommandRunner, ids []string) error { glog.Infof("Stopping containers: %s", ids) crictl := getCrictlPath(cr) - args := append([]string{crictl, "rm"}, ids...) + args := append([]string{crictl, "stop"}, ids...) c := exec.Command("sudo", args...) if _, err := cr.RunCmd(c); err != nil { return errors.Wrap(err, "crictl") diff --git a/pkg/minikube/cruntime/cruntime.go b/pkg/minikube/cruntime/cruntime.go index 9bde921993e1..bbb410be131e 100644 --- a/pkg/minikube/cruntime/cruntime.go +++ b/pkg/minikube/cruntime/cruntime.go @@ -166,6 +166,7 @@ func ContainerStatusCommand() string { // disableOthers disables all other runtimes except for me. func disableOthers(me Manager, cr CommandRunner) error { + // valid values returned by manager.Name() runtimes := []string{"containerd", "crio", "docker"} for _, name := range runtimes { @@ -178,13 +179,22 @@ func disableOthers(me Manager, cr CommandRunner) error { if r.Name() == me.Name() { continue } + + // Don't disable containerd if we are bound to it + if me.Name() == "Docker" && r.Name() == "containerd" && dockerBoundToContainerd(cr) { + glog.Infof("skipping containerd shutdown because we are bound to it") + continue + } + // runtime is already disabled, nothing to do. if !r.Active() { continue } + if err = r.Disable(); err != nil { glog.Warningf("disable failed: %v", err) } + // Validate that the runtime really is offline - and that Active & Disable are properly written. if r.Active() { return fmt.Errorf("%s is still active", r.Name()) diff --git a/pkg/minikube/cruntime/docker.go b/pkg/minikube/cruntime/docker.go index 236ae3510ac9..95f855415235 100644 --- a/pkg/minikube/cruntime/docker.go +++ b/pkg/minikube/cruntime/docker.go @@ -364,3 +364,18 @@ func DockerImagesPreloaded(runner command.Runner, images []string) bool { } return true } + +func dockerBoundToContainerd(runner command.Runner) bool { + // NOTE: assumes systemd + rr, err := runner.RunCmd(exec.Command("sudo", "systemctl", "cat", "docker.service")) + if err != nil { + glog.Warningf("unable to check if docker is bound to containerd") + return false + } + + if strings.Contains(rr.Stdout.String(), "\nBindsTo=containerd") { + return true + } + + return false +} diff --git a/pkg/minikube/node/cache.go b/pkg/minikube/node/cache.go index 46a51ba8c9d5..ffbde22e8490 100644 --- a/pkg/minikube/node/cache.go +++ b/pkg/minikube/node/cache.go @@ -21,6 +21,7 @@ import ( "runtime" "github.com/golang/glog" + "github.com/pkg/errors" "github.com/spf13/viper" "golang.org/x/sync/errgroup" cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config" @@ -144,7 +145,7 @@ func saveImagesToTarFromConfig() error { func CacheAndLoadImagesInConfig() error { images, err := imagesInConfigFile() if err != nil { - return err + return errors.Wrap(err, "images") } if len(images) == 0 { return nil @@ -155,7 +156,7 @@ func CacheAndLoadImagesInConfig() error { func imagesInConfigFile() ([]string, error) { configFile, err := config.ReadConfig(localpath.ConfigFile()) if err != nil { - return nil, err + return nil, errors.Wrap(err, "read") } if values, ok := configFile[cacheImageConfigKey]; ok { var images []string diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go index 5abfa40151c2..b469ba6e168f 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -140,7 +140,7 @@ func Start(starter Starter, apiServer bool) (*kubeconfig.Settings, error) { wg.Add(1) go func() { if err := CacheAndLoadImagesInConfig(); err != nil { - out.FailureT("Unable to load cached images from config file: {{error}}", out.V{"error": err}) + out.FailureT("Unable to push cached images: {{error}}", out.V{"error": err}) } wg.Done() }() diff --git a/pkg/minikube/registry/drvs/docker/docker.go b/pkg/minikube/registry/drvs/docker/docker.go index 1e512d9f87a0..db82619eb82a 100644 --- a/pkg/minikube/registry/drvs/docker/docker.go +++ b/pkg/minikube/registry/drvs/docker/docker.go @@ -70,30 +70,40 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) { } func status() registry.State { + docURL := "https://minikube.sigs.k8s.io/docs/drivers/docker/" _, err := exec.LookPath(oci.Docker) if err != nil { - return registry.State{Error: err, Installed: false, Healthy: false, Fix: "Install Docker.", Doc: "https://minikube.sigs.k8s.io/docs/drivers/docker/#install-docker"} + return registry.State{Error: err, Installed: false, Healthy: false, Fix: "Install Docker", Doc: docURL} } - // Allow no more than 3 seconds for docker info - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second) defer cancel() - err = exec.CommandContext(ctx, oci.Docker, "info").Run() + // Quickly returns an error code if server is not running + cmd := exec.CommandContext(ctx, oci.Docker, "version", "--format", "{{.Server.Version}}") + _, err = cmd.Output() + if err == nil { + return registry.State{Installed: true, Healthy: true} + } + + glog.Warningf("docker returned error: %v", err) + // Basic timeout if ctx.Err() == context.DeadlineExceeded { - return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Docker responds too slow. Restart the Docker Service.", Doc: "https://minikube.sigs.k8s.io/docs/drivers/docker"} + return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Restart the Docker service", Doc: docURL} } - if err != nil { - glog.Infof("docker info returned error: %v", err) - if strings.Contains(err.Error(), "Cannot connect to the Docker daemon") { - return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Start the Docker Service.", Doc: "https://minikube.sigs.k8s.io/docs/drivers/docker"} + + if exitErr, ok := err.(*exec.ExitError); ok { + stderr := strings.TrimSpace(string(exitErr.Stderr)) + newErr := fmt.Errorf(`%q %v: %s`, strings.Join(cmd.Args, " "), exitErr, stderr) + + if strings.Contains(stderr, "Cannot connect") || strings.Contains(stderr, "refused") || strings.Contains(stderr, "Is the docker daemon running") { + return registry.State{Error: newErr, Installed: true, Healthy: false, Fix: "Start the Docker service", Doc: docURL} } - // if we get here, something is really wrong on their docker. - // our best suggestion would be re-install latest docker. - return registry.State{Error: err, Installed: true, Healthy: false, Fix: "Re-install the latest version of Docker.", Doc: "https://minikube.sigs.k8s.io/docs/drivers/docker"} + // We don't have good advice, but at least we can provide a good error message + return registry.State{Error: newErr, Installed: true, Healthy: false, Doc: docURL} } - return registry.State{Installed: true, Healthy: true} + return registry.State{Error: err, Installed: true, Healthy: false, Doc: docURL} } diff --git a/site/assets/scss/_variables_project.scss b/site/assets/scss/_variables_project.scss index f9c97d406aa7..768b6b866296 100644 --- a/site/assets/scss/_variables_project.scss +++ b/site/assets/scss/_variables_project.scss @@ -3,16 +3,18 @@ // minikube colors, taken from the logo $mk-dark: #306EE5; $mk-medium: #1FC3CF; -$mk-light:#C7EAEC; +$mk-midlight: #e8f3f3; +$mk-light:#CCEBEC; +$mk-verylight: lighten($mk-light, 15%); $mk-verydark: darken($mk-dark, 15%); // bootstrap colors $dark: #403F4C !default; $blue: #72A1E5 !default; $orange: #BA5A31 !default; -$gray-100: #f8f9fa !default; +$gray-100: #f6f6f8 !default; $gray-200: #eee !default; -$gray-300: #dee2e6 !default; +$gray-300: #dedeef !default; $gray-400: #ccc !default; $gray-500: #adb5bd !default; $gray-600: #888 !default; @@ -31,7 +33,30 @@ $danger: #ED6A5A !default; $white: #fff !default; $light: $mk-light; $medium: $mk-medium; +$spacer: 0.5em; +body, p { + font-family: 'Lora', serif !important; +} + + +h1,h2,h3,h4,h5 { + font-family: 'Open Sans', sans-serif !important; +} + +.step { + margin-top: 2em; + font-family: 'Open Sans', sans-serif !important; + + .text-primary { + color: $mk-dark !important; + } + + .fa-stack { + color: $mk-midlight !important; + margin-right: 0.4em; + } +} // Navigation bar $navbar-dark-color: $mk-dark; @@ -151,21 +176,41 @@ section.td-box--height-auto { } + +// Allow code tags to span most of a window length (default is 80%) +pre { + max-width: 99% !important; + font-family: 'Inconsolata', monospace !important; + font-size: 13px !important; +} + div.td-content { - // Allow code tags to span most of a window length (default is 80%) - pre { - max-width: 99% !important; - } h2 { - font-size: 1.4rem !important; + font-size: 1.6rem !important; } + h3 { font-size: 1.3rem !important; } + + .highlight { + padding: 0.5em !important; + margin-top: 1.25em; + margin-bottom: 1.25em; + } +} + +.td-sidebar { + background-color: $gray-100 !important; +} + +.td-search-input { + background-color: #fff !important; } // make search bar wider https://www.docsy.dev/docs/adding-content/navigation/#configure-local-search-with-lunr .popover.offline-search-result { background-color: $gray-200 !important; max-width: 460px; -} \ No newline at end of file +} + diff --git a/site/content/en/docs/drivers/docker.md b/site/content/en/docs/drivers/docker.md index 248428753d19..65e1db23037d 100644 --- a/site/content/en/docs/drivers/docker.md +++ b/site/content/en/docs/drivers/docker.md @@ -19,8 +19,6 @@ The Docker driver allows you to install Kubernetes into an existing Docker insta ## Known Issues -- On macOS, containers might get hung and require a restart of Docker for Desktop. See [docker/for-mac#1835](https://github.com/docker/for-mac/issues/1835) - - The `ingress`, `ingress-dns` and `registry` addons are currently only supported on Linux. See [#7332](https://github.com/kubernetes/minikube/issues/7332) and [#7535](https://github.com/kubernetes/minikube/issues/7535) - On WSL2 (experimental - see [#5392](https://github.com/kubernetes/minikube/issues/5392)), you may need to run: @@ -33,5 +31,4 @@ The Docker driver allows you to install Kubernetes into an existing Docker insta ## Troubleshooting -- On macOS or Windows, you may need to restart Docker for Desktop if a command gets hung - Run `--alsologtostderr -v=1` for extra debugging information diff --git a/site/content/en/docs/handbook/pushing.md b/site/content/en/docs/handbook/pushing.md index ed2cc65506d0..32c58edf2fdb 100644 --- a/site/content/en/docs/handbook/pushing.md +++ b/site/content/en/docs/handbook/pushing.md @@ -19,7 +19,7 @@ Here is a comparison table to help you choose: |--- |--- |--- |--- |--- | | [docker-env command](/docs/handbook/pushing/#1pushing-directly-to-the-in-cluster-docker-daemon-docker-env) | only docker | | good | | [podman-env command](/docs/handbook/pushing/#3-pushing-directly-to-in-cluster-crio-podman-env) | only cri-o | | good | -| [cache add command](/pushing/#push-images-using-cache-command) | all | | ok | +| [cache add command](/pushing/#2-push-images-using-cache-command) | all | | ok | | [registry addon](/docs/handbook/pushing/#4-pushing-to-an-in-cluster-using-registry-addon) | all | work in progress for [docker on mac](https://github.com/kubernetes/minikube/issues/7535) | ok | | [minikube ssh](/docs/handbook/pushing/#5-building-images-inside-of-minikube-using-ssh) | all | | best | @@ -39,35 +39,44 @@ To point your terminal to use the docker daemon inside minikube run this: eval $(minikube docker-env) ``` -now any 'docker' command you run in this current terminal will run against the docker inside minikube VM or Container. -Try it: +now any 'docker' command you run in this current terminal will run against the docker inside minikube cluster. + +so if you do the following commands, it will show you the containers inside the minikube inside minikube's VM or Container. ```shell docker ps ``` -now you 'build' against the docker inside minikube. which is instantly accessible to kubernetes cluster. +now you can 'build' against the docker inside minikube. which is instantly accessible to kubernetes cluster. -''' -docker build -t myimage . -''' +```shell +docker build -t my_image . +``` -Remember to turn off the `imagePullPolicy:Always` (use `imagePullPolicy:IfNotPresent` or `imagePullPolicy:Never`), as otherwise Kubernetes won't use images you built locally. +To verify your terminal is using minikuber's docker-env you can check the value of the environment variable MINIKUBE_ACTIVE_DOCKERD to reflect the cluster name. -{{% pageinfo %}} +{{% pageinfo color="info" %}} +Tip 1: +Remember to turn off the `imagePullPolicy:Always` (use `imagePullPolicy:IfNotPresent` or `imagePullPolicy:Never`) in your yaml file.otherwise Kubernetes won't use your locally build image and it will pull from the network. +{{% /pageinfo %}} + +{{% pageinfo color="info" %}} +Tip 2: Evaluating the docker-env is only valid for the current terminal. and by closing the terminal, you will go back to using your own system's docker daemon. +{{% /pageinfo %}} -in some drivers such as Docker or Podman, you will need to re-do docker-env each time you restart your minikube. +{{% pageinfo color="info" %}} +Tip 3: +In container-based drivers such as Docker or Podman, you will need to re-do docker-env each time you restart your minikube cluster. {{% /pageinfo %}} -To verify your terminal is using minikuber's docker-env you can check the value of the environment variable MINIKUBE_ACTIVE_DOCKERD to reflect the profile name. more information on [docker-env](https://minikube.sigs.k8s.io/docs/commands/docker-env/) --- -## 2.Push images using 'cache' command. +## 2. Push images using 'cache' command. From your host, you can push a Docker image directly to minikube. This image will be cached and automatically pulled into all future minikube clusters created on the machine @@ -77,15 +86,23 @@ minikube cache add alpine:latest The add command will store the requested image to `$MINIKUBE_HOME/cache/images`, and load it into the minikube cluster's container runtime environment automatically. -{{% pageinfo %}} -if your image changes after your cached it, you could do `cache reload` to ensure minikube gets the last updates. +{{% pageinfo color="info" %}} +Tip 1 : +If your image changes after your cached it, you need to do 'cache reload'. +{{% /pageinfo %}} -``` -shell + +minikube refreshes the cache images on each start. however to reload all the cached images on demand run this command : +```shell minikube cache reload ``` + +{{% pageinfo color="info" %}} +Tip 2 : +if you have multiple cluster, cache command will load the image for all of them. {{% /pageinfo %}} + To display images you have added to the cache: ```shell @@ -108,6 +125,7 @@ For more information, see: ## 3. Pushing directly to in-cluster CRIO. (podman-env) +This is simmilar to docker-env but only for cri-o runtime. To push directly to CRIO, configure podman client on your mac/linux host using the podman-env command in your shell: ```shell diff --git a/site/content/en/docs/handbook/troubleshooting.md b/site/content/en/docs/handbook/troubleshooting.md index b4606f0116c1..0f8e4a143295 100644 --- a/site/content/en/docs/handbook/troubleshooting.md +++ b/site/content/en/docs/handbook/troubleshooting.md @@ -1,8 +1,6 @@ --- title: "Troubleshooting" -linkTitle: "Troubleshoot" weight: 20 -date: 2019-08-01 description: > How to troubleshoot minikube issues --- diff --git a/site/content/en/docs/start/_index.md b/site/content/en/docs/start/_index.md index 6d58d2df6db2..df077d6a8b80 100644 --- a/site/content/en/docs/start/_index.md +++ b/site/content/en/docs/start/_index.md @@ -1,8 +1,190 @@ --- -title: "Get Started!" +title: "minikube start" +linkTitle: "Get Started!" weight: 1 -description: > - How to install minikube aliases: - /docs/start --- + +minikube is local Kubernetes, focusing on making it easy to learn and develop for Kubernetes. + +All you need is Docker (or similarly compatible) container or a Virtual Machine environment, and Kubernetes is a single command away: `minikube start` + + +## What you’ll need + +* 2GB of free memory +* 20GB of free disk space +* Internet connection +* Container or virtual machine manager, such as: [Docker]({{}}), [Hyperkit]({{}}), [Hyper-V]({{}}), [KVM]({{}}), [Parallels]({{}}), [Podman]({{}}), [VirtualBox]({{}}), or [VMWare]({{}}) + +

1Installation

+ +{{% tabs %}} +{{% tab "Linux" %}} + +For Linux users, we provide 3 easy download options: + +### Binary download + +```shell + curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 + sudo install minikube-linux-amd64 /usr/local/bin/minikube +``` + +### Debian package + +```shell +curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_{{< latest >}}-0_amd64.deb +sudo dpkg -i minikube_{{< latest >}}-0_amd64.deb +``` + +### RPM package + +```shell +curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-{{< latest >}}-0.x86_64.rpm +sudo rpm -ivh minikube-{{< latest >}}-0.x86_64.rpm +``` + +{{% /tab %}} +{{% tab "macOS" %}} + +If the [Brew Package Manager](https://brew.sh/) installed: + +```shell +brew install minikube +``` + +Otherwise, download minikube directly: + +```shell +curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 +sudo install minikube-darwin-amd64 /usr/local/bin/minikube +``` + +{{% /tab %}} +{{% tab "Windows" %}} + +If the [Chocolatey Package Manager](https://chocolatey.org/) is installed, use it to install minikube: + +```shell +choco install minikube +``` + +Otherwise, download and run the [Windows installer](https://storage.googleapis.com/minikube/releases/latest/minikube-installer.exe) + +{{% /tab %}} +{{% /tabs %}} + +

2Start your cluster

+ +From a terminal with administrator access (but not logged in as root), run: + +```shell +minikube start +``` + +If minikube fails to start, see the [drivers page]({{}}) for help setting up a compatible container or virtual-machine manager. + +

3Interact with your cluster

+ +If you already have kubectl installed, you can now use it to access your shiny new cluster: + +```shell +kubectl get po -A +``` + +Alternatively, minikube can download the appropriate version of kubectl, if you don't mind the double-dashes in the command-line: + +```shell +minikube kubectl -- get po -A +``` + +minikube bundles the Kubernetes Dashboard, allowing you to get easily acclimated to your new environment: + +```shell +minikube dashboard +``` + +

4Deploy applications

+ +Create a sample deployment and expose it on port 8080: + +```shell +kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4 +kubectl expose deployment hello-minikube --type=NodePort --port=8080 +``` + +Find your cluster IP: + +```shell +minikube ip +``` + +Either navigate to <your ip>:8080 in your web browser, or let minikube do it for you: + +```shell +minikube service hello-minikube +``` + +To access a LoadBalancer application, use the "minikube tunnel" feature. Here is an example deployment: + +```shell +kubectl create deployment balanced --image=k8s.gcr.io/echoserver:1.4 +kubectl expose deployment balanced --type=LoadBalancer --port=8081 +``` + +In another window, start the tunnel to create a routable IP for the deployment: + +```shell +minikube tunnel +``` + +Access the application using the "service" command, or your web browser. If you are using macOS, minikube will also forward DNS requests for you: [http://balanced.default.svc.cluster.local:8081/](http://balanced.default.svc.cluster.local:8081/) + +

5Manage your cluster

+ +Pause Kubernetes without impacting deployed applications: + +```shell +minikube pause +``` + +Halt the cluster: + +```shell +minikube stop +``` + +Increase the default memory limit (requires a restart): + +```shell +minikube config set memory 16384 +``` + +Browse the catalog of easily installed Kubernetes services: + +```shell +minikube addons list +``` + +Create a second cluster running an older Kubernetes release: + +```shell +minikube start -p aged --kubernetes-version=v1.16.1 +``` + +Delete all of the minikube clusters: + + +```shell +minikube delete --all +``` + +## Take the next step + +* [The minikube handbook]({{}}) +* [Community-contributed tutorials]({{}}) +* [minikube command reference]({{}}) +* [Contributors guide]({{}}) +* Take our [fast 5-question survey](https://forms.gle/Gg3hG5ZySw8c1C24A) to share your thoughts 🙏 \ No newline at end of file diff --git a/site/content/en/docs/start/includes/post_install.inc b/site/content/en/docs/start/includes/post_install.inc deleted file mode 100644 index 03ed41bb617d..000000000000 --- a/site/content/en/docs/start/includes/post_install.inc +++ /dev/null @@ -1,22 +0,0 @@ -## Getting to know Kubernetes - -Once started, you can use any regular Kubernetes command to interact with your minikube cluster. For example, you can see the pod states by running: - -```shell - kubectl get po -A -``` - -## Increasing memory allocation - -minikube auto-selects the memory size based on your system up to 6000mb. For larger -deployments, increase the memory allocation using the `--memory` flag, or make the setting persistent using: - -```shell -minikube config set memory 8096 -``` - -## Where to go next? - -Visit the [examples](/docs/examples) page to get an idea of what you can do with minikube. - -📣😀 **Please fill out our [fast 5-question survey](https://forms.gle/Gg3hG5ZySw8c1C24A)** so that we can learn how & why you use minikube, and what improvements we should make. Thank you! 💃🏽🎉 \ No newline at end of file diff --git a/site/content/en/docs/start/linux.md b/site/content/en/docs/start/linux.md deleted file mode 100644 index d4036af85c67..000000000000 --- a/site/content/en/docs/start/linux.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: "Linux" -linkTitle: "Linux" -weight: 1 -aliases: - - /docs/start/linux/ ---- - -## Installation - -{{% tabs %}} -{{% tab "Direct" %}} - -Download and install minikube to /usr/local/bin: - -```shell - curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \ - && sudo install minikube-linux-amd64 /usr/local/bin/minikube -``` -{{% /tab %}} -{{% tab "Debian/Ubuntu (deb)" %}} - -Download and install minikube: - -```shell -curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_{{< latest >}}-0_amd64.deb \ - && sudo dpkg -i minikube_{{< latest >}}-0_amd64.deb - ``` - -{{% /tab %}} - -{{% tab "Fedora/Red Hat (rpm)" %}} - -Download and install minikube: - -```shell -curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-{{< latest >}}-0.x86_64.rpm \ - && sudo rpm -ivh minikube-{{< latest >}}-0.x86_64.rpm - ``` - -{{% /tab %}} -{{% /tabs %}} - -## Driver Setup - -{{% tabs %}} -{{% tab "Docker" %}} -## Check container support -{{% readfile file="/docs/drivers/includes/docker_usage.inc" %}} -{{% /tab %}} - -{{% tab "KVM" %}} -## Check virtualization support -{{% readfile file="/docs/drivers/includes/check_virtualization_linux.inc" %}} - -{{% readfile file="/docs/drivers/includes/kvm2_usage.inc" %}} -{{% /tab %}} -{{% tab "VirtualBox" %}} -## Check virtualization support -{{% readfile file="/docs/drivers/includes/check_virtualization_linux.inc" %}} - -{{% readfile file="/docs/drivers/includes/virtualbox_usage.inc" %}} -{{% /tab %}} -{{% tab "None (bare-metal)" %}} -## Check baremetal support -{{% readfile file="/docs/drivers/includes/check_baremetal_linux.inc" %}} - -If you are already running minikube from inside a VM, it is possible to skip the creation of an additional VM layer by using the `none` driver. - -{{% readfile file="/docs/drivers/includes/none_usage.inc" %}} -{{% /tab %}} -{{% tab "Podman (experimental)" %}} -{{% readfile file="/docs/drivers/includes/podman_usage.inc" %}} -{{% /tab %}} - - -{{% /tabs %}} - -{{% readfile file="/docs/start/includes/post_install.inc" %}} diff --git a/site/content/en/docs/start/macos.md b/site/content/en/docs/start/macos.md deleted file mode 100644 index 5350cbe2d081..000000000000 --- a/site/content/en/docs/start/macos.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: "macOS" -linkTitle: "macOS" -weight: 2 -aliases: - - /docs/start/macos/ ---- - -### Prerequisites - -* macOS 10.12 (Sierra) -* A hypervisor such as Hyperkit, Parallels, VirtualBox, or VMware Fusion - -### Installation - -{{% tabs %}} -{{% tab "Brew" %}} - -If the [Brew Package Manager](https://brew.sh/) is installed, use it to download and install minikube: - -```shell -brew install minikube -``` - -{{% /tab %}} -{{% tab "Direct" %}} - -Download and install minikube to /usr/local/bin: - -```shell -curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \ - && sudo install minikube-darwin-amd64 /usr/local/bin/minikube -``` -{{% /tab %}} -{{% /tabs %}} - -### Upgrading minikube - -{{% tabs %}} -{{% tab "Brew" %}} - -If the [Brew Package Manager](https://brew.sh/) is installed, use it to download and upgrade minikube: - -```shell -brew update -brew upgrade minikube -``` - -{{% /tab %}} -{{% /tabs %}} - -## Hypervisor Setup - -{{% tabs %}} -{{% tab "Docker" %}} -{{% readfile file="/docs/drivers/includes/docker_usage.inc" %}} -{{% /tab %}} -{{% tab "Hyperkit" %}} -{{% readfile file="/docs/drivers/includes/hyperkit_usage.inc" %}} -{{% /tab %}} -{{% tab "VirtualBox" %}} -{{% readfile file="/docs/drivers/includes/virtualbox_usage.inc" %}} -{{% /tab %}} -{{% tab "Parallels" %}} -{{% readfile file="/docs/drivers/includes/parallels_usage.inc" %}} -{{% /tab %}} -{{% tab "VMware" %}} -{{% readfile file="/docs/drivers/includes/vmware_macos_usage.inc" %}} -{{% /tab %}} -{{% tab "Podman (experimental)" %}} -{{% readfile file="/docs/drivers/includes/podman_usage.inc" %}} -{{% /tab %}} - -{{% /tabs %}} - -{{% readfile file="/docs/start/includes/post_install.inc" %}} diff --git a/site/content/en/docs/start/windows.md b/site/content/en/docs/start/windows.md deleted file mode 100644 index 7e318318468e..000000000000 --- a/site/content/en/docs/start/windows.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: "Windows" -linkTitle: "Windows" -weight: 3 -aliases: - - /docs/start/windows/ ---- - -### Prerequisites - -* Windows 8 or above -* 4GB of RAM - -### Installation - -{{% tabs %}} -{{% tab "Direct" %}} -Download and run the [minikube installer](https://storage.googleapis.com/minikube/releases/latest/minikube-installer.exe) -{{% /tab %}} - -{{% tab "Chocolatey" %}} - -If the [Chocolatey Package Manager](https://chocolatey.org/) is installed, use it to install minikube: - -```shell -choco install minikube -``` - -After it has installed, close the current CLI session and reopen it. minikube should have been added to your path automatically. -{{% /tab %}} -{{% /tabs %}} - -{{% tabs %}} -{{% tab "Docker" %}} -{{% readfile file="/docs/drivers/includes/docker_usage.inc" %}} -{{% /tab %}} - -{{% tab "Hyper-V" %}} - -## Check Hypervisor - -{{% readfile file="/docs/drivers/includes/check_virtualization_windows.inc" %}} - -{{% readfile file="/docs/drivers/includes/hyperv_usage.inc" %}} -{{% /tab %}} -{{% tab "VirtualBox" %}} - -## Check Hypervisor - -{{% readfile file="/docs/drivers/includes/check_virtualization_windows.inc" %}} - -{{% readfile file="/docs/drivers/includes/virtualbox_usage.inc" %}} -{{% /tab %}} -{{% /tabs %}} - -{{% readfile file="/docs/start/includes/post_install.inc" %}} diff --git a/site/layouts/partials/hooks/head-end.html b/site/layouts/partials/hooks/head-end.html index 0ff1699c987b..ed11ad10a1ff 100644 --- a/site/layouts/partials/hooks/head-end.html +++ b/site/layouts/partials/hooks/head-end.html @@ -1,4 +1,5 @@ + - + \ No newline at end of file diff --git a/site/static/css/tabs.css b/site/static/css/tabs.css index d3c83fd294b2..60410a2fecb9 100644 --- a/site/static/css/tabs.css +++ b/site/static/css/tabs.css @@ -8,48 +8,62 @@ ul.nav.nav-tabs { div.code-tabs li.nav-tab { margin-top: 1.5rem; - padding: 10px 20px; + padding: 7px 18px; float: left; text-align: center; text-decoration: none; - color: #666; - font-size: 14px; + color: #444; + font-size: 18px; + font-family: 'Open Sans', sans-serif; - border-top: 1px solid #C7EAEC; - border-left: 1px solid #C7EAEC; - border-right: 1px solid #C7EAEC; + border-top: 1px solid #ccc; + border-left: 1px solid #ccc; + border-right: 1px solid #ccc; margin-right: 0.5em; border-top-left-radius: 4px; border-top-right-radius: 4px; - background-color: #c7eaec; + /* inactive tab (title) */ + background-color: #C5E8EA; /* $mk-light - minus two shades*/ } +/* active tab (title) */ div.code-tabs li.active { color: #f2771a; - border-top: 1px solid #C7EAEC; - border-left: 1px solid #C7EAEC; - border-right: 1px solid #C7EAEC; - background: rgb(244, 255, 255); + border-top: 1px solid #b0b6b6; + border-left: 1px solid #b0b6b6; + border-right: 1px solid #b0b6b6; + background: #f3f9fa; /* $mk-verylight */ font-weight: bold; } +/* active tab background */ +div.tab-pane.active { + display: block; + padding: 2em; + background: #f3f9fa; /* $mk-verylight */ + border: 1px solid #b0b6b6; +} + + +/* active tab code sample */ +div.code-tabs div.highlight { + border: 1px solid #ccc; + background-color: #fff; +} + + div.code-tabs a.nav-tab { all: unset; cursor: pointer; } + div.tab-pane { display: none; margin-bottom: 3rem; } -div.tab-pane.active { - display: block; - padding: 2em; - background: rgb(244, 255, 255); - border: 1px solid #C7EAEC; -} div.code-tabs code { word-break: keep-all; diff --git a/test.sh b/test.sh index 21eae1dfed65..79a350164853 100755 --- a/test.sh +++ b/test.sh @@ -60,7 +60,7 @@ then echo "mode: count" >"${COVERAGE_PATH}" pkgs=$(go list -f '{{ if .TestGoFiles }}{{.ImportPath}}{{end}}' ./cmd/... ./pkg/... | xargs) go test \ - -v -ldflags="$MINIKUBE_LDFLAGS" \ + -ldflags="$MINIKUBE_LDFLAGS" \ -tags "container_image_ostree_stub containers_image_openpgp" \ -covermode=count \ -coverprofile="${cov_tmp}" \ diff --git a/test/integration/error_spam_test.go b/test/integration/error_spam_test.go new file mode 100644 index 000000000000..98a4fa150892 --- /dev/null +++ b/test/integration/error_spam_test.go @@ -0,0 +1,69 @@ +// +build integration + +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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 integration + +import ( + "context" + "os/exec" + "strings" + "testing" +) + +// TestErrorSpam asserts that there are no errors displayed +func TestErrorSpam(t *testing.T) { + if NoneDriver() { + t.Skip("none driver always shows a warning") + } + MaybeParallel(t) + + profile := UniqueProfileName("nospam") + ctx, cancel := context.WithTimeout(context.Background(), Minutes(25)) + defer CleanupWithLogs(t, profile, cancel) + + // This should likely use multi-node once it's ready + args := append([]string{"start", "-p", profile, "-n=1", "--memory=2250", "--wait=false"}, StartArgs()...) + + rr, err := Run(t, exec.CommandContext(ctx, Target(), args...)) + if err != nil { + t.Errorf("failed to start minikube with args: %q : %v", rr.Command(), err) + } + + for _, line := range strings.Split(rr.Stderr.String(), "\n") { + if strings.HasPrefix(line, "E") { + t.Errorf("unexpected error log in stderr: %q", line) + continue + } + + if strings.Contains(line, "kubectl") || strings.Contains(line, "slow") || strings.Contains(line, "long time") { + continue + } + if len(strings.TrimSpace(line)) > 0 { + t.Errorf("unexpected stderr line: %q", line) + } + } + + for _, line := range strings.Split(rr.Stdout.String(), "\n") { + keywords := []string{"error", "fail", "warning", "conflict"} + for _, keyword := range keywords { + if strings.Contains(line, keyword) { + t.Errorf("unexpected %q in stdout line: %q", keyword, line) + } + } + } +} diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go index 8545e811a71d..5f1ef0124b1c 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -814,11 +814,16 @@ func setupFileSync(ctx context.Context, t *testing.T, profile string) { testPem := "./testdata/minikube_test.pem" - err = copy.Copy(testPem, localTestCertPath()) - if err != nil { + // Write to a temp file for an atomic write + tmpPem := localTestCertPath() + ".pem" + if err := copy.Copy(testPem, tmpPem); err != nil { t.Fatalf("failed to copy %s: %v", testPem, err) } + if err := os.Rename(tmpPem, localTestCertPath()); err != nil { + t.Fatalf("failed to rename %s: %v", tmpPem, err) + } + want, err := os.Stat(testPem) if err != nil { t.Fatalf("stat failed: %v", err) diff --git a/test/integration/helpers.go b/test/integration/helpers.go index e8bd0b1d9fae..bd1fe195255a 100644 --- a/test/integration/helpers.go +++ b/test/integration/helpers.go @@ -213,7 +213,7 @@ func clusterLogs(t *testing.T, profile string) { t.Logf("%s logs: %s", t.Name(), rr.Output()) t.Logf("======> post-mortem[%s]: disk usage <======", t.Name()) - rr, err = Run(t, exec.Command(Target(), "-p", profile, "ssh", "df -h /var/lib/docker/overlay2 /var /; du -hs /var/lib/docker/overlay2")) + rr, err = Run(t, exec.Command(Target(), "-p", profile, "ssh", "sudo df -h /var/lib/docker/overlay2 /var /;sudo du -hs /var/lib/docker/overlay2")) if err != nil { t.Logf("failed df error: %v", err) } diff --git a/test/integration/start_stop_delete_test.go b/test/integration/start_stop_delete_test.go index fc3462261fad..593019c06f08 100644 --- a/test/integration/start_stop_delete_test.go +++ b/test/integration/start_stop_delete_test.go @@ -135,10 +135,10 @@ func TestStartStop(t *testing.T) { if strings.Contains(tc.name, "cni") { t.Logf("WARNING: cni mode requires additional setup before pods can schedule :(") } else { - if _, err := PodWait(ctx, t, profile, "default", "integration-test=busybox", Minutes(4)); err != nil { + if _, err := PodWait(ctx, t, profile, "default", "integration-test=busybox", Minutes(7)); err != nil { t.Fatalf("failed waiting for pod 'busybox' post-stop-start: %v", err) } - if _, err := PodWait(ctx, t, profile, "kubernetes-dashboard", "k8s-app=kubernetes-dashboard", Minutes(4)); err != nil { + if _, err := PodWait(ctx, t, profile, "kubernetes-dashboard", "k8s-app=kubernetes-dashboard", Minutes(9)); err != nil { t.Fatalf("failed waiting for 'addon dashboard' pod post-stop-start: %v", err) } }