Docker and Kubernetes notes

Ramesh Pokhrel
7 min readMar 6, 2024

--

Create Node.js project

Create Dockerfile

FROM node:20
WORKDIR /home/node/app
COPY app /home/node/app/
RUN npm install
CMD npm run app
EXPOSE 9000
docker build -t nodeapp .
docker run -p 9001:9000 nodeapp // nodeapp will be available in 9001

Use load balancer with Haproxy LoadBalancing

create haproxy/haproxy.cfg and add extra line at the end. Host can access to 8080 port.

frontend http
bind *:8080
mode http
timeout client 10s
use_backend all

backend all
mode http
server s1 nodeapp1:1111
server s2 nodeapp2:2222
server s3 nodeapp3:3333
server s4 nodeapp4:4444

Docker commands

docker images - Use this command to view a list of Docker images present on your local machine
docker build -t <image_name> <path_to_Dockerfile_directory>
#Create a custom Docker image based on the instructions provided in a Dockerfile.
#eg. docker build . -t pokhrelramesh1996576/k8-demo-node:1.0.1
# docker push pokhrelramesh1996576/k8-demo-node:1.0.1

docker pull <image_name>
#Download Docker images from Docker Hub or other container registries.

docker push <image_name>
#Upload Docker images to a registry for sharing or deployment.

docker rmi <image_name>
#Delete Docker images from your local machine to free up resources.

docker run <options> <image_name>
#Run a Docker container based on an existing image.
docker run -d -p 3000:3000 my-app

docker ps
#View a list of currently running Docker containers.

docker ps -a
#Display a list of all Docker containers, including both running and stopped containers.

docker exec <options> <container_id or container_name> <command>
#Execute a command within a running Docker container

For example, if you want to execute the ls -l command within a container named my_container, the command would look like this:
docker exec -it my_container ls -l
#ls -l is the command to list files and directories within the container.
docker exec -it my_container sh #for container sh terminal
docker exec -it my_container bash #for container bash terminal

docker stop <container_id or container_name>
#Gracefully stop a running Docker container

docker start <container_id or container_name>
#Resume the execution of a previously stopped Docker container

docker restart <container_id or container_name>
#Restart a Docker container with a single command

docker rm <container_id or container_name>
#Delete stopped Docker containers to free up resources.

docker logs <options> <container_id or container_name>
#Retrieve the logs generated by a specific container
Example: docker logs -f my_container

docker inspect <object_id or object_name>
#Retrieve comprehensive information about Docker objects such as containers, images, or networks.
Example: docker inspect my_container

docker top <container_id or container_name>
#View the active processes within a specific container.

docker stats <container_id or container_name>
#Monitor real-time resource usage (CPU, memory, etc.) of running containers.
docker attach <container_id or container_name>
#Connect to the input/output of a running container's main process
docker wait <container_id or container_name>
#Wait for a specific container to exit and print its exit code.
docker network <subcommand> <options>
#This is a top-level command used to manage Docker networks.

#Perform various network-related operations such as creating, inspecting, connecting, or disconnecting Docker networks.
Example: docker network --help

docker network ls
#Display a list of Docker networks present on the Docker host.

docker network create <options> <network_name>
#Create a new Docker network with specified configurations.
Example: docker network create my_network

docker network inspect <network_id or network_name>
#Retrieve comprehensive details about a specific Docker network.
Example: docker network inspect my_network

docker network connect <network_id or network_name> <container_id or container_name>
#Attach a running container to a specific Docker network.
Example: docker network connect my_network my_container
docker-compose <subcommand> <options>
#Define and run multi-container Docker applications.
Examplel: docker-compose --help

docker-compose up <options>
#Create and start containers based on the docker-compose.yml file
Example: docker-compose up -d

docker-compose down <options>
#Stop and remove containers created by docker-compose up

docker-compose ps
#List containers managed by Docker Compose

docker-compose logs <options> <service_name>
#View output from containers managed by Docker Compose
Example: docker-compose logs -f app
#Docker Expose to host machine
docker ps #to get container id
docker exec -it my_container sh #terminal windows /bin/sh
redis-cli

Copy Files

sudo docker container cp 9dd4c391e033:/usr/src/app/ncpdp-test-claim-payload.text .

Kubernetes

Automatic deployment of the containerized applications across different servers.

Distribution of the load across multiple servers

Auto scaling of the deployed applications

Monitoring and Health check of the containers

Replacement of the failed containers

Supported runtime containers

Docker, CRI-O, Containerd

Terminology of kubernetes

Pods: Pod is smallest unit in the kubernetes world, Container will be created inside POD. Pod has one or multiple containers, shared volume, Shared IP address. One container per POD is most common use case.

pod can be moved, removed, from on Node to another Node.

In Kubernetes we can deploy our workloads using different type of API objects like Pods, Deployment, ReplicaSet, ReplicationController and StatefulSets.

Out of those Pods are the smallest deployable unit in Kubernetes. Any workload/application that runs in Kubernetes, has to run inside a container part of a Pod. A Pod could run multiple containers (meaning multiple applications) within it. A Pod is a wrapper on top of one/many running containers. Using a Pod, kubernetes could control, monitor, operate the containers.

Now using stand alone Pods we can’t do lot of things. We can’t change configurations, volumes inside Pods. We can’t restart the Pod if one is down. So there is another API Object called Deployment comes into picture which maintains the desired state (how many instances, how much compute resource application uses) of the application. The Deployment maintaines multiple instances of same application by running multiple Pods. Deployments unlike Pods are mutable. Deployments uses another API Object called ReplicaSet to maintain the desired state. Deployments through ReplicaSet spawns another Pod if one is down.

So Pod runs applications in containers. Deployments run Pods and maintains desired state of the application.

Kubernetes Cluster: Collections of Nodes, Inside node, there is pod, and inside pod there is container. Cluster has master node, it’s job is to distribute loads across worked node, It’s system node.

kubectl command is use to manage kubernetes cluster.

Minikube

Creates kubernetes Cluster with single Node. This could be both master node and worker node.

minikube node user credentials:

ssh docker@minikune-ip
OR
minikube ssh //for docker

username: docker
password: tcuser
minikube status
minikube start --driver docker
minikube status
kubectl get nodes //control-panel is master node
minikube ip

Kubectl

kubectl command is use to manage kubernetes cluster.

//add alias for kubectl
alias k="kubectl"


kubectl get nodes //control-panel is master node
kubectl get pods
kubectl get namespaces
kubectl get pods --namespace=
kubectl run newpod --image=docker-image-name //it will create newpod
kubectl describe pod pod-name //print all information of the pod

kubectl get all //of get all deployments, pods. services
kubectl get configmap //
kubectl get secret //
kubectl get pod //
kubectl describe pod podid //
kubectl get svc //get services
minikube ip //get minikube ip


kubectl get deployment
kubectl delete deployment dpname
kubectl logs deploymentname -f
kubectl get svc // list of services

kubectl create deployment deployment-name --image=docker-image
kubectl create deployment k8-node-deployment --image=pokhrelramesh1996576/k8-demo-node:1.0.0

//create service for particular deployment
//we expose internal port from container 80 to external port 8080
kubectl expose deployment k8-node-deployment --port=8080 --target-port=80

// set latest image to deployment
kubectl set image deployment deployment-name image-name=changed-image-name
kubectl rollout status deploy deployment-name
//copy service internal ip address
kubectl get svc

//get minikube ip address
minikube ip

//enter in minikube cluster
minikube ssh or ssh docker@minikubeip

//now connect with curl ip of deployment and port
curl 10.97.246.243:8080


kubectl get deployments
kubectl get pods
kubectl describe deployment deployment-name

Kubernetes Services

Each pod has it’s own IP address, Pods are emphemeral — are destroyed frequently. And you have to adjust ip every time pods created and destroyed. So need of Service.

Service has stable IP address,

Service types:

ClusterIP service:

If you would like to connect specific deployment using specific ip address, you need service. Possible to expose ip address to outside world.

#create service for particular deployment
# we expose internal port from container 80 to external port 8080
kubectl expose deployment deployment-name --port=8080 --target-port=80 --type=NodePort

minikube service k8-demo

First create config and secret

  1. Add pg-config.yaml

go to kubernetes documentations and serch for configmap, copy content

2. Add pg-secret.yaml, go kubernetes documentation and search for secret and copy content. For username and password, we have to encode the text , i.e pguser

echo -n pguser| base64

Second deployment

  1. create pg-deployment.yaml file, and search deployment in kubernetes documentation, copy content

Deployment kind

template is configuration for pod, has it’s own metadata and spec section.

containers has which image and which port.

Labels: you can give any k8s component label, labels are key/value pair that are attached to k8s resources. identifier which shoule be meaningful and relevant to users.

  • you can write multiple yaml configuration within same file with 3 dash

Service config file:

kind: service

Web app need information about database username password and database url endpoint where we can access

Configure external service

Web app should be accessible from outside

External service for external access

type: service type

default:

ClusterIP=> internal service

NodePort=> external service

Deploy all resources in mini kube

if kubectl doesn't work, run minikube start

kubectl apply -f pg-config.yaml
kubectl apply -f pg-secret.yaml
kubectl apply -f pg-deployment.yaml
kubectl apply -f webapp-deployment.yaml

validate webapp is accessible to broswer. Nodeport service is always accessible to worker’s node ip address.

kubectl get svc
minikube ip
//Use LoadBalancer in spec type and use minikube tunnel to get external ip address

github link : https://github.com/kanxoramesh/k8-demo

--

--