Kubernetes is the industry-standard orchestration system for running containerized applications at scale. This article walks through the three core primitives every beginner needs to know: Pods (the smallest deployable unit), Deployments (declarative updates and scaling), and Services (stable networking). You’ll see minimal manifests and the kubectl commands you need to experiment locally.
What is a Pod?
A Pod is the smallest unit that Kubernetes creates and schedules. It represents one or more containers that share the same network namespace (IP) and storage volumes. In most cases you don’t deploy pods directly for production — you use higher-level controllers (Deployments, StatefulSets) — but it’s important to understand the shape and anatomy of a Pod.
Example: a single-container Pod running nginx:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
Notes:
- Labels (app: nginx) are key/value pairs used by selectors.
- Pods are ephemeral: if a Pod dies, Kubernetes can recreate it only if a controller (like a Deployment) expects it.
Deployments: Declarative updates and scaling
Deployments manage ReplicaSets, which in turn manage Pod replicas. Use Deployments for stateless apps: they provide rolling updates, rollbacks, and scaling.
Example Deployment manifest (3 replicas):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
Key behaviors:
- Rolling update: change the image and kubernetes replaces pods incrementally.
- Rollback: kubectl rollout undo deployment/nginx-deployment.
- Scaling: kubectl scale deployment nginx-deployment –replicas=5 or use Horizontal Pod Autoscaler (HPA).
Services: Networking for Pods
Pods get ephemeral IPs. A Service provides a stable network endpoint (ClusterIP) and forwards traffic to matching Pod backends using selectors.
Common Service types:
- ClusterIP (default): internal cluster-only service.
- NodePort: exposes service on each node’s port (useful for dev).
- LoadBalancer: provisions an external load balancer in supported clouds.
Example: ClusterIP service exposing the nginx deployment:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80 # service port
targetPort: 80 # container port
type: ClusterIP
To expose it outside the cluster (dev):
# create a NodePort service
kubectl expose deployment/nginx-deployment --type=NodePort --port=80
# forward a local port to a pod (dev/test)
kubectl port-forward svc/nginx-service 8080:80
How selectors and endpoints work
A Service’s selector (app: nginx) matches Pod labels. Kubernetes creates Endpoints objects that list Pod IPs. If no pods match, the Service has no endpoints and traffic returns connection errors.
Common kubectl commands
# apply manifests
kubectl apply -f deployment.yaml
# check resources
kubectl get pods
kubectl get deployments
kubectl get svc
# inspect details
kubectl describe pod <pod-name>
kubectl logs <pod-name> -c <container-name>
# scale
kubectl scale deployment/nginx-deployment --replicas=5
# rollout status and rollback
kubectl rollout status deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment
Putting it all together: a simple workflow
- Build and push an image to a registry (DockerHub, GitHub Container Registry). 2. Create a Deployment manifest that references the image. 3. Apply the Deployment: kubectl apply -f deployment.yaml. 4. Expose the Deployment with a Service. 5. Validate with kubectl get pods and port-forward or curl the Service. 6. To update: change the image tag and kubectl apply — watch rolling update with kubectl rollout status.
Best practices and tips
- Prefer Deployments (or StatefulSets for stateful workloads) over standalone Pods.
- Use labels and meaningful selectors; keep a consistent label schema (app, tier, version).
- Set resource requests and limits to improve scheduling and stability.
- Add readinessProbe and livenessProbe to manage traffic routing and restarts.
- Avoid using :latest in production image tags — prefer immutable tags or digests.
- Use ConfigMaps and Secrets for configuration, not baked into the image.
- Start with a local cluster (kind, minikube, k3s) before moving to managed Kubernetes.
Troubleshooting quick checklist
- Pods CrashLoopBackOff: check logs and liveness/readiness probes.
- Service has no endpoints: verify labels/selectors match.
- Image pull errors: ensure registry credentials and image name/tag are correct.
- Scheduling issues: check node capacity and pod resource requests (kubectl describe pod).
Kubernetes has a learning curve, but mastering Pods, Deployments, and Services gives you a solid foundation. Experiment locally, iterate on manifests, and expand into ConfigMaps, Secrets, Ingress, and autoscaling as you become comfortable.
