arundhaj

all that is technology

Kubernetes Pods Explained: Pod Manifest, kubectl logs and describe

 

If you are starting with Kubernetes, the Pod is the first thing to understand. Every container you run on Kubernetes runs inside a Pod. Deployments, Jobs, and StatefulSets all create Pods for you. In this post we'll cover what a Pod is, how to write a Pod manifest, and how to debug Pods with kubectl logs and kubectl describe.

What is a Pod?

A Pod is the smallest deployable unit in Kubernetes. Kubernetes doesn't run containers directly. It runs Pods, and each Pod wraps one or more containers.

All containers in a Pod:

  • are scheduled together on the same node
  • share the same network namespace, so they share one IP address and can reach each other on localhost
  • can share volumes to exchange files

Pods are also ephemeral. If a Pod dies or its node fails, Kubernetes doesn't bring that same Pod back. A controller such as a Deployment creates a new Pod with a new name and a new IP.

Create a Pod quickly with kubectl run

The fastest way to start a Pod is the imperative kubectl run command.

$ kubectl run nginx --image=nginx:1.27
pod/nginx created

$ kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          8s

Add -o wide to see the Pod's IP address and the node it is running on.

$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          20s   10.244.0.12  minikube   <none>           <none>

Writing a Pod manifest

For anything beyond a quick test, describe the Pod in a YAML manifest. Here is pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.27
      ports:
        - containerPort: 80
      resources:
        requests:
          cpu: 100m
          memory: 64Mi
        limits:
          cpu: 250m
          memory: 128Mi

The four top-level fields appear in almost every Kubernetes manifest:

  • apiVersion — the API group and version. Pods are in the core v1 API.
  • kind — the type of object, here Pod.
  • metadata — the name, namespace, and labels. Services and Deployments use labels to find Pods.
  • spec — the desired state: the list of containers, their images, ports, and resources.

Apply the manifest and check the Pod:

$ kubectl apply -f pod.yaml
pod/web created

$ kubectl get pod web
NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   0          5s

Tip: You don't have to write manifests from scratch. Let kubectl generate one for you:

$ kubectl run web --image=nginx:1.27 --dry-run=client -o yaml > pod.yaml

To test the Pod from your machine without creating a Service, forward a local port to it:

$ kubectl port-forward pod/web 8080:80
Forwarding from 127.0.0.1:8080 -> 80

Now open http://localhost:8080 in your browser.

Viewing Pod logs with kubectl logs

kubectl logs shows what a container wrote to stdout and stderr. It is the first place to look when an app misbehaves.

# Logs from a single-container Pod
$ kubectl logs web

# Stream logs live (like tail -f)
$ kubectl logs -f web

# Only the last 50 lines, or the last 10 minutes
$ kubectl logs web --tail=50
$ kubectl logs web --since=10m

If a container keeps crashing, the current logs may be empty because the container just restarted. Use --previous to see logs from the instance that crashed:

$ kubectl logs web --previous

Inspecting Pods with kubectl describe

kubectl describe shows the Pod's full details: which node it runs on, its IP, the state of each container, how many times each has restarted, volumes, and most importantly the Events at the bottom.

$ kubectl describe pod web
Name:             web
Namespace:        default
Node:             minikube/192.168.49.2
Labels:           app=web
Status:           Running
IP:               10.244.0.15
Containers:
  nginx:
    Image:          nginx:1.27
    Port:           80/TCP
    State:          Running
      Started:      Tue, 27 Oct 2026 11:02:41 +0530
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     250m
      memory:  128Mi
    Requests:
      cpu:     100m
      memory:  64Mi
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  30s   default-scheduler  Successfully assigned default/web to minikube
  Normal  Pulling    29s   kubelet            Pulling image "nginx:1.27"
  Normal  Pulled     25s   kubelet            Successfully pulled image "nginx:1.27"
  Normal  Created    25s   kubelet            Created container nginx
  Normal  Started    25s   kubelet            Started container nginx

The Events section shows each step Kubernetes took to start your Pod. When something goes wrong, the reason almost always appears here.

Delete a Pod

$ kubectl delete pod web
pod "web" deleted

Why you rarely create Pods directly

A Pod you create by hand is not recreated if it is deleted or its node fails. In real applications you create a Deployment, which keeps the desired number of Pod replicas running and handles rolling updates. Still, everything in this post applies there too: the spec you wrote above is exactly what goes into a Deployment's Pod template, and kubectl logs and kubectl describe are how you debug the Pods a Deployment creates.

Pods run inside a namespace. If you haven't read it yet, see Kubernetes Namespace Explained with Examples.

Comments