Pull a local image to run a pod in Kubernetes
DockerKubernetesDocker 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!
- Set the environment variables with eval $(minikube docker-env)
- Build the image (eg docker build -t my-image .)
- Set the image in the pod spec like the build tag (eg my-image)
- 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:
- 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. - Retrieve the IP of the network interface created and used
by docker, in my case I have
docker0
interface name with IP172.17.0.1
. The local insecure registry will be exposed to minikube on this IP. - Configure Docker to read/write from insecure registry by adding the
following in
/etc/docker/daemon.json
:
{"insecure-registries" : ["172.17.0.1:5000"]}
- Restart Docker:
systemctl restart docker.service
- Run minikube with
minikube start --insecure-registry="172.17.0.1:5000"
(if already running or yet started, runminikube delete
before to start) - 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
- 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