In this article we will talk about how we can create a custom Docker image and load to our kind cluster
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"]
Top comments (0)