Pull a local image to run a pod in Kubernetes

DockerKubernetes

Docker Problem Overview


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

Docker Solutions


Solution 1 - Docker

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/

Solution 2 - Docker

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

Solution 3 - Docker

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.

Solution 4 - Docker

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

Solution 5 - Docker

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCPBView Question on Stackoverflow
Solution 1 - DockerMatt RickardView Answer on Stackoverflow
Solution 2 - DockerRadek 'Goblin' PieczonkaView Answer on Stackoverflow
Solution 3 - DockermilosnkbView Answer on Stackoverflow
Solution 4 - Dockerfl4lView Answer on Stackoverflow
Solution 5 - DockershenyanView Answer on Stackoverflow