Kapil Gupta
Kapil Gupta

Reputation: 7731

How can I use local Docker images with Minikube?

I have several Docker images that I want to use with Minikube. I don't want to first have to upload and then download the same image instead of just using the local image directly. How do I do this?

Stuff I tried:


1. I tried running these commands (separately, deleting the instances of Minikube both times and starting fresh)

kubectl run hdfs --image=fluxcapacitor/hdfs:latest --port=8989
kubectl run hdfs --image=fluxcapacitor/hdfs:latest --port=8989 imagePullPolicy=Never

Output:

NAME                    READY     STATUS              RESTARTS   AGE
hdfs-2425930030-q0sdl   0/1       ContainerCreating   0          10m

It just gets stuck on some status but never reaches the ready state.


2. I tried creating a registry and then putting images into it, but that didn't work either. I might've done that incorrectly but I can't find proper instructions to do this task.

Please provide instructions to use local Docker images in a local Kubernetes instance.

OS: Ubuntu 16.04 (Xenial Xerus)
Docker: Docker version 1.13.1, build 092cba3
Kubernetes:

Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.3", GitCommit:"029c3a408176b55c30846f0faedf56aae5992e9b", GitTreeState:"clean", BuildDate:"2017-02-15T06:40:50Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"08e099554f3c31f6e6f07b448ab3ed78d0520507", GitTreeState:"clean", BuildDate:"1970-01-01T00:00:00Z", GoVersion:"go1.7.1", Compiler:"gc", Platform:"linux/amd64"}

What is a solution that uses docker-compose to do this?

Images loaded in eval $(minikube docker-env):

REPOSITORY                                           TAG     IMAGE ID      CREATED       SIZE
fluxcapacitor/jupyterhub                             latest  e5175fb26522  4 weeks ago   9.59 GB
fluxcapacitor/zeppelin                               latest  fe4bc823e57d  4 weeks ago   4.12 GB
fluxcapacitor/prediction-pmml                        latest  cae5b2d9835b  4 weeks ago   973 MB
fluxcapacitor/scheduler-airflow                      latest  95adfd56f656  4 weeks ago   8.89 GB
fluxcapacitor/loadtest                               latest  6a777ab6167c  5 weeks ago   899 MB
fluxcapacitor/hdfs                                   latest  00fa0ed0064b  6 weeks ago   1.16 GB
fluxcapacitor/sql-mysql                              latest  804137671a8c  7 weeks ago   679 MB
fluxcapacitor/metastore-1.2.1                        latest  ea7ce8c5048f  7 weeks ago   1.35 GB
fluxcapacitor/cassandra                              latest  3cb5ff117283  7 weeks ago   953 MB
fluxcapacitor/apachespark-worker-2.0.1               latest  14ee3e4e337c  7 weeks ago   3.74 GB
fluxcapacitor/apachespark-master-2.0.1               latest  fe60b42d54e5  7 weeks ago   3.72 GB
fluxcapacitor/package-java-openjdk-1.8               latest  1db08965289d  7 weeks ago   841 MB
gcr.io/google_containers/kubernetes-dashboard-amd64  v1.5.1  1180413103fd  7 weeks ago   104 MB
fluxcapacitor/stream-kafka-0.10                      latest  f67750239f4d  2 months ago  1.14 GB
fluxcapacitor/pipeline                               latest  f6afd6c5745b  2 months ago  11.2 GB
gcr.io/google-containers/kube-addon-manager          v6.1    59e1315aa5ff  3 months ago  59.4 MB
gcr.io/google_containers/kubedns-amd64               1.9     26cf1ed9b144  3 months ago  47 MB
gcr.io/google_containers/kube-dnsmasq-amd64          1.4     3ec65756a89b  5 months ago  5.13 MB
gcr.io/google_containers/exechealthz-amd64           1.2     93a43bfb39bf  5 months ago  8.37 MB
gcr.io/google_containers/pause-amd64

Upvotes: 677

Views: 459267

Answers (30)

GPuri
GPuri

Reputation: 843

The accepted answer works great on a single node minikube cluster. In case someone wants to build and use a local image on a multi-node minikube cluster, you can use --all file while building the image

minikube image build -t <image-name>:<tag> . --all

The image built via above command can be directly used in deployment file with imagePullPolicy set to Never

FYI, command to run a multi-node minikube cluster

minikube start --nodes <number-of-nodes>

Upvotes: 0

Peter L
Peter L

Reputation: 3361

Ugly But Effective

I use Minikube infrequently and often forget the nuances. So I just save the image to a file and load into Minikube from there...

docker save xxx:latest -o ~/Downloads/delme.img
minikube image load ~/Downloads/delme.img
minikube image ls

Your image should appear as docker.io/library/xxx:latest.

Upvotes: 0

Artem Kozlenkov
Artem Kozlenkov

Reputation: 1264

One thing to remember regarding Minikube is that Minikube's host is not the same as your local host, therefore, what I realized, that in order to use local images for testing with Minikube you must build your Docker image first locally or pull it locally and then add it using the command below into the Minikube context which is, nothing else as another Linux instance.

 minikube cache add <image>:<tag>

Yet, don't forget to set the imagePullPolicy: Never in your Kubernetes deployment YAML files, as it will ensure using locally added images instead of trying pull it remotely from the registry.

Note: minikube cache will be deprecated in upcoming versions. Please switch to minikube image load.

Upvotes: 17

VonC
VonC

Reputation: 1329292

In addition of minikube image load <image name>, check out the latest (Nov 2021 at the time of writing) release of Minikube.

v1.24.0

Add --no-kubernetes flag to start minikube without Kubernetes
See PR 12848, for

That gives you:

mk start --no-kubernetes

Output:

minikube v1.24.0-beta.0 on Darwin 11.6 (arm64)
Automatically selected the docker driver
Starting minikube without Kubernetes minikube in cluster minikube
Pulling base image ...
Creating docker container (CPUs=2, Memory=1988MB) ...
Done! minikube is ready without Kubernetes!

Things to try without Kubernetes

  • "minikube ssh" to SSH into minikube's node.
  • "minikube docker-env" to build images by pointing to the docker inside minikube
  • "minikube image" to build images without docker

Upvotes: 2

saga56
saga56

Reputation: 83

If I understand, you have local images, maybe passed by a USB flash drive and want to load it in Minikube?

Just load the image like:

minikube image load my-local-image:0.1

With this, in the Kubernetes YAML file, you can change the imagePullPolicy to Never, and it will be found, because you just loaded it in Minikube.

I had this problem, have done this, and it worked.

Upvotes: -1

chebus
chebus

Reputation: 772

Most of the answers are already great. But one important thing I have faced is that if you are using BuildKit

(DOCKER_BUILDKIT=1)

then the images created after executing the eval $(minkube docker-env) will not go to the Minikube Docker engine. Instead it will go to your Docker engine on local.

So remove any of the references if you are using below

-mount=type=cache,target=/root/.m2

Upvotes: -1

Anna Klein
Anna Klein

Reputation: 2171

Short version

Upload to the Minikube repository:

minikube image load imageName

Verify the upload:

minikube image ls

Upvotes: 2

Benyamin Jafari
Benyamin Jafari

Reputation: 34246

Alternative solution:

Let's say I already have the Nginx image locally.

docker save -o nginx.tar nginx:1.19.0-alpine
minikube ssh
docker load -i /path/to/nginx.tar

Now, you can create a Kubernetes deployment using the local docker image.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.19.0-alpine
        imagePullPolicy: IfNotPresent  # Note: you can also user 'Never'
        ports:
        - containerPort: 80

Finally:

kubectl apply -f my-deployment.yml

Upvotes: 0

Maytham Fahmi
Maytham Fahmi

Reputation: 33437

For Windows users, the way I do it.

I use the Docker Desktop to host my Minikube image and use PowerShell as a console.

First I create my Minikube cluster:

minikube start --bootstrapper=kubeadm --vm-driver=docker --profile "cluster1"

For instance, let's say I have a Dockerfile contains:

FROM nginx

Two steps way: Build an image and upload the image to Minikube

docker build -t mynginximage .
minikube image load mynginximage

Or a one-step way, build directly in Minikube:

minikube image build -t mynginximage .

To run my image in Minikube:

kubectl run myweb --image=mynginximage --image-pull-policy=Never

Or via the mynginxpod.yaml file:

apiVersion: v1
kind: Pod
metadata:
  name: myweb
spec:
  containers:
    - name: myweb
      image: mynginximage
      imagePullPolicy: Never
      ports:
        - containerPort: 80

And kubectl apply -f .\mynginxpod.yaml

Now to test it, run:

kubectl get pods myweb
NAME    READY   STATUS    RESTARTS   AGE
myweb   1/1     Running   0          25s

To access it:

kubectl exec --stdin --tty myweb -- /bin/bash

To expose it:

kubectl port-forward nginx 3333:80

Upvotes: 6

Alex Cline
Alex Cline

Reputation: 21

Building off the earlier answer to use eval $(minikube docker-env) in order to load up Minikube's Docker environment, for an easier toggle, add the following function to your shell rc file:

dockube() {
  if [[ $1 = 'which' ]]; then
    if [[ $MINIKUBE_ACTIVE_DOCKERD = 'minikube' ]]; then
      echo $MINIKUBE_ACTIVE_DOCKERD
    else
      echo 'system'
    fi
    return
  fi

  if [[ $MINIKUBE_ACTIVE_DOCKERD = 'minikube' ]]; then
    eval $(minikube docker-env -u)
    echo "now using system docker"
  else
    eval $(minikube -p minikube docker-env)
    echo "now using minikube docker"
  fi
}

dockube without any argument will toggle between the system and Minikube Docker environment, and dockube which will return which one is in use.

Upvotes: 2

Nithish Thomas
Nithish Thomas

Reputation: 1565

Newer versions of Minikube allows you to load an image from the local Docker instance by running:

minikube image rm image <imagename>:<version>
minikube image load <imagename>:<version> --daemon

The load command might show an error, but the image still gets loaded to your Minikube instance.

Upvotes: 17

Maciek Leks
Maciek Leks

Reputation: 1448

For Minikube on Docker:

Option 1: Using the Minikube registry

  1. Check your Minikube ports

    docker ps

    You will see something like: 127.0.0.1:32769->5000/tcp It means that your Minikube registry is on the 32769 port for external usage, but internally it's on the 5000 port.

  2. Build your Docker image tagging it:

    docker build -t 127.0.0.1:32769/hello .

  3. Push the image to the Minikube registry:

    docker push 127.0.0.1:32769/hello

  4. Check if it's there:

    curl http://localhost:32769/v2/_catalog

  5. Build some deployment using the internal port:

    kubectl create deployment hello --image=127.0.0.1:5000/hello

    Your image is right now in the Minikube container. To see it, write:

    eval $(minikube -p <PROFILE> docker-env)
    docker images
    

    Caveat: if using only one profile named "minikube" then "-p " section is redundant, but if using more then don't forget about it. Personally I delete the standard one (Minikube) not to make mistakes.

Option 2: Not using the registry

  1. Switch to Minikube container Docker:

    eval $(minikube -p <PROFILE> docker-env)

  2. Build your image:

    docker build -t hello .

  3. Create some deployment:

    kubectl create deployment hello --image=hello

    At the end, change the deployment ImagePullPolicy from Always to IfNotPresent:

    kubectl edit deployment hello

Upvotes: 2

Kartoch
Kartoch

Reputation: 7779

In Minikube 1.20, minikube cache add imagename:tag is deprecated.

Instead, use minikube image load imagename:tag.

Upvotes: -1

Gaurav J.
Gaurav J.

Reputation: 231

Use:

minikube addons enable registry -p minikube

Output:

💡  Registry addon on with docker uses 32769 please use that instead
  of default 5000 <br>
📘  For more information see:
  https://minikube.sigs.k8s.io/docs/drivers/docker

And:

docker tag ubuntu $(minikube ip -p minikube):32769/ubuntu
docker push $(minikube ip -p minikube):32769/ubuntu

Or

minikube addons enable registry
docker tag ubuntu $(minikube ip):32769/ubuntu
docker push $(minikube ip):32769/ubuntu

The above is good enough for development purposes. I am doing this on Arch Linux.

Upvotes: 6

noob_to_so
noob_to_so

Reputation: 55

Steps to run local Docker images in Kubernetes:

  1. eval $(minikube -p minikube docker-env)

  2. In the artifact file, under the spec section → *containers.

    Add:

    imagePullPolicy: IfNotPresent
    

    or

    imagePullPolicy: Never
    
    apiVersion: "v1"
    kind: Pod
    metadata:
        name: web
        labels:
            name: web
            app: demo
    spec:
        containers:
            - name: web
              image: web:latest
              imagePullPolicy: IfNotPresent
              ports:
                  - containerPort: 5000
                    name: http
                    protocol: TCP
    
  3. Then run kubectl create -f <filename>

Upvotes: 2

Krushna
Krushna

Reputation: 6160

There is one easy and effective way to push your local Docker image directly to Minikube, which will save time from building the images in Minikube again.

minikube image load <image name>

(minikube cache add <image name>—the old deprecated way, for reference)

More details are here.

All possible method to push images to Minikube are mention here: Pushing images

Upvotes: 345

jevenus
jevenus

Reputation: 1

I find this method from ClickHouse Operator Build From Sources and it helps and save my life!

docker save altinity/clickhouse-operator | (eval $(minikube docker-env) &&
docker load)

Upvotes: -1

Anurag Manikkame
Anurag Manikkame

Reputation: 837

  1. setup: minikube docker-env
  2. again build the same Docker image (using minikube docker-env)
  3. change imagePullPolicy to Never in your deployment

Actually, your Minikube can't recognise your Docker daemon as it is ab independent service. You have to first set your Minikube-Docker environment use the below command to check:

 "eval $(minikube docker-env)"

If you run the below command, it will show where your Minikube instance looks for Docker.

cd ~
minikube docker-env

Output:

export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.37.192:2376"
export DOCKER_CERT_PATH="/home/ubuntu/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"

**# To point your shell to minikube's docker-daemon, run:**
# eval $(minikube -p minikube docker-env)

You have to again build images once you set up the Minikube docker-env. Else, it will fail.

Upvotes: 0

Sagar Rathod
Sagar Rathod

Reputation: 552

One idea would be to save the Docker image locally and later load it into Minikube as follows:

Let’s say, for example, you already have puckel/docker-airflow image.

  1. Save that image to local disk -

    docker save puckel/docker-airflow > puckel_docker_airflow.tar

  2. Now enter into the Minikube Docker environment -

    eval $(minikube docker-env)

  3. Load that locally-saved image -

    docker load < puckel_docker_airflow.tar

It is that simple, and it works like a charm.

Upvotes: 7

Jackie
Jackie

Reputation: 25997

You can reuse the Docker shell, with eval $(minikube docker-env). Alternatively, you can leverage docker save | docker load across the shells.

Upvotes: -1

dididothat
dididothat

Reputation: 19

What if you could just run Kubernetes within Docker's virtual machine? There's native support for this with the more recent versions of Docker Desktop... You just need to enable that support.

How I found this out:

While reading the documentation for Helm, they give you a brief tutorial how to install Minikube. That tutorial installs Minikube in a virtual machine that's different/separate from Docker.

So when it came time to install my Helm charts, I couldn't get Helm/Kubernetes to pull the images I had built using Docker. That's how I arrived here at this question.

So... if you can live with whatever version of Kubernetes comes with Docker Desktop, and you can live with it running in whatever VM Docker has, then maybe this solution is a bit easier than some of the others.

Disclaimer: I am not sure how switching between Windows/Linux containers would impact anything.

Upvotes: 0

Adam Wise
Adam Wise

Reputation: 2290

A simpler method that answers the question "How can I use local docker images with Minikube?", is to save the image to a tar file and load it into Minikube:

# Export the Docker image to a tar file
docker save --output my-image.tar the.full.path.to/the/docker/image:the-tag
# Set local environment variables so that docker commands go to the Docker in Minikube
eval $(minikube docker-env)
# Or if on Windows: @FOR /f "tokens=*" %i IN ('minikube docker-env') DO @%i
# Import the Docker image from the tar file into Minikube
docker load --input my-image.tar
# Cleanup - put Docker back to normal
eval $(minikube docker-env -u)
# Or if on Windows: @FOR /f "tokens=*" %i IN ('minikube docker-env -u') DO @%i

Then running the image involves a command like the following. Make sure to include the "--image-pull-policy=Never" parameter.

kubectl run my-image --image=the.full.path.to/the/docker/image:the-tag --image-pull-policy=Never --port=80

Upvotes: 9

Nithin
Nithin

Reputation: 5840

Adding to to Farhad's answer based on this answer,

These are the steps to set up a local registry.

Set up in local machine

Set up the hostname in the local machine: edit /etc/hosts to add this line:

docker.local 127.0.0.1

Now start a local registry (remove -d to run non-daemon mode):

docker run -d -p 5000:5000 --restart=always --name registry registry:2

Now tag your image properly:

docker tag ubuntu docker.local:5000/ubuntu

Now push your image to the local registry:

docker push docker.local:5000/ubuntu

Verify that the image is pushed:

curl -X GET http://docker.local:5000/v2/ubuntu/tags/list

Set up in Minikube

SSH into Minikube with: minukube ssh

Edit /etc/hosts to add this line:

docker.local <your host machine's IP address>

Verify access:

curl -X GET http://docker.local:5000/v2/ubuntu/tags/list

Now if you try to pull, yo might get an http access error.

Enable insecure access:

If you are always planning to use Minikube with this local setup then create a Minikube instance to use the insecure registry by default (it won’t work on an existing cluster).

minikube start --insecure-registry="docker.local:5000"

Else follow the below steps:

systemctl stop docker

Edit the Docker serice file: get path from systemctl status docker

It might be:

/etc/systemd/system/docker.service.d/10-machine.conf or /usr/lib/systemd/system/docker.service

Append this text (replace 192.168.1.4 with your IP address)

--insecure-registry docker.local:5000 --insecure-registry 192.168.1.4:5000

to this line

ExecStart=/usr/bin/docker daemon -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --tlsverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=virtualbox --insecure-registry 10.0.0.0/24

And:

systemctl daemon-reload
systemctl start docker

Try pulling:

docker pull docker.local:5000/ubuntu

Now change your YAML file to use the local registry.

containers:
  - name: ampl-django
       image: dockerhub/ubuntu

to

containers:
  - name: ampl-django
    image: docker.local:5000/nymbleup

Don't use http in production. Make the effort for securing things up.

Upvotes: 28

никта
никта

Reputation: 138

Other answers suppose you use Minikube with a VM, so your local images are not accessible from the Minikube VM.

In case if you use Minikube with --vm-driver=none, you can easily reuse local images by setting image_pull_policy to Never:

kubectl run hello-foo --image=foo --image-pull-policy=Never

Or setting the imagePullPolicy field for containers in corresponding .yaml manifests.

Upvotes: 2

Michael B&#246;ckling
Michael B&#246;ckling

Reputation: 7942

There is now a Minikube Registry addon, and this is probably the easiest way. Here is how to use it: Registries

Note that I had DNS issues, and it might be a bug.

Upvotes: 4

tonyslowdown
tonyslowdown

Reputation: 14687

What worked for me, based on the solution by svenwltr:

# Start minikube
minikube start

# Set docker env
eval $(minikube docker-env)             # Unix shells
minikube docker-env | Invoke-Expression # PowerShell

# Build image
docker build -t foo:0.0.1 .

# Run in Minikube
kubectl run hello-foo --image=foo:0.0.1 --image-pull-policy=Never

# Check that it's running
kubectl get pods

Upvotes: 320

Chamila Adhikarinayake
Chamila Adhikarinayake

Reputation: 3756

If anyone is looking to come back to the local environment after setting the Minikube environment, use the following command.

eval $(docker-machine env -u)

Upvotes: 9

Julien Nyambal
Julien Nyambal

Reputation: 674

To add to the previous answers, if you have a tarball image, you can simply load it to you local Docker set of images docker image load -i /path/image.tar. Please remember to run it after eval $(minikube docker-env), since Minikube does not share images with the locally-installed Docker engine.

Upvotes: 2

Chris Stryczynski
Chris Stryczynski

Reputation: 34081

One approach is to build the image locally and then do:

docker save imageNameGoesHere | pv | (eval $(minikube docker-env) && docker load)

minikube docker-env might not return the correct info running under a different user / sudo. Instead you can run sudo -u yourUsername minikube docker-env.

It should return something like:

export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/chris/.minikube/certs"
export DOCKER_API_VERSION="1.23"
# Run this command to configure your shell:
# eval $(minikube docker-env)

Upvotes: 13

Jason
Jason

Reputation: 3179

From the Kubernetes documentation:

Updating images

The default pull policy is IfNotPresent which causes the Kubelet to skip pulling an image if it already exists. If you would like to always force a pull, you can do one of the following:

  • set the imagePullPolicy of the container to Always;
  • use :latest as the tag for the image to use;
  • enable the AlwaysPullImages admission controller.

Or read the other way: Using the :latest tag forces images to always be pulled. If you use the eval $(minikube docker-env) as mentioned in other answers, then either don't use any tag, or assign a tag to your local image you can avoid Kubernetes trying to forcibly pull it.

Upvotes: 7

Related Questions