An Introduction To Pods In Kubernetes

What is a Pod

Pods are a basic abstraction in Kubernetes. The easiest way to think of them is a compute resource – a lightweight “logical host” which your containerized applications run on.

Pods run on nodes. A node can be an actual physical or virtual machine. You can have multiple pods per node (depending on resources available to the node).

A pod can run one or many containers.

Basic Pod Topology

An application running in a pod shares network and storage resources with other applications in the same pod. Each pod has a IP address assigned to it. 2 applications running in a given pod will need to have different ports (again think of them as a logical host).

Simple architecture of a web application with a database

How To Create a Pod

Pods can be created using JSON or YAML manifests. However, in a real life scenario they are created through Controllers such as ReplicaSets, Deployments or Jobs (more on this below).

Here is how to create a pod that runs a shell script that says “Hello, World!”

apiVersion: v1
kind: Pod
metadata:
  name: helloworld-pod
  labels:
    app: helloworldpod
spec:
  containers:
  - name: hellworld-container
    image: alpine:latest
    command: ['sh', '-c', 'echo Hello, World! && sleep 3000']

Save the above code as hello_world-pod.yaml, make sure your Kubernetes cluster is running and context is set for kubectl. Then run:

kubectl create -f hello_world-pod.yaml

You can check to see if the pod started:

kubectl get pods

If all worked well, you should see something like:

You can see the output of the application:

kubectl logs helloworld-pod

Let us talk a bit about what are the various components of the pod YAML for the “helloworld-pod”

Metadata

The metadata: section of the YAML has values such as Name (of the pod), Labels (more on Pod labels later)

Spec

The spec: section has configuration around the container(s) that will run in the Pod such as the Container image, ports the container runs on, protocols such as TCP or UDP. For a more comprehensive reference, please see https://kubernetes.io/docs/reference/

We wanted to illustrate how to manually create and start a pod which we just did. However, as mentioned above, pods should be run by Controllers. So let us discuss pod controllers briefly (we will have a more comprehensive post on Controllers very soon).

Pod Controllers

A desired running state of the cluster is created and it is the job of Kubernetes to ensure the state is functioning and available for users. The basic Pod definition (called a Pod Template) goes in a ReplicaSet. The ReplicationController ensures the number of pods described in the ReplicaSet are up and running.

In a ReplicaSet, the defintion of Pod is described in Pod Template.

Pod Templates

Below, we have shown how to create a ReplicaSet for the Hello World app described earlier.

We are asking Kubernetes to ensure there are 3 “replicas” of the Pod running for the application which is described in the template: section. That is the Pod Template. As you can see, it is very similar to the Pod YAML we had created earlier

Pod YAML Example

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: hwapp
  labels:
    app: helloworldapp
    tier: main
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: helloworldapp
  template:
    metadata:
      labels:
        tier: helloworldapp
    spec:
      containers:
      - name: helloworld-container
        image: alpine:latest
        command: ['sh', '-c', 'echo Hello, World! && sleep 3000']

Save the ReplicaSet code above as hello_world-rs.yaml and then create it with:

kubectl apply -f hello_world-rs.yaml

You should see something like:

Helpful Commands

Here are some commands for basic operations on Pods:

Create a Pod from a YAML spec

kubectl create -f <filename>

See the status of Pods in your cluster

kubectl get pods

Output a YAML file of a Pod in your cluster (this includes metadata, spec and status)

kubectl get pod <pod_name> -o yaml

See any application logs available in a given pod.

kubectl logs <pod_name>

See any application logs available in a given pod for a specific container (assuming multiple containers per pod)

kubectl logs <pod_name> -c <container_name>

Stop and delete a pod from the cluster

kubectl delete pod <pod_name>

Set up a port map so you can access an application from an external host (to the pod). This is usually done using Ingress but useful for quick testing.

kubectl port-forward <pod_name> port:port