Your containerized application runs fine locally. Now you need to take it to production across multiple servers, handle replicas, updates, and traffic. Kubernetes does it, but if you don't understand Pods, Deployments, Services, and Namespaces, you risk copying YAML from tutorials without knowing what you're doing. And when something breaks, you lose time and money.
We at Meteora Web have worked with Kubernetes on real projects for years. We've seen clients spin up clusters without environment isolation, or use Pods directly instead of Deployments, with disastrous results. This guide covers the four fundamental building blocks — Pod, Deployment, Service, Namespace — with concrete examples, working YAML, and commands you can run right now. No abstract theory: you'll learn why they are used and how to combine them in production.
Pod: The atomic unit of the cluster
A Pod is the smallest object Kubernetes manages. It holds one or more containers that share the same network namespace and storage. In practice, most Pods contain a single container. Why call it a Pod instead of a container? Because Kubernetes works at a higher abstraction level. A Pod guarantees its containers run on the same node, share localhost, and volumes. Useful for patterns like sidecars (e.g., a proxy or logger) that must be attached to the main container.
Common mistake: creating Pods directly with kubectl run. Such a Pod does not self-heal. If the node crashes, the Pod dies with it. That's why Deployments exist.
Basic Pod YAML
apiVersion: v1
kind: Pod
metadata:
name: web-pod
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Run it with kubectl apply -f pod.yaml. But don't do this in production. You need Deployments.
What you can do now: if you have a cluster, create a test Pod, inspect it with kubectl describe pod web-pod, then delete it with kubectl delete pod web-pod. You'll understand termination.
Deployment: Desired state management
A Deployment declares how many replicas of a Pod you want, which image to use, and how to update them. Kubernetes takes care of the rest: create Pods, replace them if they die, perform rolling updates with zero downtime. In our daily work, the Deployment is the starting point for any stateless application.
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.25
ports:
- containerPort: 80
replicas: 3 tells Kubernetes to always keep three Pods running. selector links the Deployment to Pods via labels. template defines the desired Pod specification.
Operational commands:
kubectl apply -f deployment.yamlkubectl get pods -wto watch statuskubectl scale deployment web-deployment --replicas=5to scale on the fly
We've seen clients manually edit existing Pods. With a Deployment, just change the image in the YAML and run kubectl apply: Kubernetes executes a rolling update, replacing one Pod at a time. Zero downtime.
Heads-up: without a Service, Pods are only reachable inside the cluster via ephemeral IPs. To expose them to the outside world you need a Service.
Service: A stable access point
Pods are born and die, changing IPs. A Service provides a stable DNS name (e.g., web-service.default.svc.cluster.local) and load-balances traffic among Pods matching the selected labels.
There are three main types:
- ClusterIP (default): accessible only inside the cluster. Good for microservice communication.
- NodePort: exposes the Service on a static port on every node. For development or small environments.
- LoadBalancer: creates an external load balancer (on cloud providers like AWS, GKE, AKS). The most common way to expose in production.
LoadBalancer Service YAML
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: LoadBalancer
selector:
app: web
ports:
- port: 80
targetPort: 80
selector: app: web tells the Service to forward traffic to all Pods with that label. port is the exposed port of the Service, targetPort is the container port.
Operational tip: after applying, check the external IP with kubectl get svc web-service. If you don't get an IP (e.g., on minikube), use minikube service web-service.
We at Meteora Web have optimized Services for high-traffic applications using session affinity and health checks. But the base is simple: without a Service, your Deployment is invisible.
Namespace: Logical multi-environment isolation
A namespace is a virtual partition of the cluster. It allows you to separate teams, environments (dev, staging, prod), or applications. Resources in one namespace do not see resources in another (unless explicit NetworkPolicy allows it).
Why it's crucial: In many inherited projects we've found all resources in the default namespace. Chaos. With namespaces you can apply resource quotas, RBAC, and network isolation per environment.
Create a namespace and deploy into it
kubectl create namespace staging
kubectl apply -f deployment.yaml -n staging
kubectl get pods -n staging
Or declaratively:
apiVersion: v1
kind: Namespace
metadata:
name: staging
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
namespace: staging
spec:
...
Useful commands:
kubectl get nslists namespaceskubectl config set-context --current --namespace=stagingchanges the default namespace for the current context
Note: namespaces do not isolate network by default. Pods can communicate across namespaces via DNS (service.namespace.svc.cluster.local). To block traffic you need NetworkPolicy — that's another spoke.
Putting it all together: a working example
Suppose you want to launch a web application in staging with 3 replicas and an external load balancer. Here's the sequence:
- Create the namespace (if it doesn't exist).
- Apply the Deployment with correct labels.
- Apply the Service of type LoadBalancer (on cloud) or NodePort (local).
- Verify Pods are Running and the Service has an endpoint.
kubectl create namespace staging
kubectl apply -f deployment.yaml -n staging
kubectl apply -f service.yaml -n staging
kubectl get all -n staging
The kubectl get all command shows Pods, Services, Deployments, and ReplicaSets in one go.
Common debugging: if the Service doesn't find Pods, check labels. kubectl get pods --show-labels -n staging shows actual labels. The Service's selector must match exactly.
Errors we often see in projects coming to us
- Using Pods directly instead of Deployments: no resilience. Node crashes, Pod gone.
- Omitting namespaces: everything in default, conflicts and confusion.
- Service with wrong selector: traffic doesn't reach Pods, but no visible error.
- Setting replicas without Resource Requests: cluster can overload nodes. Always include
resources.requestsfor CPU/memory. - Not using readiness probes: Service sends traffic to Pods that aren't ready. Add
readinessProbein the container spec.
We at Meteora Web have built CI/CD pipelines on Kubernetes for clients who previously deployed manually. The difference is staggering: from hours of downtime to transparent rolling updates. But it all starts with understanding these four objects.
In summary — what to do now
- Install kubectl and connect to a cluster (minikube for local testing, or a free cloud cluster like GKE Autopilot).
- Create your first Pod with
kubectl run nginx --image=nginxand delete it. Then create it via a Deployment YAML with 2 replicas. - Expose it with a Service of type NodePort or LoadBalancer. Verify you can reach it.
- Split into namespaces: move the Deployment into a namespace called
laband repeat the steps. - Read Pod logs with
kubectl logs -n lab deployment/web-deployment-xxxx. Understand the difference between Pod logs and Deployment logs.
This is the foundation for any Kubernetes architecture that is not monolithic and fragile. Once you master Pod, Deployment, Service, and Namespace, you can move on to Ingress, ConfigMap, Secret, PersistentVolumeClaim, and beyond. But if these four aren't solid, the rest will wobble.
Are you a business looking to bring your applications into production without hiccups? Contact us: we work with Kubernetes every day and support you on infrastructure, automation, and security.
Sponsored Protocol