CKA — Service Types
CKA Exam Domain
| Domain | Weight |
|---|---|
| Services & Networking | 20% |
Understanding Service types is fundamental to this domain. The CKA exam expects you to create, configure, and troubleshoot Services confidently using both YAML and imperative commands.
What Is a Service?
A Service in Kubernetes provides a stable network endpoint for a set of Pods. Since Pods are ephemeral — they get created, destroyed, and rescheduled constantly — their IP addresses change all the time. A Service solves this by giving you:
- A stable IP address (ClusterIP) that doesn’t change
- A DNS name that other Pods can use to discover the Service
- Load balancing across all matching Pods
Services use label selectors to determine which Pods receive traffic. Any Pod whose labels match the Service’s selector becomes a backend for that Service.
# The Service selects Pods with label app: web
selector:
app: web
Think of a Service as a phone number that stays the same even if the person on the other end changes.
ClusterIP
ClusterIP is the default Service type. It creates an internal IP address that is only reachable from within the cluster.
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
type: ClusterIP
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080
port: 80— The port the Service listens ontargetPort: 8080— The port on the Pod where traffic is forwarded
Imperative command:
kubectl expose deployment web --port=80 --target-port=8080 --name=web-svc
When to use: Internal microservice communication — e.g., a frontend Pod calling a backend API.
NodePort
NodePort exposes the Service on each node’s IP address at a static port in the range 30000–32767. Traffic to <NodeIP>:<NodePort> gets routed to the Service.
apiVersion: v1
kind: Service
metadata:
name: web-nodeport
spec:
type: NodePort
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080
nodePort: 30080 # Optional — Kubernetes assigns one if omitted
Imperative command:
kubectl expose deployment web --port=80 --target-port=8080 --type=NodePort --name=web-nodeport
A NodePort Service also creates a ClusterIP automatically, so it’s accessible both internally and externally.
When to use: Quick external access for development or testing. Not recommended for production.
LoadBalancer
LoadBalancer provisions an external load balancer from the cloud provider (AWS ELB, GCP LB, Azure LB). It builds on top of NodePort and ClusterIP.
apiVersion: v1
kind: Service
metadata:
name: web-lb
spec:
type: LoadBalancer
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080
When you create this Service, the cloud provider assigns an external IP or hostname. You can check it with:
kubectl get svc web-lb
The EXTERNAL-IP column shows the assigned address (it may take a minute to provision).
When to use: Exposing a Service to the internet in a cloud environment.
ExternalName
ExternalName maps a Service to an external DNS name. It doesn’t proxy traffic — it returns a CNAME record pointing to the external address.
apiVersion: v1
kind: Service
metadata:
name: external-db
spec:
type: ExternalName
externalName: db.example.com
When a Pod looks up external-db, DNS returns db.example.com. No ClusterIP is created, no proxying happens.
When to use: Pointing internal consumers to an external database or API using a Kubernetes-native DNS name.
Headless Services
A Headless Service is created by setting clusterIP: None. Instead of returning a single ClusterIP, DNS returns the individual Pod IPs directly.
apiVersion: v1
kind: Service
metadata:
name: web-headless
spec:
clusterIP: None
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 8080
DNS queries for this Service return A records for each Pod backing the Service.
When to use: StatefulSets, where each Pod needs to be individually addressable (e.g., database clusters).
Service Type Comparison
| Type | Accessibility | Use Case | Port Range |
|---|---|---|---|
| ClusterIP | Internal only | Microservice-to-microservice | Any |
| NodePort | External via <NodeIP>:<NodePort> |
Dev/test external access | 30000–32767 |
| LoadBalancer | External via cloud LB | Production internet-facing | Any |
| ExternalName | DNS alias to external | External service mapping | N/A |
| Headless | Internal, returns Pod IPs | StatefulSets, direct Pod access | Any |
Choosing the Right Service Type
Here’s a quick decision guide:
- Need internal-only access? → ClusterIP
- Need external access for testing? → NodePort
- Need production external access on cloud? → LoadBalancer
- Need to reference an external DNS name? → ExternalName
- Need individual Pod IPs (StatefulSet)? → Headless (clusterIP: None)
For the CKA exam, you’ll most commonly work with ClusterIP and NodePort. Make sure you can create both from YAML and using imperative commands.
kubectl Commands
# List all services
kubectl get svc
# List services in all namespaces
kubectl get svc -A
# Describe a specific service
kubectl describe svc web-svc
# View endpoints for a service
kubectl get endpoints web-svc
# Create a service imperatively
kubectl expose deployment web --port=80 --target-port=8080 --name=web-svc
# Create a NodePort service imperatively
kubectl expose deployment web --port=80 --target-port=8080 --type=NodePort --name=web-nodeport
# Delete a service
kubectl delete svc web-svc
Practice Questions
Q1. Create a Deployment named api with image nginx and 3 replicas. Then expose it as a ClusterIP Service on port 80.
Show Answer
kubectl create deployment api --image=nginx --replicas=3
kubectl expose deployment api --port=80 --target-port=80 --name=api-svc
Verify:
kubectl get svc api-svc
kubectl get endpoints api-svc
Q2. Create a NodePort Service for a Deployment named frontend that maps port 80 to target port 8080, with nodePort 30100.
Show Answer
apiVersion: v1
kind: Service
metadata:
name: frontend-np
spec:
type: NodePort
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 8080
nodePort: 30100
kubectl apply -f frontend-np.yaml
Q3. What is the default Service type if you don’t specify spec.type?
Show Answer
ClusterIP is the default Service type. If you omit spec.type, Kubernetes creates a ClusterIP Service.
Q4. Create a Headless Service named db-headless for Pods with label app: postgres.
Show Answer
apiVersion: v1
kind: Service
metadata:
name: db-headless
spec:
clusterIP: None
selector:
app: postgres
ports:
- protocol: TCP
port: 5432
targetPort: 5432
kubectl apply -f db-headless.yaml
Q5. What port range does NodePort use by default?
Show Answer
NodePort uses ports in the range 30000–32767 by default. You can specify a particular port in that range using nodePort in the Service spec, or let Kubernetes assign one automatically.