iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Services

A Service gives a stable name and IP to a set of Pods. ClusterIP for inside-cluster traffic, NodePort for exposing on each node, LoadBalancer for cloud LBs, ExternalName for DNS aliases.

ClusterIP / NodePort / LoadBalancer / headless

EXAMPLE
# 1) ClusterIP — default. In-cluster only.
apiVersion: v1
kind: Service
metadata: { name: web }
spec:
    type: ClusterIP
    selector: { app: web }
    ports:
        - port:        80          # cluster-side port
          targetPort:  3000        # container port
          protocol:    TCP
# Reach it as web.namespace.svc.cluster.local:80

# 2) NodePort — opens the same port on every node
apiVersion: v1
kind: Service
metadata: { name: web }
spec:
    type: NodePort
    selector: { app: web }
    ports:
        - port:        80
          targetPort:  3000
          nodePort:    30080        # 30000-32767 range
# Reach it as <ANY_NODE_IP>:30080

# 3) LoadBalancer — provisions a cloud LB (AWS NLB/ALB, GCP, Azure)
apiVersion: v1
kind: Service
metadata:
    name: web
    annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
    type: LoadBalancer
    selector: { app: web }
    ports:
        - port:        80
          targetPort:  3000
# kubectl get svc → EXTERNAL-IP column

# 4) ExternalName — DNS alias (no proxying)
apiVersion: v1
kind: Service
metadata: { name: postgres }
spec:
    type:         ExternalName
    externalName: rds.cluster-abcdef.us-east-1.rds.amazonaws.com
# postgres.default.svc → CNAME → rds...

# 5) Headless service — DNS for individual Pods (StatefulSets)
apiVersion: v1
kind: Service
metadata: { name: postgres-headless }
spec:
    clusterIP: None           # ← makes it headless
    selector: { app: postgres }
    ports: [{ port: 5432 }]
# DNS returns one A record per Pod IP:
#   postgres-0.postgres-headless.default.svc.cluster.local
#   postgres-1.postgres-headless.default.svc.cluster.local

# 6) Session affinity — sticky sessions by client IP
spec:
    sessionAffinity: ClientIP
    sessionAffinityConfig:
        clientIP: { timeoutSeconds: 10800 }   # 3 hours

# 7) Internal load balancer (cloud) — keep inside the VPC
metadata:
    annotations:
        service.beta.kubernetes.io/aws-load-balancer-scheme: internal
        cloud.google.com/load-balancer-type: Internal

# 8) Service discovery
# In-cluster DNS works automatically:
#   curl http://web.production.svc.cluster.local
# Short form within the same namespace:
#   curl http://web

# Environment variables — auto-injected by kubelet (older pattern, rarely used now)
#   WEB_SERVICE_HOST=10.0.1.42
#   WEB_SERVICE_PORT=80

# 9) Multi-port Service
spec:
    ports:
        - name:        http
          port:        80
          targetPort:  3000
        - name:        metrics
          port:        9090
          targetPort:  metrics-port    # named port on the Pod

# 10) Common kubectl
kubectl get svc -A
kubectl describe svc web
kubectl port-forward svc/web 8080:80     # local debug
kubectl run tmp --rm -it --image=alpine -- /bin/sh
#   wget -qO- web.production:80

# 11) Endpoints & EndpointSlices
# Kubernetes maintains an EndpointSlice per Service:
kubectl get endpointslice -l kubernetes.io/service-name=web
# Lists current Pod IPs the Service routes to. Updates as Pods scale.

# 12) Best practices
#   • Prefer Ingress + ClusterIP over many LoadBalancer Services (cost!)
#   • Use a Service per logical role, not per Pod
#   • Set readinessProbe on Pods — Service routes to ready Pods only
#   • Use NetworkPolicies to restrict who can call which Service

Why it matters

Use one Ingress + many ClusterIP Services instead of many LoadBalancer Services — one cloud LB instead of dozens, same routing flexibility, and you get TLS termination + host/path-based routing in the bargain.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
kind: Service
spec:
    selector: { app: api }
    ports: [{ port: 80, targetPort: 3000 }]
    type: ClusterIP    # NodePort, LoadBalancer, ExternalName
Try it Yourself »

Exercise

Default Service type for internal-only is…

type:

Test yourself

Q1. A Service gives pods a…
Q2. Expose internally with type…
Q3. Expose externally on cloud with…

Discussion

Loading…