To understand Pod, we would like to assume that the application is already developed and built into docker images and it is available on a docker repository like Docker Hub. So, Kubernetes can pull it down. Also, we assume that the Kubernetes cluster has been set up and is working.
Kubernetes is to deploy our application in the form of containers on a set of machines that are configured as worker nodes in a cluster. However, Kubernetes does not deploy containers directly on the worker nodes, the containers are encapsulated into a Kubernetes object known as POD. A pod is a single instance of an application. A pod is the smallest object that you can create in Kubernetes.
If you want to build the simplest pod, you need at least single-node Kubernetes cluster with a single instance of your application running in a single docker container encapsulated in a pod.
What if the number of users accessing your application increased and you need to scale the application. You need to add additional instances of your web application to share the load.
- Add additional pods on the node in the cluster
- Add additional pods on a new node in the cluster
Pods usually have a one to one relationship with containers running your application to scale up. You do not add additional containers to any existing pod to scale the application.
- Scale-up: create new pods
- Scale-down: delete existing pods.
Multi-Containers on a POD
You have a scenario where you have a helper container that might be doing some kind of supporting tasks, so you need containers in the same pod. The two or more containers can also communicate with each other directly by referring to each other as localhost since they share the same network space plus they can easily share the same storage space as well.
Let’s assume, we were developing a process or a script to deploy our application on a docker host. Then we would first simply deploy our application using a simple docker run command, and the application runs fine. When the load increases we deploy more instances of our application by running the docker run commands many more fines. In the future, our application is further developed, undergoes architectural changes, and grows and gets complex. We now have a new helper container that helps our web application by processing or fetching data from elsewhere. the helper containers maintain one to one relationship with our application container and need to communicate with the application containers directly and access data from those containers. And now, we need to maintain a map of what app and helper containers are connected to each other we will need to establish network connectivity between these containers ourselves using links and custom networks, we would need to create shareable volumes and share among the containers, and we would need to monitor the state of the application container and when it dies manually kill it. Also, the helper containers as well. With pod, Kubernetes does all of this for us automatically. We just need to define what containers pod consist of and the containers in a pod by default will have access to the same storage the same network the same namespace, and the same fate as well as they will be created together and destroyed together. Even if our application did not happen to be so complex and we could live with a single container Kubernetes still requires you to create pods but this is good in the long run as your application is now equipped for architectural changes and scale in the future. However, also note that muti-containers pods are a rare use case.
How to deploy pod?
Kubectl
$ kubectl run nginx
It deploys a docker container by creating a pod. So it first creates a pod automatically and deploys an instance of the nginx docker image, but where does it get the application image from. For that, you need to specify the image name using the — image parameter.
$ kubectl run nginx --image nginx
The application image in the case the nginx image is downloaded from the Docker-Hub repository. You could configure kubernetes to pull the image from the public Docker Hub or a private repository.
How do we see the list of pods available?
$ kubectl get pods
$ kubectl get pods -o wide
- kubectl get pods command helps us see the list of pods in our cluster.
How a user can access the nginx web server?
We have not made the web server accessible to external users. You can access it internally from the node. To access our pods from end users, we need to set up networking and services.
Kubectl with Minikube
$ kubectl run nginx --image=nginx
$ kubectl get pods
$ kubectl get pods -o wide
$ kubectl describe pod nginx
$ kubectl run nginx --image=nginx
pod/nginx created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 12m
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 7m43s 172.17.0.2 minikube <none> <none>
$ kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Node: minikube/192.168.49.2
Start Time: Fri, 06 Nov 2020 20:36:06 +0900
Labels: run=nginx
Annotations: <none>
Status: Running
IP: 172.17.0.2
IPs:
IP: 172.17.0.2
Containers:
nginx:
Container ID: docker://7794b90df31aedc7d504b38f8580596e8ee78ef0ae19bf6102b0fa1e004bf431
Image: nginx
Image ID: docker-pullable://nginx@sha256:aeade65e99e5d5e7ce162833636f692354c227ff438556e5f3ed0335b7cc2f1b
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 06 Nov 2020 20:36:15 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-cvxfx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-cvxfx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-cvxfx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 8m44s default-scheduler Successfully assigned default/nginx to minikube
Normal Pulling 8m44s kubelet Pulling image "nginx"
Normal Pulled 8m36s kubelet Successfully pulled image "nginx" in 7.217702738s
Normal Created 8m36s kubelet Created container nginx
Normal Started 8m36s kubelet Started container nginx
- Run the command kubectl
–image=nginx, here is where we specify the docker image to be used. While the pod name could be anything, the image name has to be the name of an image available at Docker Hub or Private container registry, and you can additionally specify a tag for the image name or a different address to an image hosted on another registry.
Create Pod with apple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
protocol: TCP
$ kubectl create -f nginx-pod.yaml
pod/nginx-pod created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 12s
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 32s 172.18.0.4 minikube <none> <none>
$ kubectl describe pods nginx-pod
Name: nginx-pod
Namespace: default
Priority: 0
Node: minikube/172.17.0.2
Start Time: Mon, 11 Jan 2021 10:58:12 +0900
Labels: app=nginx
Annotations: <none>
Status: Running
IP: 172.18.0.4
IPs:
IP: 172.18.0.4
Containers:
nginx-container:
Container ID: docker://5e861e9fe30c3838cb66bda4540b331aaea9c138f500f40619a3d13752826778
Image: nginx
Image ID: docker-pullable://nginx@sha256:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 11 Jan 2021 10:58:16 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-jkzz4 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-jkzz4:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-jkzz4
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 65s default-scheduler Successfully assigned default/nginx-pod to minikube
Normal Pulling 65s kubelet Pulling image "nginx"
Normal Pulled 62s kubelet Successfully pulled image "nginx" in 3.3901334s
Normal Created 62s kubelet Created container nginx-container
Normal Started 62s kubelet Started container nginx-container