devops

Kubernetes — Networking & Services

Tutorial-style: pod IPs, why Services exist, ClusterIP vs NodePort vs LoadBalancer, verify with describe/endpoints, port-forward


What you will learn

  1. Why pod IPs are a bad contract between components.
  2. How a Service fixes that with a stable VIP + DNS name.
  3. When to use ClusterIP, NodePort, and LoadBalancer.
  4. How to prove traffic flows with kubectl describe, Endpoints, and port-forward.

Lesson A — Pod IPs change; Services do not

Each Pod gets an address on the cluster pod network (often 10.244.x.x or similar). When the pod restarts, that IP changes. If your front-end hard-codes the back-end pod IP, it will break after the next restart.

Node IP vs pod IP

Rule for revision: apps talk to Services (or Ingress), not to raw pod IPs.

On multi-node clusters, a CNI plugin (Calico, Cilium, Flannel, …) gives each node a slice of pod IPs and routes traffic so every pod can reach every other pod without NAT breaking the model.


Lesson B — What a Service does

A Service is its own object. It has:

  • Selectors — labels that pick which Pods are backends.
  • Ports — usually port (Service) → targetPort (container).
  • Type — how that Service is reached.

NodePort, ClusterIP, LoadBalancer

TypeWho can reach itTypical use
ClusterIPOnly inside the clusterInternal APIs, databases, Redis, “backend” tiers.
NodePortFrom outside using NodeIP:nodePort (high port range)Labs, quick demos, bare metal without a cloud LB.
LoadBalancerInternet via cloud load balancer (when supported)Public web apps on EKS/GKE/AKS.

Lesson C — ClusterIP (internal only)

C.1 — Example manifest

Save as backend-service.yaml (labels must match your pods):

apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
selector:
app: votes
tier: backend

C.2 — Apply and inspect

Terminal window
kubectl apply -f backend-service.yaml
kubectl get svc backend
kubectl describe svc backend
kubectl get endpoints backend -o wide

Success checklist:

  • Endpoints lists pod IPs and ports.
  • If Endpoints is empty, either no pods match the selector, or pods are not Ready.

C.3 — DNS name (inside the cluster)

From another pod in the same namespace:

http://backend
http://backend.default.svc.cluster.local

Lesson D — NodePort (reach the app from outside)

D.1 — Example manifest

Save as myapp-nodeport.yaml:

apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: NodePort
selector:
app: myapp
ports:
- port: 80
targetPort: 80
nodePort: 30008

nodePort must stay in 30000–32767 if you set it yourself; omit it and Kubernetes picks one for you.

D.2 — Apply

Terminal window
kubectl apply -f myapp-nodeport.yaml
kubectl get svc myapp

D.3 — How to open it (depends on your cluster)

  • Minikube: minikube service myapp --url
  • Kind / Docker Desktop: often localhost with port-forward (next lesson).
  • Cloud / real nodes: http://NODE_EXTERNAL_IP:nodePort

Lesson E — LoadBalancer (one line)

On supported clouds, type: LoadBalancer allocates an external IP or hostname. Until EXTERNAL-IP leaves <pending>, wait and re-run kubectl get svc.


Lesson F — Debug without exposing the app

From your laptop, tunnel to a ClusterIP Service:

Terminal window
kubectl port-forward svc/backend 8080:80

Then open http://localhost:8080 in a browser or curl it.


Lesson G — Command cheat sheet for “it’s broken”

Terminal window
kubectl get pods -l app=myapp -o wide
kubectl get svc
kubectl describe svc myapp
kubectl get endpoints myapp -o yaml

What’s next

  • Full stack example: Example voting app note (Redis + DB + worker + two UIs).
  • Production depth: operational Kubernetes note (Ingress, probes, limits, failures).