Today I would like to share with you an error that I faced when I was trying to deploy an application to Kubernetes (the standalone version included in Docker Desktop) that led me to understand how Kubernetes pull images from a repository. Let's start detailing the error itself. I created the image:
❯ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry/demoapi latest 110fb82f1b68 23 hours ago 212MB
Using the following configuration I created a deployment in Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapi-test-deployment
labels:
app: demoapi-test
spec:
replicas: 1
selector:
matchLabels:
app: demoapi-test
template:
metadata:
labels:
app: demoapi-test
spec:
containers:
- name: demoapi-test-container
image: registry/demoapi:latest
ports:
- containerPort: 80
Getting an error at the moment to pull the image:
❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
demoapi-test-deployment-7b8f5d4fc7-8fd7t 0/1 ErrImagePull 0 14s
Then a question came to me, why is Kubernetes trying to pull the image If it's already on my machine?. Looking at the pod information, I found that Kubernetes set the image pull policy to "Always":
❯ kubectl get pod demoapi-test-deployment-7b8f5d4fc7-8fd7t -o yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2022-04-17T15:51:47Z"
generateName: demoapi-test-deployment-7b8f5d4fc7-
labels:
app: demoapi-test
pod-template-hash: 7b8f5d4fc7
name: demoapi-test-deployment-7b8f5d4fc7-8fd7t
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: demoapi-test-deployment-7b8f5d4fc7
uid: 7a4cdd35-8f56-4e5e-ab11-efc1e8994423
resourceVersion: "70292"
uid: 4c430c05-f007-4a81-ad6a-396231675567
spec:
containers:
- image: registry/demoapi:latest
imagePullPolicy: Always
name: demoapi-test-container
ports:
- containerPort: 80
protocol: TCP
Then I went to the Kubernetes documentation where I found the logic used to assign the default image pull policy:
- If you omit the imagePullPolicy field, and the tag for the container image is :latest, imagePullPolicy is automatically set to Always.
- If you omit the imagePullPolicy field, and you don't specify the tag for the container image, imagePullPolicy is automatically set to Always.
- If you omit the imagePullPolicy field, and you specify the tag for the container image that isn't :latest, the imagePullPolicy is automatically set to IfNotPresent.
After reading that, the fix was pretty simple. I decided to specify an image pull policy:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demoapi-test-deployment
labels:
app: demoapi-test
spec:
replicas: 1
selector:
matchLabels:
app: demoapi-test
template:
metadata:
labels:
app: demoapi-test
spec:
containers:
- name: demoapi-test-container
image: registry/demoapi:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
And problem fixed:
❯ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
demoapi-test-deployment 1/1 1 1 2s