GitHub EN PT

K8s by Example: Services (LoadBalancer)

LoadBalancer provisions an external load balancer from your cloud provider (AWS ELB, GCP LB, Azure LB). Traffic is routed to your Pods. Only works in supported environments.

service-loadbalancer.yaml

Set type: LoadBalancer to provision a cloud load balancer. The cloud controller creates and configures the LB automatically.

apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: my-app
terminal

The external IP appears in the Service status once provisioned. This can take a few minutes depending on the cloud provider.

$ kubectl get svc my-app -w
NAME     TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
my-app   LoadBalancer   10.96.0.100   <pending>     80:31234/TCP   10s
my-app   LoadBalancer   10.96.0.100   34.123.45.67  80:31234/TCP   45s

$ curl http://34.123.45.67
Hello from my-app!
service-lb-aws.yaml

Cloud-specific annotations configure the load balancer. Each provider has different options for internal LBs, NLB vs ALB, etc.

apiVersion: v1
kind: Service
metadata:
  name: my-app
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-internal: "true"
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: my-app
service-external-traffic.yaml

externalTrafficPolicy: Cluster (default) load balances across all nodes. Traffic may hop between nodes, causing extra latency and losing source IP.

spec:
  type: LoadBalancer
  externalTrafficPolicy: Cluster

externalTrafficPolicy: Local routes traffic only to nodes with pods. Preserves source IP and reduces latency, but requires pods on all receiving nodes.

spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: my-app
terminal

With Local policy, check that pods run on nodes receiving traffic. Use DaemonSet or pod anti-affinity to ensure coverage. Nodes without pods return connection refused.

$ kubectl get svc my-app -o yaml | grep externalTrafficPolicy
  externalTrafficPolicy: Local

$ kubectl get pods -o wide -l app=my-app
NAME       NODE      IP
my-app-1   node-1    10.244.1.5
my-app-2   node-2    10.244.2.8

$ kubectl logs my-app-1
Received request from 203.0.113.50
terminal

Each LoadBalancer Service creates a separate cloud resource (deleted when Service is deleted). For multiple services, use Ingress to share a single load balancer.

$ kubectl delete svc my-app
service "my-app" deleted

Index | Use arrow keys to navigate