81

I have the following image created by a Dockerfile:

REPOSITORY   TAG      IMAGE ID       CREATED       SIZE 
ruby/lab     latest   f1903b1508cb   2 hours ago   729.6 MB

And I have my following YAML file:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ruby-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: ruby
    spec:
      containers:
      - name: ruby-app
        image: ruby/lab
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 4567

When I create the deployment I got the following info in the pods:

ruby-deployment-3830038651-sa4ii   0/1       ImagePullBackOff   0          7m
ruby-deployment-3830038651-u1tvc   0/1       ImagePullBackOff   0          7m

And the error Failed to pull image "ruby/lab:latest": Error: image ruby/lab not found from below:

 8m            2m              6       {kubelet minikube}      spec.containers{ruby}   Normal          Pulling         pulling image "ruby/lab:latest"
 8m            2m              6       {kubelet minikube}      spec.containers{ruby}   Warning         Failed          Failed to pull image "ruby/lab:latest": Error: image ruby/lab not found
 8m            2m              6       {kubelet minikube}                              Warning         FailedSync      Error syncing pod, skipping: failed to "StartContainer" for "ruby" with ErrImagePull: "Error: image ruby/lab not found"

Is really necessary to have registry in docker for this? I just want to make test locally and pass my code/repo to a friend for testing purposes

Thanks

Joe
  • 3,370
  • 4
  • 33
  • 56
CPB
  • 903
  • 1
  • 8
  • 6

7 Answers7

105

You can point your docker client to the VM's docker daemon by running

eval $(minikube docker-env)

Then you can build your image normally and create your kubernetes resources normally using kubectl. Make sure that you have

imagePullPolicy: IfNotPresent

in your YAML or JSON specs.

Additionally, there is a flag to pass in insecure registries to the minikube VM. However, this must be specified the first time you create the machine.

minikube start --insecure-registry

You may also want to read this when using a private registry http://kubernetes.io/docs/user-guide/images/

Patrick Motard
  • 2,650
  • 2
  • 14
  • 23
Matt Rickard
  • 1,998
  • 1
  • 12
  • 9
  • 2
    @CPB can you mark this as the answer if it solved your issue please? – Patrick Motard Aug 01 '17 at 20:36
  • that worked for me without `minikube start --insecure-registry`. It was not clear for me where to put imagePullPolicy, but I found out. That should be in your deployment.yaml `.spec.template.containers.imagePullPolicy` – Roman T May 13 '18 at 11:13
  • What if I don't use minikube but want to upload the image to a remote cluster? Can kubectl upload the image? – Peter Dotchev Aug 16 '18 at 06:50
  • No @PeterDotchev, you will have to use the docker CLI to do so. And you'll have to have a docker image registry configured, since one is not included in a vanilla kubernetes cluster. – Matt Rickard Aug 24 '18 at 00:43
  • 3
    @MattRickard : I don't use minikube, I use kubectl, kubernetes cluster, I don't have a docker image registry. Can I use local image for deployment ? – taibc Jun 19 '19 at 23:18
  • ANy idea what to pass, flag needs an argument: --insecure-registry – k_vishwanath Oct 07 '19 at 07:53
  • 3
    `minikube start --insecure-registry true` – SaundersB Mar 04 '20 at 22:24
  • I use ContainerD and I had to remove "imagePullPolicy: IfNotPresent" completely and then it respected that the image was already there. I did this just as a last resort for grins and giggles just to see if it would work and lo and behold, it did. I run K8s in an Air-gapped configuration so I have to import the images into the Worker Nodes. – user3008410 Oct 03 '22 at 12:49
  • To answer the original question more directly, especially if Joe can't (or won't) push the image to a repo to which he and his friend have access, he can commit container back to an image (if there's changes in the container that aren't in his image via "docker commit -p CONTAINER_ID NEWNAME"), then save the image to a tarball (via "docker save -o TARBALLNAME.tar IMAGENAME"). He can then send the tarball to his friend who can load it into his Docker (via "docker load --input TARBALLNAME.tar"). – joat Jan 02 '23 at 11:43
  • Joe didn't mention which K8S flavor he uses, but (by default) Minikube uses it's own internal instance of Docker. You can access Minikube's internal Docker instance by first connecting to the Minikube container (via "minikube ssh") then running your Docker commands. – joat Jan 02 '23 at 11:46
  • i am running minikube but the command eval $(minikube docker-env) is not working for me – jmiguel77 Jul 04 '23 at 19:51
39

AFAIR minikube runs in a VM hence it will not see the images you've built locally on a host machine, but... as stated in https://github.com/kubernetes/minikube/blob/master/docs/reusing_the_docker_daemon.md you can use eval $(minikube docker-env) to actually utilise docker daemon running on minikube, and henceforth build your image on the minikubes docker and thus expect it to be available to the minikubes k8s engine without pulling from external registry

kross
  • 3,627
  • 2
  • 32
  • 60
Radek 'Goblin' Pieczonka
  • 21,554
  • 7
  • 52
  • 48
  • 2
    I don't use minikube, I use kubectl, kubernetes. How can I fix this ? – taibc Jun 19 '19 at 23:15
  • 4
    I did this, but it still can't find the local image. – Alexej Magura Sep 19 '19 at 15:41
  • If you're publishing your image using SBT and SBT is running as an existing daemon process that was spawned in another process space then it would not inherit the environment defined by `minikube docker-env` – Coder Guy Feb 23 '21 at 20:44
9

To use an image without uploading it, you can follow these steps: It is important that you be in same shell since you are setting environment variables!

  1. Set the environment variables with eval $(minikube docker-env)
  2. Build the image (eg docker build -t my-image .)
  3. Set the image in the pod spec like the build tag (eg my-image)
  4. Set the imagePullPolicy to Never, otherwise, Kubernetes will try to download the image.
milosnkb
  • 1,523
  • 12
  • 15
3

I ran in a similar issue with minikube v1.9.2, Kubernetes v1.18.0, Docker 19.03.2 on Centos 8.1.1911. All in a single machine used for develop, I chosen for a local insecure docker registry.

The following steps were useful for me to share the local insecure docker registry with local kubernetes/minikube env and to allow kube nodes (and also minikube) to reach Internet:

  1. Disable the firewalld in order to make DNS resolution work inside Docker containers with (reboot required):
    systemctl disable firewalld

    Otherwise during minikube startup it is prompted the following:
    VM may be unable to resolve external DNS records
    VM is unable to access k8s.gcr.io, you may need to configure a proxy or set --image-repository.

    I wasted several days on this.
  2. Retrieve the IP of the network interface created and used by docker, in my case I have docker0 interface name with IP 172.17.0.1. The local insecure registry will be exposed to minikube on this IP.
  3. Configure Docker to read/write from insecure registry by adding the following in /etc/docker/daemon.json:
    {"insecure-registries" : ["172.17.0.1:5000"]}
  4. Restart Docker:
    systemctl restart docker.service
  5. Run minikube with
    minikube start --insecure-registry="172.17.0.1:5000"
    (if already running or yet started, run minikube delete before to start)
  6. Build, tag and push your application in the local insecure registry:
    docker build -t mydemo/demo .
    docker tag mydemo/demo 172.17.0.1:5000/myminikubedemo
    docker push 172.17.0.1:5000/myminikubedemo
  7. Now when you create the deployment.yaml descriptor for your application put the correct image path and then apply:
    kubectl create deployment mydemo --image=172.17.0.1:5000/myminikubedemo --dry-run=client -o=yaml > deployment.yaml
    kubectl apply -f deployment.yaml
fl4l
  • 1,580
  • 4
  • 21
  • 27
0

In my case, the minikube VM can not pull the images even though they are stored locally and the imagePullPolicy is set to Never.

My workaround solution is creating a local docker repository and pushing these images to that repository. Then, specify the image as follow: localhost:5000/image/name. Sources: https://minikube.sigs.k8s.io/docs/handbook/registry/#docker-on-macos

0

In my case, I have setup k8s cluster with kubeadm. so, if you want to use local image to run pod do below things.

If you have docker image, create tar file of image by using below command.

docker save <image-name> -o <filename.tar>

If you have containerd image, create tar file of image by using below command.

ctr image export <output-filename> <image-name>

After transferring the standalone archives to the other systems (using whatever means you prefer; I used scp), then load (or import) the images into containerd with this command:

ctr -n=k8s.io images import <filename-from-previous-step>

Verify that the image(s) are present and recognized by containerd using

ctr image ls

Note that you may not be able to list this image (imported for k8s) using ctr image ls.

Dhruv Modi
  • 36
  • 4
-3

docker pull , pulls all images manually in every node or run a DaemonSet to pull all images

shenyan
  • 408
  • 4
  • 9