KIND: Kubernetes In Docker — Beginner’s Guide To Create Cluster, Deployment, Service, Ingress & ConfigMap

Nash
4 min readAug 26, 2023

--

When I first started learning Kubernetes for a project requirement, I was suggested to use a lighter version of Kubernetes. My initial thought was to use k3s, and as I explored it, I came across an article that mentions the advantages of kind over k3s¹.

Kind (Kubernetes in Docker) helps you run Kubernetes clusters locally and in CI pipelines using Docker containers as “nodes”.

Based on resource availability and the need to transition to Kubernetes from on-premise before moving to AWS, I gave a green signal to kind. Before I proceed any further, let me mention that it is assumed that the reader knows how to containerise an application using Docker.

Here I have provided step-by-step instructions from installation on Linux (Ubuntu) to communicating with the service deployed on Kubernetes using curl command.

  1. Install kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/ to apply Kubernetes configuration files and run basic commands.
  2. Install kind: https://kind.sigs.k8s.io/docs/user/quick-start
  3. Write a config file, kind-cluster.yml to create a kind cluster².
    a. role: control-plane is the master node
    b. node-labels: “ingress-ready=true” allows ingress controller to run on a specific node matching the label selector.
    c. extraPortMappings allows the local host to make requests to the ingress controller over ports 80/443
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP

5. Create the cluster by using the kind-cluster.yml file.

kind create cluster --image kindest/node:v1.27.3 --name test-cluster --config kind-cluster.yml

6. Once the cluster is created successfully, load the docker image(s) on the cluster

kind load docker-image example-docker-image:tag --name test-cluster

7. Write the deployment, service & ingress for your application, kube-manifests.yml
a. replicas: 1, there will have one replica of main the pod.
b. Make sure the metadata:name in Service has same value as backend:service:name in Ingress.
c. It is suggested to provide same value to selector:matchLabels:app & metadata:labels:app in Deployment and selector:app in Service.
d. ingressClassName: nginx, should be the name of the ingress class you are using.
e. nginx.ingress.kubernetes.io/ssl-redirect: “false”, allows you to access the host, test.example.com, using http.
f. The port exposed in your Dockerfile must be same to the value of containerPort in Deployment.

apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
replicas: 1
selector:
matchLabels:
app: example-label
template:
metadata:
labels:
app: example-label
spec:
containers:
- name: example-container
image: example-image:tag
ports:
- containerPort: 8084
env:
- name: DB_NAME
valueFrom:
configMapKeyRef:
name: example-config
key: db.name
- name: DB_SVC
valueFrom:
configMapKeyRef:
name: example-config
key: db.svc
---
apiVersion: v1
kind: Service
metadata:
labels:
app: example-label
name: example-service
spec:
selector:
app: example-label
ports:
- protocol: TCP
port: 8084
targetPort: 8084
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx
rules:
- host: test.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 8084

6. In the above code snippet you can see that the environment values are referred from a configMap (valueFrom:configMapKeyRef). Write a config map for those environment values, configMap.yml
a. The value of metadata:name in ConfigMap must be same as valueFrom:configMapKeyRef:name in Deployment
b. The key under data in ConfigMap must be same as valueFrom:configMapKeyRef:key in Deployment

apiVersion: v1
kind: ConfigMap
metadata:
name: example-config
data:
db.name: database_name
db.svc: another-example-service:port-number

7. It is important that you install an ingress controller³. Here I have considered the ingress NGINX controller.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

8. Apply the configMap.yml as well as kube-manifests.yml file in the kubernetes cluster you have created.

kubectl apply -f configMap.yml
kubectl apply -f kube-manifests.yml

9. Use the below commands to check the pods, services and ingress, respectively.

kubectl get po -o wide
kubectl get svc -o wide
kubectl get ing -o wide

10. To see detail information about any pod, service or ingress, use the below commands.

kubectl describe po <pod-name>
kubectl describe svc <service-name>
kubectl describe ing <ingress-name>

11. Add the host mentioned in Ingress of kube-manifests.yml file, in your /etc/hosts file and access it using curl command.

127.0.0.1       test.example.com
curl --head http://test.example.com

Hope the content of this article has successfully fulfilled its intended objectives and effectively addressed the goals it was meant to achieve.

[***] To learn another interesting work on Kind Kubernetes dive to this article.

[1] kind vs k3s https://thechief.io/c/editorial/kind-vs-k3s/

[2] Different commands related to kind cluster https://kind.sigs.k8s.io/docs/user/quick-start/

[3] All about ingress in kind https://kind.sigs.k8s.io/docs/user/ingress/

[4] The GitHub link which I have referred for understanding purpose https://github.com/ardanlabs/service/tree/master

--

--

Nash

Software developer with a passion for Kubernetes, ML, and Networking. Committed to merging skills for innovative solutions.