Kubernetes Services

The networking abstraction that provides stable, discoverable endpoints for ephemeral Pods. Services are the bridge between dynamic workloads and reliable client access — a core topic in the CKA “Services & Networking” domain (~20%). Synthesized from CKA Day 9 — Kubernetes Services Explained.

The Problem: Pods Are Ephemeral

Every Pod receives a unique internal IP address when it starts. But when a Pod restarts, crashes, or is rescheduled, it gets a new IP. If a front-end Pod tries to reach a back-end Pod at 10.244.1.2, that address becomes invalid the moment the back-end Pod restarts.

Services solve this by:

  • Providing a stable virtual IP (ClusterIP) that never changes
  • Maintaining an Endpoints list that automatically tracks which Pods are healthy backends
  • Offering DNS resolution so clients use names (my-service) instead of IPs
  • Enabling load balancing across multiple Pod replicas

Service YAML Anatomy

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    env: demo
spec:
  type: ClusterIP        # NodePort | LoadBalancer | ExternalName
  selector:
    app: nginx           # Must match Pod labels
  ports:
    - port: 80           # Service port (cluster-internal)
      targetPort: 80     # Pod container port
      nodePort: 30001    # Only for NodePort/LoadBalancer (30000-32767)
FieldDescriptionRequired
apiVersionv1 for ServiceYes
kindService (case-sensitive)Yes
metadata.nameUnique name in namespaceYes
spec.typeClusterIP (default), NodePort, LoadBalancer, ExternalNameNo
spec.selectorLabel key-value pairs to match target PodsYes
spec.ports[].portPort exposed by the Service inside the clusterYes
spec.ports[].targetPortPort the container listens onNo (defaults to port)
spec.ports[].nodePortStatic external port (30,000–32,767)No (auto-allocated)

YAML Tip: selector uses plain key-value pairs, not matchLabels. This is a common mistake — Services use selector: {app: nginx}, while Deployments/ReplicaSets use selector: matchLabels: {app: nginx}. Source: CKA Day 9

The Three Port Concepts

Understanding the distinction between these three ports is critical for both the exam and real-world debugging:

PortRoleAudience
targetPortThe actual port the application container is listening onThe Service forwards traffic here
portThe port exposed by the Service within the clusterOther Pods and Services in the cluster
nodePortA static port opened on every node’s IP (30,000–32,767)External users and clients outside the cluster

Example: A Nginx container listens on targetPort: 80. The Service exposes port: 80 for internal clients. If type: NodePort, it also opens nodePort: 30001 on each node’s IP. External traffic hits NodeIP:30001 → Service forwards to Pod at targetPort: 80.

How Services Route Traffic

  1. The Service controller watches for Pods matching the selector
  2. Healthy matching Pods are added to the Endpoints object
  3. kube-proxy on each node programs iptables (or ipvs) rules to route traffic destined for the Service IP to one of the Endpoint IPs
  4. The selection algorithm is typically round-robin (with iptables mode using random distribution)
User/Client
    │
    ▼
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  NodePort   │────▶│   Service   │────▶│   Pod 1     │
│  30001      │     │   ClusterIP │     │ 10.244.1.2  │
└─────────────┘     └─────────────┘     ├─────────────┤
                                        │   Pod 2     │
                                        │ 10.244.1.3  │
                                        ├─────────────┤
                                        │   Pod 3     │
                                        │ 10.244.2.5  │
                                        └─────────────┘

Endpoints and EndpointSlices

Endpoints are the dynamic backend list maintained by Kubernetes:

kubectl get endpoints        # List all endpoints
kubectl get ep               # Short form
kubectl describe svc <name>  # View endpoints attached to a service

When a Pod is created, restarted, or deleted, its IP is automatically added or removed from the Endpoints object. This is why Services remain stable even as Pods churn — the virtual IP is constant, but the backend IPs are continuously refreshed.

In large clusters, Kubernetes uses EndpointSlices (introduced in v1.21, default in v1.22+) to split endpoints into smaller, more scalable chunks instead of one large Endpoints object.

Essential kubectl Commands

CommandPurpose
kubectl get svcList all Services
kubectl get serviceSame as above
kubectl describe svc <name>Detailed Service info including Endpoints
kubectl get endpointsShow backend Pod IPs for all Services
kubectl apply -f service.yamlCreate/Update from manifest
kubectl delete svc <name>Delete a Service
kubectl expose deployment <name> --port=80Imperative Service creation

Imperative Service Creation (CKA Speed Pattern)

Writing full YAML under exam pressure is slow. Use imperative commands:

# ClusterIP (default)
kubectl expose deployment nginx-deploy --port=80
 
# NodePort with specific port
kubectl expose deployment nginx-deploy --type=NodePort --port=80 --target-port=80 --node-port=30001
 
# LoadBalancer
kubectl expose deployment nginx-deploy --type=LoadBalancer --port=80

CKA Tip: Imperative commands are ~3x faster than writing YAML from scratch. Practice them for the exam. Source: CKA Day 9

Troubleshooting Services

SymptomLikely CauseFix
Service shows no EndpointsSelector labels don’t match Pod labelsCheck kubectl get pods --show-labels and align selectors
NodePort not accessible from hostKind cluster missing extraPortMappingsAdd port mapping in kind-config.yaml and recreate cluster
LoadBalancer pending external IPNo cloud provider integrationUse NodePort locally; on cloud, check CCM
Connection refused on targetPortApplication not listening on that portVerify container’s containerPort matches targetPort
Service name not resolvingCoreDNS issues or wrong namespaceUse FQDN: <service>.<namespace>.svc.cluster.local

Sources


Tags: kubernetes services clusterip nodeport loadbalancer externalname networking cka devops endpoints kube-proxy