Kubernetes Services — Hands-On
Hands-on understanding of how Services work: ClusterIP, labels/selectors, Ingress, and service discovery via DNS.
Connecting Pods with a Service
Here is a complete end-to-end example: a Deployment whose Pods are exposed by a Service.
# full-example.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web # ← Service selects on this label
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web # ← match Pods with label app=web
ports:
- port: 80
targetPort: 80
type: ClusterIP
kubectl apply -f full-example.yaml
# Confirm pods and service are up
kubectl get pods,svc
# Test internal connectivity
kubectl run curl-test --rm -it --image=curlimages/curl -- curl http://web-service
Service Discovery via DNS
Kubernetes automatically assigns DNS entries for every Service.
# Format: <service>.<namespace>.svc.cluster.local
# From inside any pod in the same namespace:
curl http://web-service # short name works
curl http://web-service.default # with namespace
curl http://web-service.default.svc.cluster.local # fully qualified
# Cross-namespace call
curl http://payments.finance.svc.cluster.local
# Debug DNS resolution
kubectl run dns-debug --rm -it --image=busybox -- sh
# Inside:
nslookup web-service
nslookup web-service.default.svc.cluster.local
Exposing Externally with NodePort
# service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: web-nodeport
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
nodePort: 31000 # accessible at <any-node-ip>:31000
type: NodePort
kubectl apply -f service-nodeport.yaml
# minikube convenience URL
minikube service web-nodeport --url
Ingress — HTTP Routing to Multiple Services
Ingress lets you route traffic by hostname or URL path using a single external IP.
# Enable the ingress addon (minikube)
minikube addons enable ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.local
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service # route /api → api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service # route / → web-service
port:
number: 80
kubectl apply -f ingress.yaml
# Check ingress status (ADDRESS column shows external IP once assigned)
kubectl get ingress
# Test (add myapp.local to /etc/hosts pointing to minikube IP first)
minikube ip # get the IP
echo "$(minikube ip) myapp.local" | sudo tee -a /etc/hosts
curl http://myapp.local/api
curl http://myapp.local/
Port Forwarding (Local Dev)
No need to expose a service externally just to test it locally.
# Forward local port 8080 → pod port 80 (good for one-off debugging)
kubectl port-forward pod/my-pod 8080:80
# Forward via service (load-balances across pods)
kubectl port-forward service/web-service 8080:80
# Now accessible at http://localhost:8080
Service Debugging Checklist
# 1. Are pods running and Ready?
kubectl get pods -l app=web
# 2. Do pod labels match the service selector?
kubectl describe service web-service | grep -A2 Selector
kubectl get pods --show-labels
# 3. Are endpoints populated?
kubectl get endpoints web-service
# Empty endpoints = selector mismatch or pods not Ready
# 4. Can another pod reach the service?
kubectl run probe --rm -it --image=curlimages/curl -- curl http://web-service
# 5. Check events for errors
kubectl describe service web-service
Learning Outcomes
You can:
- Deploy a Service alongside a Deployment end-to-end
- Use DNS names for internal service-to-service calls
- Choose the right Service type for each access pattern
- Configure Ingress for HTTP routing on a single external IP
- Debug connectivity issues systematically
Frequently Asked Questions
What does ClusterIP mean?
ClusterIP exposes the Service internally inside the cluster on a virtual IP. It's the default Service type and the right choice for pod-to-pod communication.
What is Ingress and when should I use it instead of LoadBalancer?
Ingress routes HTTP/HTTPS traffic to multiple services based on host or path rules using a single external IP. LoadBalancer provisions one external IP per service. Use Ingress to avoid paying for multiple cloud LBs.