Running Custom Docker Images Inside Kind Cluster
Tags: kind, kubernetes, docker, devops
Published: 2023-09-17 14:56:33

We are going to build a docker image locally and then run a Pod inside the Kubernetes cluster with that image.

Build a docker image locally using dockerfile. 

Save the following docker file ubuntu-sleep.dockerfile

```
 FROM ubuntu

 ENTRYPOINT ["sleep"]
 CMD ["5"] 
```
Build image `docker build -t ubuntu-sleep -f ubuntu-sleep.dockerfile .`

```
(base) ~/code/devops/kubernetes/CKAD (master ✗) docker build -t ubuntu-sleep -f ubuntu-sleep.dockerfile .
[+] Building 0.1s (5/5) FINISHED                                                                                                  
 => [internal] load build definition from ubuntu-sleeper.dockerfile                                                          0.0s
 => => transferring dockerfile: 51B                                                                                          0.0s
 => [internal] load .dockerignore                                                                                            0.0s
 => => transferring context: 2B                                                                                              0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                                             0.0s
 => CACHED [1/1] FROM docker.io/library/ubuntu                                                                               0.0s
 => exporting to image                                                                                                       0.0s
 => => exporting layers                                                                                                      0.0s
 => => writing image sha256:b739783c0472bbc0008474a0e9f1c5a55dc0419fd4d7851bed8b08fec7596332                                 0.0s
 => => naming to docker.io/library/ubuntu-sleep    
```
Create a [Kind](https://kind.sigs.k8s.io/docs/user/configuration/#getting-started) Cluster with the name demo.  
`kind create cluster --name=demo`

```
(base) ~/code/devops/kubernetes/CKAD (master ✗) kind create cluster --name=demo 
Creating cluster "demo" ...
 ✓ Ensuring node image (kindest/node:v1.25.3) 🖼 
 ✓ Preparing nodes 📦  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹️ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-demo"
You can now use your cluster with:

kubectl cluster-info --context kind-demo

Have a nice day! 👋

```
Load the docker image to the kind cluster demo
`kind load docker-image ubuntu-sleep --name demo`

```
(base) ~/code/devops/kubernetes/CKAD (master ✗) kind load docker-image ubuntu-sleep --name demo
Image: "" with ID "sha256:b739783c0472bbc0008474a0e9f1c5a55dc0419fd4d7851bed8b08fec7596332" not yet present on node "demo-control-plane", loading...
```
Kind load is a very useful command and provides multiple options as well. To get more info about the kind load command use the -h option. 

Run a pod inside the demo cluster with the following command 
`kubectl run ubuntu-sleep --image=ubuntu-sleep`

```
(base) ~/code/devops/kubernetes/CKAD (master ✗) kubectl run ubuntu-sleep --image=ubuntu-sleep
pod/ubuntu-sleep created
(base) ~/code/devops/kubernetes/CKAD (master ✗) kubectl get pod ubuntu-sleep
NAME           READY   STATUS             RESTARTS   AGE
ubuntu-sleep   0/1     ImagePullBackOff   0          14s
```
When we check the pod status it is ImagePullBackOff which means it is failing in running the container with the given image. Wait, what did we do wrong?
Lets, try to debug the problem. As we all know the Kind runs a kubernetes cluster inside docker right? KIND (Kubernetes Inside Docker)

Run the following command to check if the image is already available. 

```
(base) ~/code/devops/kubernetes/CKAD (master ✗) docker exec -it demo-control-plane crictl images
IMAGE                                      TAG                  IMAGE ID            SIZE
docker.io/kindest/kindnetd                 v20221004-44d545d1   7ba9b35cf55e6       23.7MB
docker.io/kindest/local-path-helper        v20220607-9a4d8d2a   304f67e47fc80       2.75MB
docker.io/kindest/local-path-provisioner   v0.0.22-kind.0       7902f9a1c54fa       15.6MB
docker.io/library/ubuntu-sleep             latest               b739783c0472b       71.8MB
registry.k8s.io/coredns/coredns            v1.9.3               b19406328e70d       13.4MB
registry.k8s.io/etcd                       3.5.4-0              8e041a3b0ba8b       81.1MB
registry.k8s.io/kube-apiserver             v1.25.3              feafd6a91eb52       74.2MB
registry.k8s.io/kube-controller-manager    v1.25.3              05b17bba8656e       62.3MB
registry.k8s.io/kube-proxy                 v1.25.3              aa31a9b19ccdf       59.6MB
registry.k8s.io/kube-scheduler             v1.25.3              253d0aeea8c69       50.6MB
registry.k8s.io/pause                      3.7                  e5a475a038057       268kB
```
Yeah! it's there. Then what the hack problem is?
If we sit back and relax and look again at the pod events we see it is trying to pull the image, but why? we already have that in our local system. 
ahhh! we didn't specify the pull policy and the default one is imagePullPolicy: Always 

```
Events:
  Type     Reason     Age                   From               Message
  ----     ------     ----                  ----               -------
  Normal   Scheduled  12m                   default-scheduler  Successfully assigned default/ubuntu-sleep to demo-control-plane
  Normal   Pulling    10m (x4 over 12m)     kubelet            Pulling image "ubuntu-sleep"
  Warning  Failed     10m (x4 over 12m)     kubelet            Failed to pull image "ubuntu-sleep": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/library/ubuntu-sleep:latest": failed to resolve reference "docker.io/library/ubuntu-sleep:latest": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
  Warning  Failed     10m (x4 over 12m)     kubelet            Error: ErrImagePull
  Warning  Failed     10m (x6 over 12m)     kubelet            Error: ImagePullBackOff
  Normal   BackOff    2m19s (x43 over 12m)  kubelet            Back-off pulling image "ubuntu-sleep"
```

Run the pod again, this time with image-pull-policy option
`kubectl run ubuntu-sleep-1 --image=ubuntu-sleep --image-pull-policy=Never`

```
(base) ~/code/devops/kubernetes/CKAD (master ✗) kubectl run ubuntu-sleep-1 --image=ubuntu-sleep --image-pull-policy=Never
pod/ubuntu-sleep-1 created
(base) ~/code/devops/kubernetes/CKAD (master ✗) kubectl get pod 
NAME             READY   STATUS             RESTARTS   AGE
ubuntu-sleep     0/1     ImagePullBackOff   0          8m16s
ubuntu-sleep-1   1/1     Running            0          5s
(base) ~/code/devops/kubernetes/CKAD (master ✗) 
```
woala!!! It is working and the container is running!

Happy Learning...