K8s by Example: Services (ClusterIP)
| A Service provides a stable IP and DNS name for accessing Pods. Pod IPs are unreliable - they change on restarts and scaling. Services solve this with a persistent endpoint. ClusterIP is the default type and is internal-only. |
| service.yaml | |
| Services use the core | |
|
| |
| service-multiport.yaml | |
| Services can expose multiple ports. Pods must have ALL labels in the selector to receive traffic. | |
| terminal | |
| Each Service gets an Endpoint object automatically. The Endpoint maintains a real-time list of Pod IPs matching the selector. | |
| terminal | |
| Watch endpoints update in real-time as Pods scale up and down. | |
| pod-env.yaml | |
| Service discovery via DNS is preferred. Every Service gets a DNS name: | |
| Cross-namespace references use | |
| Full FQDN includes | |
| terminal | |
| Kubernetes DNS resolves service names dynamically. More reliable than environment variables which are set only at Pod start. | |
| service-session-affinity.yaml | |
| Session affinity routes a client to the same Pod for a period. Useful for stateful apps. Default is | |
| terminal | |
| Service types build on each other: ClusterIP (internal) → NodePort (adds external port) → LoadBalancer (adds cloud LB). | |
| terminal | |
| Debug Service routing with kubectl. Check Endpoints first - if empty, your selector doesn’t match any Pods. | |
| terminal | |
| Test Service connectivity from inside the cluster with a temporary Pod. | |