Loading Docker Images
Following a system restart, when I didn't have an internet connection, my application
stopped working because Kubernetes could not pull the Docker image
robertoprevato/fortunecookies:latest
from Docker Hub.
When you use the :latest
tag, Kubernetes will attempt to pull the image from the
source registry (e.g., Docker Hub) on each pod restart by default. This means your
workloads deployed to Kubernetes may fail to start if a connection to the source
registry is unavailable, or if the containers registry is unreachable.
While looking for information on this subject, I came across this great article:
I recommend reading this article.
Listing Docker images in Kind¶
To verify which Docker images are loaded in the Kind cluster, enter the
kind-control-plane
using the Docker CLI:
This enters the Docker container using bash
. Then to see the list of
images in the container run the following command:
root@kind-control-plane:/# crictl images
IMAGE TAG IMAGE ID SIZE
registry.k8s.io/ingress-nginx/controller <none> 11b916a025f02 105MB
docker.io/kindest/kindnetd v20250512-df8de77b 409467f978b4a 44.4MB
docker.io/robertoprevato/fortunecookies latest 06c0613648b0c 141MB
registry.k8s.io/coredns/coredns v1.12.0 1cf5f116067c6 20.9MB
registry.k8s.io/etcd 3.5.21-0 499038711c081 58.9MB
registry.k8s.io/kube-scheduler-amd64 v1.33.1 398c985c0d950 74.5MB
registry.k8s.io/kube-scheduler v1.33.1 398c985c0d950 74.5MB
registry.k8s.io/pause 3.10 873ed75102791 320kB
registry.k8s.io/ingress-nginx/kube-webhook-certgen <none> a62eeff05ba51 26.2MB
docker.io/kindest/local-path-helper v20241212-8ac705d0 baa0d31514ee5 3.08MB
docker.io/kindest/local-path-provisioner v20250214-acbabc1a bbb6209cc873b 22.5MB
registry.k8s.io/kube-apiserver-amd64 v1.33.1 c6ab243b29f82 103MB
registry.k8s.io/kube-apiserver v1.33.1 c6ab243b29f82 103MB
registry.k8s.io/kube-controller-manager-amd64 v1.33.1 ef43894fa110c 95.7MB
registry.k8s.io/kube-controller-manager v1.33.1 ef43894fa110c 95.7MB
registry.k8s.io/kube-proxy-amd64 v1.33.1 b79c189b052cd 99.1MB
registry.k8s.io/kube-proxy v1.33.1 b79c189b052cd 99.1MB
crictl
The Kind control plane node runs Kubernetes using containerd
as its container runtime,
not Docker. Therefore, the docker
CLI is not available inside the node.
Instead, you should use crictl
, which is a CLI for CRI-compatible container runtimes
like containerd.
The Container Runtime Interface (CRI) is a set of specifications that define how
container runtimes should behave in a Kubernetes environment. CRI-compatible tools, like
crictl
, are used to interact with container runtimes that are compatible with the CRI
specification, enabling Kubernetes to manage containers. While Docker historically had
its own runtime, Kubernetes adopted the CRI to allow for more flexibility and support
for different runtimes like containerd and CRI-O.
Initially Kubernetes was tightly coupled with Docker (which is understandable, as it was Docker to revolutionize containerization since in 2013).
How to prevent Kubernetes from re-fetching images¶
To prevent Kubernetes from re-fetching container images upon restart, there are two options:
- Using a specific tag for the Docker image, instead of
:latest
. - Applying an
imagePullPolicy
to the container's configuration.
containers:
- name: fortune-cookies
image: robertoprevato/fortunecookies:latest
imagePullPolicy: IfNotPresent
Loading images manually into Kind¶
To load images manually from the host into Kind, you can use the load
command offered
by the kind
CLI. For instance, to load a robertoprevato/mvcdemo:0.0.1
image into
Kind:
This allows you to load images that are built locally into Kind, removing the need to fetch them from a container registry.
For more information, refer to the Kind documentation: Loading an Image Into Your Cluster.
Next steps¶
My next exercise describes how to simulate multiple nodes in Kind.