Pod IPs change constantly, so a Service provides a fixed virtual IP and DNS name.
It finds its backends with a label selector and load-balances across the ready ones.
Default. A virtual IP reachable only inside the cluster. Most Services.
Opens the same port (30000-32767) on every node. A building block, rarely used directly.
Asks the cloud for a real load balancer (GCP, AWS NLB/ALB, Azure LB, or MetalLB on-prem).
A pure DNS alias (CNAME) to something outside the cluster.
service.yaml
apiVersion: v1 kind: Service metadata: {name: checkout, namespace: shop} spec: type: ClusterIP selector: {app: checkout} # finds Pods by label ports: [{port: 80, targetPort: 8080}]
Session affinity
sessionAffinity: ClientIP pins a client IP to one Pod. A stopgap for legacy apps; better to move session state to Redis or a database.
Cloud cost note
A separate LoadBalancer per Service gets expensive. Put many Services behind one Ingress or Gateway.