1. Why Do We Need a Kubernetes Service?
In traditional deployments, applications are accessed using IP address + Port. However, in Kubernetes:
- Pods are ephemeral — they can be destroyed and recreated at any time.
- Each new Pod gets a new IP address.
- Kubernetes doesn’t assign IPs to Pods until they’re scheduled, so there’s no way to hardcode IPs.
- You usually deploy multiple replicas of the same app. Accessing them individually is not practical.
Problem:
How do we access a group of Pods (that may come and go) through a stable IP and Port?
Solution: Kubernetes Service
A Kubernetes Service provides a stable network endpoint (Cluster IP, DNS name, and Port) that routes traffic to a dynamic set of Pods. It ensures:
- Load balancing across Pods
- Service discovery within the cluster
- Loose coupling between clients and Pods
2. How Services Work Internally
- Services select Pods using labels (like
app: nginx). - When a Service is created, Kubernetes also creates an Endpoints object with the same name.
- The Endpoints object holds the Pod IPs that match the selector.
- Kube-proxy watches for Services and Endpoints, and sets up iptables or IPVS rules for routing traffic.
3. How to Define a Service with YAML
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 8081
targetPort: 80
Explanation of Fields:
| Field | Description |
|---|---|
apiVersion | Kubernetes API version used (for Services: v1) |
kind | Type of resource: Service |
metadata | Standard metadata including name |
spec.selector | Label selector used to find matching Pods |
spec.ports | List of ports exposed by the service |
port | Port on which service is exposed |
targetPort | Port on the container where the traffic will be forwarded |
protocol | Usually TCP, but can also be UDP |
Tip: Use the same port number for
portandtargetPortto avoid confusion.
4. Step-by-Step: Create a Deployment First
Before creating a Service, ensure Pods are running. For example:
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.14.2
ports:
- containerPort: 80
Apply the Deployment:
kubectl apply -f nginx-deployment.yaml
Check Pods and Labels:
kubectl get pods --show-labels
5. Apply the Service Manifest
Create the Service
kubectl apply -f nginx-service.yaml
Verify the Service
kubectl get services
Sample Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-service ClusterIP 10.105.224.36 <none> 8081/TCP 112s
6. Behind the Scenes: Endpoints Resource
When the Service is created, Kubernetes also creates an Endpoints resource:
kubectl get endpoints
Sample Output:
NAME ENDPOINTS AGE nginx-service 10.1.1.68:80,10.1.1.69:80,10.1.1.70:80 19m
This shows that the Service routes traffic to these Pods with label app=nginx.
7. Test the Service (Internal Access)
Enter into a Pod:
kubectl exec -it <nginx-pod-name> -- /bin/bash
Install curl and test:
apt-get update apt-get install curl curl http://nginx-service:8081
Or:
curl http://10.105.224.36:8081
8. Test the Service (External Access using Port Forwarding)
If you want to test the Service from your local computer:
kubectl port-forward service/nginx-service 8081:8081
Then, open your browser and go to:
http://localhost:8081
This forwards traffic from your local machine’s port 8081 to the service port inside the cluster.
9. Create Service via kubectl expose Command
Instead of YAML, you can use the imperative command:
kubectl expose deployment nginx-deployment --name=nginx-service --port=8081 --target-port=80
This does the same thing — it creates a Service targeting Pods managed by the Deployment.
10. Summary Table
| Feature | Description |
|---|---|
| Stable IP & Port | ClusterIP doesn’t change while Service exists |
| Pod Discovery | Uses label selectors to route to correct Pods |
| Load Balancing | Balances traffic across all matching Pods |
| Kube-Proxy | Handles low-level network routing |
| Endpoints | Tracks IP:Port of matching Pods |
| Port Forwarding | Lets you access Services locally |
| Multiple Ports | A Service can expose multiple ports |
| Service Types | ClusterIP, NodePort, LoadBalancer, etc. (default: ClusterIP) |
11. Key Takeaways
- Never rely on Pod IPs directly — they’re short-lived.
- A Service provides decoupling, stability, and discoverability.
- Always label your Pods appropriately so they can be discovered by Services.
- Use port-forwarding for local development and testing.
- Services are core building blocks in making a microservices architecture work in Kubernetes.
