1. Overview
In this tutorial, we’ll deploy Docker containers to Kubernetes and see how we can use local images for these containers. We’ll use Minikube to run the Kubernetes cluster.
2. Dockerfile
First of all, we need a Dockerfile to be able to create local Docker images. This should be simple because we’ll focus on the Minikube commands.
Let’s create a Dockerfile with just an echo command that prints a message:
FROM alpine
CMD ["echo", "Hello World"]
3. docker-env Command
For the first approach, we need to make sure that Docker CLI is installed. This is a tool for managing Docker resources, such as images and containers.
By default, it uses the Docker Engine on our machine, but we can change that easily. We’ll use this and point our Docker CLI to the Docker Engine inside Minikube.
Let’s check this prerequisite and see if the Docker CLI is working:
$ docker version
The output should be similar to this:
Client: Docker Engine - Community
Version: 19.03.12
...
Server: Docker Engine - Community
Engine:
Version: 19.03.12
...
Let’s proceed with the next steps. We can configure this CLI to use the Docker Engine inside Minikube. This way, we’ll be able to list the images available in Minikube and even build images inside it.
Let’s see the steps required to configure the Docker CLI:
$ minikube docker-env
We can see the list of commands here:
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://172.22.238.61:2376"
export DOCKER_CERT_PATH="C:\Users\Baeldung\.minikube\certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"
# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)
Let’s execute the command from the last line as it will do the configuration for us:
$ eval $(minikube -p minikube docker-env)
Now, we can use the Docker CLI to investigate the Docker environment inside Minikube.
Let’s list the available images with the minikube image ls command:
$ minikube image ls --format table
This prints a table with the images:
|-----------------------------------------|---------|---------------|--------|
| Image | Tag | Image ID | Size |
|-----------------------------------------|---------|---------------|--------|
| docker.io/kubernetesui/dashboard | <none> | 1042d9e0d8fcc | 246MB |
| docker.io/kubernetesui/metrics-scraper | <none> | 115053965e86b | 43.8MB |
| k8s.gcr.io/etcd | 3.5.3-0 | aebe758cef4cd | 299MB |
| k8s.gcr.io/pause | 3.7 | 221177c6082a8 | 711kB |
| k8s.gcr.io/coredns/coredns | v1.8.6 | a4ca41631cc7a | 46.8MB |
| k8s.gcr.io/kube-controller-manager | v1.24.3 | 586c112956dfc | 119MB |
| k8s.gcr.io/kube-scheduler | v1.24.3 | 3a5aa3a515f5d | 51MB |
| k8s.gcr.io/kube-proxy | v1.24.3 | 2ae1ba6417cbc | 110MB |
| k8s.gcr.io/pause | 3.6 | 6270bb605e12e | 683kB |
| gcr.io/k8s-minikube/storage-provisioner | v5 | 6e38f40d628db | 31.5MB |
| k8s.gcr.io/echoserver | 1.4 | a90209bb39e3d | 140MB |
| k8s.gcr.io/kube-apiserver | v1.24.3 | d521dd763e2e3 | 130MB |
|-----------------------------------------|---------|---------------|--------|
If we compare it with the output of the docker image ls command, we see that both show the same list. This means that our Docker CLI is correctly configured.
Let’s use our Dockerfile and build an image from it:
$ docker build -t first-image -f ./Dockerfile .
Now that it’s available within Minikube, we can create a pod that uses this image:
$ kubectl run first-container --image=first-image --image-pull-policy=Never --restart=Never
Let’s check the logs of this pod:
$ kubectl logs first-container
We can see the expected “Hello World” message. Everything works correctly. Let’s close the terminal to make sure our Docker CLI is not connected to Minikube for the next example.
4. Minikube Image Load Command
Let’s see another approach for using local images. This time, we’ll build the Docker image outside of Minikube on our machine and load it into Minikube. Let’s build the image:
$ docker build -t second-image -f ./Dockerfile .
Now the image exists, but it’s not yet available in Minikube. Let’s load it:
$ minikube image load second-image
Let’s list the images and check if it’s available:
$ minikube image ls --format table
We can see the new image in the list. This means that we can create the pod:
$ kubectl run second-container --image=second-image --image-pull-policy=Never --restart=Never
The container starts successfully. Let’s check the logs:
$ kubectl logs second-container
We can see it prints the correct message.
5. Minikube Image Build Command
In the previous example, we loaded a pre-built Docker image to Minikube. However, we can also build our images inside Minikube.
Let’s use the same Dockerfile and build a new Docker image:
$ minikube image build -t third-image -f ./Dockerfile .
Now that the image is available in Minikube, we can start a container with it:
$ kubectl run third-container --image=third-image --image-pull-policy=Never --restart=Never
Let’s check the logs to make sure it’s working:
$ kubectl logs third-container
It prints the “Hello World” message as expected.
6. Conclusion
In this article, we used three different ways to run local Docker images in Minikube.
Firstly, we configured our Docker CLI to connect to the Docker Engine inside Minikube. Then, we saw two commands to load a pre-built image and build an image directly in Minikube.