Services Explained

Pods in Kubernetes are ephemeral — they are created and destroyed by Deployments, and each new Pod gets a new IP address. This makes direct Pod-to-Pod communication unreliable. A Service is a stable network endpoint (fixed IP and DNS name) that load-balances traffic across a set of Pods, identified by their labels. Services abstract the Pod churn: whether 1 pod or 100 pods are running behind a Service, the Service IP stays constant.

Why Services?

Without Service (pod IPs change):
  frontend → 10.244.1.15 (backend pod, crashes) → connection fails
  frontend → 10.244.1.23 (new backend pod)      → must update manually

With Service (stable endpoint):
  frontend → backend-service:8080 (always resolves to healthy pods)
             ClusterIP: 10.96.45.200 (never changes)
             kube-proxy load-balances to: 10.244.1.15, 10.244.1.23, 10.244.1.31

Service types

TypeAccessible fromUse case
ClusterIP (default)Inside cluster onlyInternal service-to-service communication
NodePortOutside cluster via node IP + portDevelopment, testing, on-prem without load balancer
LoadBalancerPublic via cloud load balancerProduction services on cloud (AWS/GCP/Azure)
ExternalNameDNS alias to external serviceMapping external services into cluster DNS

ClusterIP service

nano backend-service.yaml

backend-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: backend-service
spec:
  selector:
    app: backend     # Routes traffic to pods with this label
  ports:
    - protocol: TCP
      port: 8080       # Port the Service listens on
      targetPort: 8080 # Port the container actually uses
  type: ClusterIP      # Internal only (default)
kubectl apply -f backend-service.yaml
kubectl get service backend-service

kubectl get service output

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
backend-service   ClusterIP   10.96.45.200            8080/TCP   30s
# From any pod in the cluster, reach the service by DNS name:
# backend-service:8080          (same namespace)
# backend-service.default:8080  (explicit namespace)
# backend-service.default.svc.cluster.local:8080  (fully qualified)

# Test from another pod:
kubectl run test-pod --rm -it --image=alpine -- wget -qO- http://backend-service:8080

NodePort and LoadBalancer

nano frontend-service.yaml

frontend-service.yaml — NodePort type

apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  selector:
    app: frontend
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080    # Fixed external port on every node (range: 30000-32767)
  type: NodePort
kubectl apply -f frontend-service.yaml

# Access the service from outside the cluster:
# http://ANY_NODE_IP:30080
# (Traffic hits any node on port 30080, kube-proxy routes to correct pods)

# For cloud deployments — LoadBalancer type provisions a cloud LB automatically:
# type: LoadBalancer
# → cloud controller assigns EXTERNAL-IP within 1-2 minutes
kubectl get service frontend-service -w    # Watch EXTERNAL-IP appear

LoadBalancer service after IP assignment

NAME               TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
frontend-service   LoadBalancer   10.96.78.100   34.82.45.123   80:31200/TCP   90s

Conclusion

Services are the networking glue of Kubernetes. Use ClusterIP for all internal service-to-service communication (database services, backend APIs). Use NodePort for quick external access during development. Use LoadBalancer for production services on cloud platforms where the cloud provider provisions a load balancer automatically. On-premises clusters without cloud load balancers should use MetalLB (a software load balancer) or Ingress controllers to expose services externally without NodePort.

FAQ

Why should administrators understand Services Explained?+

Because this topic affects planning decisions, server lifecycle, compatibility, support expectations, or how you reason about Ubuntu systems before making operational changes.

Do I need a lab for this topic?+

A lab is useful for checking commands and seeing the concept on a real Ubuntu machine, but the main value is understanding the decision, tradeoff, or system behavior clearly.

How should I use this knowledge in production?+

Use it to make better choices, document why those choices were made, and avoid rushed changes that ignore support windows, compatibility, stability, or operational risk.

Need help with Ubuntu administration?

Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.

Hire Me for Support