Kubernetes for Beginners: Pods, Deployments and Services

DevOps 9 min readPublished 20 September 2026

Quick answer

Learn how Kubernetes Pods, Deployments and Services work together. Build a practical NGINX application and troubleshoot common errors with kubectl.

Kubernetes runs containerised applications across a group of machines called a cluster. For anyone learning Kubernetes for beginners, the three most important objects to understand first are Pods, Deployments and Services.

This guide explains their roles, shows how traffic moves between them and provides a practical NGINX lab. You will also learn the kubectl commands used to inspect and troubleshoot each object.

What problem does Kubernetes solve?

Kubernetes automates the deployment, scaling, networking and recovery of containerised applications. Instead of starting containers manually on individual servers, you describe the required state and Kubernetes continuously works to maintain it.

For example, you can tell Kubernetes that an application must always have three running copies. If a copy fails or its server becomes unavailable, Kubernetes schedules a replacement where suitable capacity exists.

A Kubernetes cluster has two main parts:

Cluster componentPurpose
Control planeStores cluster state and makes scheduling decisions
Worker nodeRuns application workloads inside Pods
API serverAccepts requests from users, tools and cluster components
SchedulerSelects a suitable node for a new Pod
Controller managerReconciles actual state with desired state
etcdStores Kubernetes configuration and state
kubeletManages Pods assigned to a worker node

Diagram in words: An administrator sends a manifest through kubectl to the API server. The scheduler chooses a worker node, and the kubelet on that node asks the container runtime to start the required containers.

Kubernetes does not normally build application images. A CI/CD system builds and pushes an image to a registry, after which Kubernetes pulls and runs it. To study how application delivery can be automated before deployment, see this practical guide to Jenkins declarative pipelines.

What is a Kubernetes Pod?

A Pod is the smallest deployable unit in Kubernetes. It contains one or more tightly related containers that share networking and can share storage volumes.

Every Pod receives an IP address inside the cluster. Containers in the same Pod share that network namespace, so they communicate with each other through localhost and must use different listening ports.

Most Pods run one main application container. Additional containers should be placed in the same Pod only when they are closely coupled to that application, such as a sidecar that processes its logs or provides a local proxy.

A simple standalone Pod manifest looks like this:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: web
spec:
  containers:
    - name: nginx
      image: nginx:1.27-alpine
      ports:
        - containerPort: 80

Save it as pod.yaml and apply it:

kubectl apply -f pod.yaml
kubectl get pods
kubectl get pod nginx-pod -o wide

Example output:

NAME        READY   STATUS    RESTARTS   AGE   IP           NODE
nginx-pod   1/1     Running   0          35s   10.244.1.8   worker-1

The READY value of 1/1 means that one of one declared containers is ready. Running means the Pod has been assigned to a node and its containers have started, although individual readiness should still be checked.

Why should you not manage application Pods directly?

Standalone Pods are useful for short tests, but they do not provide application-level replacement, scaling or controlled updates. If you delete a Pod that has no managing controller, Kubernetes does not recreate it.

Try the following command:

kubectl delete pod nginx-pod
kubectl get pods

The Pod disappears because no Deployment or other workload controller owns it. Production applications are therefore commonly managed through Deployments rather than isolated Pod manifests.

What is a Kubernetes Deployment?

A Deployment manages replicated application Pods and supports scaling, rolling updates and rollback. You specify a desired state, and the Deployment controller creates a ReplicaSet that maintains the requested number of Pods.

Diagram in words: A Deployment owns a ReplicaSet. The ReplicaSet owns three Pods, and each Pod runs one NGINX container. If one Pod disappears, the ReplicaSet creates another to return to three replicas.

Create a file named deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 50m
              memory: 32Mi
            limits:
              cpu: 200m
              memory: 128Mi

Apply and inspect it:

kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get replicasets
kubectl get pods -l app=web -o wide

The selector under spec.selector.matchLabels must match the labels in spec.template.metadata.labels. The Deployment uses these labels to identify the Pods it manages.

Resource requests help the scheduler choose a node with sufficient capacity. Limits restrict how much CPU or memory a container can use. If a container exceeds its memory limit, it may be terminated with an OOMKilled reason.

How does a Deployment recover a failed Pod?

A Deployment restores the declared replica count through its ReplicaSet. Deleting one managed Pod demonstrates this reconciliation process without affecting the desired state.

Run:

kubectl get pods -l app=web
kubectl delete pod <one-pod-name>
kubectl get pods -l app=web -w

You should see a replacement Pod being created. The replacement normally receives a different name and IP address, which is one reason clients should not connect directly to Pod IPs.

How do scaling and rolling updates work?

Scaling changes the desired number of replicas, while a rolling update gradually replaces old Pods with new ones. This allows an application image to be updated without deleting every existing Pod at once.

Scale the Deployment:

kubectl scale deployment web-deployment --replicas=5
kubectl get pods -l app=web

Update its image and watch the rollout:

kubectl set image deployment/web-deployment nginx=nginx:1.27.4-alpine
kubectl rollout status deployment/web-deployment
kubectl rollout history deployment/web-deployment

For production releases, prefer an immutable image digest or a versioning policy that prevents a tag from unexpectedly pointing to different content.

If an update fails, return to the previous revision:

kubectl rollout undo deployment/web-deployment
kubectl rollout status deployment/web-deployment

These operations are part of a broader DevOps workflow involving source control, image registries, CI/CD, infrastructure and monitoring. The AWS DevOps course covers how these tools work together in practical cloud environments.

What is a Kubernetes Service?

A Service gives a stable network endpoint to a changing set of Pods. It selects Pods by label and sends traffic to ready endpoints even when individual Pod names and IP addresses change.

Services are important because Pods are replaceable. A replacement Pod can receive a new IP address, but the Service name and virtual cluster IP remain stable for clients.

Create service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

Apply and inspect it:

kubectl apply -f service.yaml
kubectl get services
kubectl describe service web-service
kubectl get endpointslices -l kubernetes.io/service-name=web-service

In this example, port: 80 is the port exposed by the Service. targetPort: 80 is the port to which traffic is sent on the selected Pods.

The Service selector app: web matches the labels assigned by the Deployment. Kubernetes represents the selected backends through EndpointSlice objects, while the cluster network implementation handles traffic forwarding.

Which Kubernetes Service type should you use?

Use ClusterIP for communication that must remain inside the cluster. NodePort and LoadBalancer provide forms of external access, while ExternalName creates a DNS alias for an external name.

Service typeTypical useExternal access
ClusterIPInternal application or APINo direct external access
NodePortLab access through a node address and portYes
LoadBalancerCloud load balancer integrationYes
ExternalNameDNS alias to an external hostnameDepends on destination

A NodePort normally allocates a port from the default range 30000-32767, although a cluster administrator can configure a different range. A LoadBalancer Service asks a supported cloud integration to provision or attach an external load balancer; it does not guarantee that every local cluster can create one.

On Amazon EKS, a suitable AWS controller and configuration may provision AWS load-balancing resources for Kubernetes workloads. Beginners who need deeper knowledge of EC2, IAM, VPC design and managed AWS services can also review the AWS Solutions Architect course.

How do Pods, Deployments and Services work together?

The Deployment creates and replaces labelled Pods, while the Service discovers those Pods through its selector. Clients connect to the stable Service address rather than tracking temporary Pod IP addresses.

The complete traffic path can be described as follows:

Client Pod
   |
   | Request to web-service:80
   v
ClusterIP Service
   |
   | Selects ready endpoints with label app=web
   v
Pod A:80   Pod B:80   Pod C:80

Inside the same namespace, another Pod can use the short DNS name web-service. The fully qualified cluster DNS name is commonly:

web-service.default.svc.cluster.local

Test the Service from a temporary curl Pod:

kubectl run curl-test --rm -it --restart=Never \
  --image=curlimages/curl -- http://web-service

You should receive the default NGINX HTML response. If your terminal does not allocate interactively, start the temporary Pod separately and inspect its logs.

You can also test from your local machine with port forwarding:

kubectl port-forward service/web-service 8080:80

Open http://localhost:8080 in a browser or run:

curl http://localhost:8080

Port forwarding is useful for local testing, but it is not a production exposure method.

How do you run this beginner Kubernetes lab?

Use a working Kubernetes cluster with kubectl configured to access it. Minikube, kind or a managed cluster can support this lab, although installation steps differ between operating systems and environments.

First confirm the active context and node status:

kubectl config current-context
kubectl cluster-info
kubectl get nodes

Then apply the Deployment and Service:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl get all

A healthy result should show the Deployment with its desired replicas available, running Pods, a ReplicaSet and the web-service ClusterIP. Test the Service from a temporary Pod before changing it to an externally accessible type.

Clean up the resources when finished:

kubectl delete -f service.yaml
kubectl delete -f deployment.yaml

How do you troubleshoot common Kubernetes errors?

Start by checking object status, events and container logs rather than immediately deleting resources. Kubernetes usually reports whether the problem involves scheduling, image retrieval, startup, health checks or Service selection.

Pod remains Pending

A Pending Pod has not completed scheduling or container setup. Check the detailed event messages:

kubectl describe pod <pod-name>
kubectl get events --sort-by=.metadata.creationTimestamp

Look for insufficient CPU or memory, node selectors that match no node, unbound persistent volume claims or node taints that the Pod does not tolerate.

Pod shows ImagePullBackOff

This state means Kubernetes cannot pull the container image and is retrying with increasing delays. Verify the repository, tag, registry authentication and node connectivity.

kubectl describe pod <pod-name>
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].image}'

For a private registry, confirm that the correct image pull secret exists and is referenced under spec.imagePullSecrets.

Pod shows CrashLoopBackOff

CrashLoopBackOff means a container repeatedly starts and exits. Inspect current and previous logs, then check the command, arguments, environment variables and application configuration.

kubectl logs <pod-name>
kubectl logs <pod-name> --previous
kubectl describe pod <pod-name>

The --previous option is especially useful after a container has restarted.

Service has no endpoints

A Service with no endpoints usually has a selector that does not match any ready Pods. Compare the Service selector with the actual Pod labels.

kubectl get service web-service -o yaml
kubectl get pods --show-labels
kubectl get endpointslices -l kubernetes.io/service-name=web-service

If the Service selects app: web but the Pods use app: website, correct one side so the labels match. Also check readiness probes because unready Pods are normally not included as ready Service endpoints.

Application is unreachable through the Service

Confirm that the application listens on the expected interface and port. Then test Pod access directly from within the cluster before testing the Service name.

kubectl get pods -l app=web -o wide
kubectl exec -it <pod-name> -- wget -qO- http://127.0.0.1:80
kubectl describe service web-service

Also verify targetPort, NetworkPolicies and cluster DNS. A correct Service cannot deliver traffic if the application is listening on a different port or only the wrong interface.

Frequently asked questions

Is a Pod the same as a container?

No. A Pod is a Kubernetes object that can contain one or more containers. Containers in one Pod share the Pod IP address and can share attached volumes.

What happens if a Deployment Pod fails?

The ReplicaSet controlled by the Deployment creates a replacement to restore the declared replica count. The new Pod may run on another node and normally receives a different name and IP address.

Does a Service create Pods?

No. A Service only provides discovery and network access to matching Pods. A Deployment, StatefulSet, DaemonSet, Job or another workload controller is responsible for creating Pods.

Is Kubernetes required for every container application?

No. A small application may be simpler to run with a basic container service or directly on a virtual machine. Kubernetes becomes useful when teams need scheduling, self-healing, service discovery, scaling and controlled releases across multiple workloads.

Should beginners learn Docker before Kubernetes?

Beginners should understand container images, registries, ports, environment variables and volumes before learning Kubernetes. This foundation makes Pod specifications and image-related errors easier to understand.

Summary

Pods run one or more closely related containers, Deployments maintain replicated Pods and manage updates, and Services provide stable access to changing Pod endpoints. Together, these objects form the foundation of many stateless Kubernetes applications.

Practise creating manifests, checking labels, viewing events and reading logs instead of memorising definitions alone. To build these skills within a broader cloud automation workflow, enquire about AWS DevOps course batch details.

*Reviewed by Network Rhinos cloud and DevOps trainers.*

Frequently asked questions

Is a Pod the same as a container?

No. A Pod is a Kubernetes object that can contain one or more containers. Containers in the same Pod share the Pod network and can share storage volumes.

What happens if a Pod managed by a Deployment fails?

The Deployment's ReplicaSet creates a replacement Pod to restore the required replica count. The replacement can receive a different name, IP address and worker node.

Does a Kubernetes Service create Pods?

No. A Service provides a stable network endpoint for matching Pods. Workload controllers such as Deployments, StatefulSets and DaemonSets create and manage Pods.

What is the difference between ClusterIP and NodePort?

ClusterIP exposes a Service only inside the cluster. NodePort also opens a port on each node so the Service can be reached through a node address and the allocated port.

Is Kubernetes required for every container application?

No. Simple applications may be easier to operate on a basic container platform or virtual machine. Kubernetes is useful when workloads require scheduling, self-healing, service discovery, scaling and controlled updates.

Should beginners learn Docker before Kubernetes?

Beginners should first understand container images, registries, ports, environment variables and volumes. This knowledge makes Kubernetes Pod specifications and container errors easier to understand.

Related articles

Train with Network Rhinos

Hands-on CCNA, CCNP, AWS, Azure, DevOps and cybersecurity training in Chennai & Bangalore, with placement support. Talk to our team or attend a free demo class.