kind - Loading Custom Docker Image into the Cluster - Part 2

kind - Loading Custom Docker Image into the Cluster - Part 2

In this article we will talk about how we can create a custom Docker image and load to our kind cluster

·

3 min read

Prerequisites

We need a running kind cluster to do our tasks

$ kubectl get nodes
NAME                STATUS   ROLES           AGE   VERSION
dev-control-plane   Ready    control-plane   25s   v1.26.3

Building Docker Image

Create a sample index.html file

$ echo “Hello from Pod!” > index.html

Write a Dockerfile for our custom application

$ cat Dockerfile
FROM nginx:1.23
COPY index.html /usr/share/nginx/html

Now we have index.html and Dockerfile in the working directory

$ tree
.
├── Dockerfile
└── index.html

0 directories, 2 files

Build the image using Dockerfile

$ docker image build -f Dockerfile -t my-app:v1 .
[+] Building 0.9s (7/7) FINISHED                                                                                                                                                               
 => [internal] load build definition from Dockerfile                                                                                                                                      0.0s
 => => transferring dockerfile: 91B                                                                                                                                                       0.0s
 => [internal] load .dockerignore                                                                                                                                                         0.0s
 => => transferring context: 2B                                                                                                                                                           0.0s
 => [internal] load metadata for docker.io/library/nginx:1.23                                                                                                                             0.9s
 => [1/2] FROM docker.io/library/nginx:1.23@sha256:63b44e8ddb83d5dd8020327c1f40436e37a6fffd3ef2498a6204df23be6e7e94                                                                       0.0s
 => [internal] load build context                                                                                                                                                         0.0s
 => => transferring context: 31B                                                                                                                                                          0.0s
 => CACHED [2/2] COPY index.html /usr/share/nginx/html                                                                                                                                    0.0s
 => exporting to image                                                                                                                                                                    0.0s
 => => exporting layers                                                                                                                                                                   0.0s
 => => writing image sha256:e7d1111901cd427f155186597c1dfc850e1a7656b9ad0291f23e8a9dcc60e1de                                                                                              0.0s
 => => naming to docker.io/library/my-app:v1
$ docker image ls
REPOSITORY     TAG       IMAGE ID       CREATED              SIZE
my-app         v1        e7d1111901cd   About a minute ago   142MB
kindest/node   <none>    36d37c652064   3 weeks ago          936MB

Deploying Application

Now our custom Docker image is ready and we can load it to our Kubernetes cluster

$ kind load docker-image my-app:v1 --name dev
Image: "my-app:v1" with ID "sha256:e7d1111901cd427f155186597c1dfc850e1a7656b9ad0291f23e8a9dcc60e1de" not yet present on node "dev-control-plane", loading...

We can get a list of images loaded in our cluster using the below command

$ docker container exec -it dev-control-plane crictl images
IMAGE                                                     TAG                 IMAGE ID            SIZE
docker.io/library/my-app                                  v1                  e7d1111901cd4       147MB
registry.k8s.io/kube-controller-manager                   v1.26.3             cb77c367deebf       68.5MB
registry.k8s.io/kube-proxy                                v1.26.3             eb3079d47a23a       67.2MB
registry.k8s.io/kube-scheduler                            v1.26.3             dec886d066492       57.8MB
docker.io/library/import-2023-04-20                       <none>              1e4c13e43754c       147MB
registry.k8s.io/coredns/coredns                           v1.9.3              5185b96f0becf       14.8MB
registry.k8s.io/etcd                                      3.5.6-0             fce326961ae2d       103MB
registry.k8s.io/pause                                     3.7                 221177c6082a8       311kB
docker.io/kindest/local-path-helper:v20230330-48f316cd    <none>              37af659db0ba1       3.05MB
docker.io/kindest/local-path-provisioner:v0.0.23-kind.0   <none>              c408b2276bb76       18.7MB
registry.k8s.io/kube-apiserver                            v1.26.3             801fc1f38fa6c       80.4MB

Create a pod using our custom image and expose it as ClusterIP

$ kubectl run my-app --image=my-app:v1 --port=80 --expose
service/my-app created
pod/my-app created
$ kubectl get pods,svc
NAME         READY   STATUS    RESTARTS   AGE
pod/my-app   1/1     Running   0          7s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   57m
service/my-app       ClusterIP   10.96.168.181   <none>        80/TCP    7s

Once our pod is running, verify our application using the below command.
From the output, we can see the “Hello from Pod!” message.

$ kubectl run busybox --image=busybox --restart=Never --rm -it -- wget -O- http://my-app
Connecting to my-app (10.96.168.181:80)
writing to stdout
Hello from Pod!
-                    100% |********************************|    16  0:00:00 ETA
written to stdout
pod "busybox" deleted

Cleanup

Deleting our cluster

$ kind delete cluster --name dev
Deleting cluster "dev" ...
Deleted nodes: ["dev-control-plane"]

Reference

https://kind.sigs.k8s.io/