Kubernetes – POD

A Pod is a basic unit of deployment that encloses one or more containers in it. The Pod API object is used to create a single instance of a Pod.

An application may need multiple things for its operation as shown in the diagram. A container that run the app may not support all of them; a Docker container does not provide an in-built support for external storage for instance.

The Pod that encloses the containers, builds the features needed for the underlying application instances. It fulfills the needs of the app and the needs of framework to manage the app instance as shown.

As shown in the diagram, each Pod gets a separate virtual IP as its address and acts like a separate virtual machine. With the virtual networking model K8s keeps the applications secured and independent from the from outside world. It also helps K8s automate internal traffic routing and service discovery.

 

Lifecycle , Restart Policy , Hooks & Probes

As the system plans to create an instance of a Pod, the system asks the scheduler to find a suitable Node. As we find the node, the kubelet on the Node is handed over the Pod spec to create and manage it. The kubelet ensures the Pod and the containers within it run as per the specifications. And, keeps updating their status to the Master node.

This diagram briefly consolidates Pod and Container life-cycle events to show the order of their occurrence in a normal course of action. Apart from the order, it shows their relationship and significance.

 

Creating , Exploring & Debugging a POD

A simple POD

test-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: demo-app
  label:
    app: demo-app
spec:
  containers:
  - name: hello-echo
    image: k8s.gcr.io/echoserver:1.10
    ports:
    - containerPort: 8080

kind – Says its a POD API object.
name – Gives a unique name to these objects
labels – Allows us to give a group name to multiple instances of the Pod
image – specifies the app build IMAGE file to be used
port – Provides the port at which the app will run

After creating this file, we can use the following command to deploy it:

kubectl apply -f  test-pod.yaml

Since its simple POD , we can also conveniently deploy it using a command line as follows :

kubectl run hello-echo \
--image=k8s.gcr.io/echoserver:1.10 \
--port=8080 \
--generator=run-pod/v1 

 

Deploy the Pod

Lets deploy it using the command line on a minikube environment and explore:

$ kubectl run hello-echo --image=k8s.gcr.io/echoserver:1.10 --port=8080 --generator=run-pod/v1 
pod/hello-echo created

$ kubectl get pod -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
hello-echo   1/1     Running   0          48s   160.74.10.26   minikube   <none>           <none>

As we see, the Pod is running on the minikube Node with its virtual IP 160.74.10.26 .

Inside the Pod,we can access the application using localhost or the Pod’s IP. It is to be noted that, there can be multiple Pods on a Node, the localhost inside a Pod refers to the Pod IP , not to the Node’s ip.

 

exec : Login to container workspace & access the application

As we can not access this IP from outside,let us login to the container and try accessing the application.

#Command to login to the container workspace
$ kubectl exec -it hello-echo -- /bin/bash
root@hello-echo:/#

#Access the application inside the cluster using localhost or  pod ip
root@hello-echo:/# curl http://localhost:8080 | head -4
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   404    0   404    0     0  28230      0 --:--:-- --:--:-- --:--:-- 28857

Hostname: hello-echo

 

Logs : Explore the container logs

Here we are accessing the logs using only the Pod name. If there multiple containers, we can specify the container name after the pod name.

$ kubectl logs hello-echo
Generating self-signed cert
Generating a 2048 bit RSA private key
writing new private key to '/certs/privateKey.key'
-----
Starting nginx
127.0.0.1 - - [07/Jul/2020:07:13:51 +0000] "GET / HTTP/1.1" 200 416 "-" "curl/7.47.0"
127.0.0.1 - - [07/Jul/2020:07:15:17 +0000] "GET / HTTP/1.1" 200 416 "-" "curl/7.47.0"

 

Get : Explore a detailed runtime Pod state and status history

The ‘get’ command using ‘-o yaml’ provides the important information about the selected object as stored in the system.

We can explore the detailed runtime Pod status as below:

$ kubectl get pod hello-echo -o yaml 
-----
  kind: Pod
  metadata:
    creationTimestamp: "2020-07-07T07:10:29Z"
    labels:
      run: hello-echo
    name: hello-echo
    namespace: default
   ---------
  spec:
    containers:
    - image: k8s.gcr.io/echoserver:1.10
      imagePullPolicy: IfNotPresent
      name: hello-echo      
      -------

Status part in the same YAML output shows the status history of the Pod. The latest container status is also shown at the end.

status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2020-07-30T15:13:05Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2020-07-30T15:13:05Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2020-07-30T15:12:56Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2020-07-30T15:12:56Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - image: k8s.gcr.io/echoserver:1.10
    name: hello-echo
    ready: true
    started: true
    state:
      running:
        startedAt: "2020-07-30T15:13:04Z"

 

Describe : Provides a more formatted Pod status & associate events

The describe provides a more concise and formatted Pod status information and the list associated event.

#Lines has been removed from the output for clarity
$ kubectl describe pod hello-echo | less
Name:         hello-echo
Namespace:    default
Node:         minikube/160.74.10.26
Labels:       run=hello-echo
Status:       Running
IP:           160.74.10.26
Containers:
  hello-echo:
    Container ID:   docker://7507054f5a3f34c60d080323e5f1f0c2f9b8c588e85a423e51f31b383bb011f3
    Image:          k8s.gcr.io/echoserver:1.10
    Port:           8080/TCP
    State:          Running

QoS Class:       BestEffort

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  45m   default-scheduler  Successfully assigned default/hello-echo to minikube
  Normal  Pulled     45m   kubelet, minikube  Container image "k8s.gcr.io/echoserver:1.10" already present on machine
  Normal  Created    45m   kubelet, minikube  Created container hello-echo
  Normal  Started    45m   kubelet, minikube  Started container hello-echo

 

Delete the POD
$ kubectl delete pod hello-echo
pod "hello-echo" deleted

 

Conclusion

A Pod API object creates a single instance of a Pod. Creation and a deletion of each instance needs to be done manually.

The API objects like ReplicaSet, Deployment, Job, StatefulSets etc add features to automate the scaling, version upgrades of the Pod through configuration in the API objects. These API object use the Pod specification as a template to create the Pod instances.

The above paragraph just says, never use a Pod for deploying your application. Choose an appropriate Deployment API object to simplify your deployment.