16: Service LoadBalancer

16: Service LoadBalancer

Objective

Learn how the LoadBalancer Service type works in AKS, understand how Azure automatically provisions an Azure Load Balancer, and practice creating both public and internal LoadBalancer Services.


Theory

LoadBalancer Extends ClusterIP

A LoadBalancer Service is a superset of a ClusterIP Service. When you create a LoadBalancer Service, Kubernetes:

  1. Creates a ClusterIP (internal virtual IP)
  2. Requests the cloud provider (Azure) to provision an external load balancer
  3. Azure creates an Azure Load Balancer with a public (or internal) IP
  4. Traffic from the external IP is routed through the Azure LB to the Service’s ClusterIP, and then to the Pods

ClusterIP vs LoadBalancer Comparison

Feature ClusterIP LoadBalancer
Accessible from Inside the cluster only Internet or internal Azure network
External IP None Assigned by Azure
Azure resource created None Azure Load Balancer + Public IP
Use case Internal microservice communication Exposing services to external clients
Cost Free Azure LB and Public IP costs apply

Public vs Internal Load Balancer

Type Description Use Case
Public Gets a public IP address accessible from the Internet Web applications, public APIs
Internal Gets a private IP address from your VNet Backend services, internal APIs, hybrid connectivity

To create an internal Load Balancer, add the annotation:

metadata:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"

Traffic Flow Diagram

graph TB
    Internet["Internet / Client"]

    subgraph Azure["Azure"]
        ALB["Azure Load Balancer<br/>External IP: 20.50.100.200"]
    end

    subgraph AKS["AKS Cluster"]
        SVC["Service: nginx-lb-XX<br/>ClusterIP: 10.0.100.50"]
        subgraph Pods["Pods"]
            P1["Pod 1<br/>10.244.0.5:80"]
            P2["Pod 2<br/>10.244.1.8:80"]
            P3["Pod 3<br/>10.244.2.3:80"]
        end
    end

    Internet -->|"http://20.50.100.200"| ALB
    ALB --> SVC
    SVC --> P1
    SVC --> P2
    SVC --> P3

    style Azure fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
    style AKS fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
    style Internet fill:#fff3e0,stroke:#f57c00,stroke-width:1px

Practical Tasks

Task 1: Create a Public LoadBalancer Service

Create a file called nginx-loadbalancer.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-lb-XX                   # Replace XX with your student number
  namespace: student-XX
  labels:
    app: nginx-lb-XX
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-lb-XX
  template:
    metadata:
      labels:
        app: nginx-lb-XX
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80
              name: http
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb-XX                   # Replace XX with your student number
  namespace: student-XX
spec:
  type: LoadBalancer
  selector:
    app: nginx-lb-XX
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      name: http

Deploy and wait for the external IP:

kubectl apply -f nginx-loadbalancer.yaml

Watch the Service until EXTERNAL-IP changes from <pending> to an actual IP address:

kubectl get svc nginx-lb-XX -n student-XX -w

Note: It may take 1-3 minutes for Azure to provision the Load Balancer and assign a public IP.

Once the external IP is assigned, test it in your browser:

http://<EXTERNAL-IP>

You should see the default nginx welcome page.

You can also test from the command line:

curl http://<EXTERNAL-IP>

Task 2: Create an Internal LoadBalancer Service

Create a file called nginx-internal-lb.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-internal-lb-XX          # Replace XX with your student number
  namespace: student-XX
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: "true"
spec:
  type: LoadBalancer
  selector:
    app: nginx-lb-XX                  # Reuses the same Deployment from Task 1
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      name: http

Deploy and verify:

kubectl apply -f nginx-internal-lb.yaml
kubectl get svc nginx-internal-lb-XX -n student-XX -w

Notice that the EXTERNAL-IP is a private IP address from your VNet (e.g., 10.0.x.x), not a public IP.

This Service is accessible from:

  • Other Pods within the cluster
  • Other resources in the same VNet (VMs, other AKS clusters)
  • On-premises networks connected via VPN or ExpressRoute

It is not accessible from the public Internet.

Clean Up

Important: Each LoadBalancer Service creates Azure resources (Load Balancer rules, Public IPs) that incur costs. Always clean up LoadBalancer Services promptly when you are done with the exercise to avoid unnecessary charges.

kubectl delete -f nginx-loadbalancer.yaml
kubectl delete -f nginx-internal-lb.yaml

AKS Diagnostics (Instructor Reference)

Note: The following Azure CLI commands and Azure Portal tasks require access to the Azure subscription. In this training, these are performed by the instructor as a demo. Participants can observe but should focus on the kubectl commands in the practical tasks above.

Check the MC_ Resource Group

Azure creates Load Balancer resources in the managed resource group (prefixed with MC_). The instructor can inspect them:

# List resources in the managed resource group
az resource list --resource-group MC_<resource-group>_<cluster-name>_<region> --output table

# List Load Balancers specifically
az network lb list --resource-group MC_<resource-group>_<cluster-name>_<region> --output table

Check NSG Rules

Network Security Groups control traffic flow. Verify that the NSG allows inbound traffic on the Service port:

az network nsg list --resource-group MC_<resource-group>_<cluster-name>_<region> --output table
az network nsg rule list --resource-group MC_<resource-group>_<cluster-name>_<region> --nsg-name <nsg-name> --output table

Check LB Health Probes in Azure Portal (Instructor Demo)

In the Azure Portal:

  1. Navigate to the managed resource group (MC_...)
  2. Open the Load Balancer resource
  3. Check Health probes — these must be healthy for traffic to flow
  4. Check Backend pools — these should list your AKS nodes
  5. Check Load balancing rules — these map the external port to backend port

Useful Commands

Command Description
kubectl get svc -n student-XX List all Services
kubectl get svc nginx-lb-XX -n student-XX -o wide Show Service with additional details
kubectl describe svc nginx-lb-XX -n student-XX Detailed Service info including events
kubectl get events -n student-XX --sort-by=.lastTimestamp Check events for LB provisioning status

Common Problems

Problem Possible Cause Solution
EXTERNAL-IP stays <pending> for more than 5 minutes AKS service principal/managed identity lacks permissions to create Azure resources Check cluster identity permissions on the MC_ resource group
EXTERNAL-IP is <pending> Azure LB quota exceeded Check Azure subscription quotas for Load Balancers and Public IPs
Cannot reach external IP from browser NSG blocking inbound traffic on the port Check NSG rules in the MC_ resource group
Internal LB gets a public IP Missing annotation Verify the azure-load-balancer-internal: "true" annotation is present
Service exists but no traffic flows LB health probes failing Check health probes in Azure Portal (see next exercise)
Slow LB provisioning Azure API throttling Wait and retry; check kubectl get events for details

Best Practices

  1. Use LoadBalancer only when you need external access — For internal communication, ClusterIP is simpler and free.
  2. Prefer internal LB for backend services — If a service only needs to be accessed from within the VNet, use the internal annotation.
  3. Be aware of costs — Each LoadBalancer Service creates an Azure LB rule and potentially a Public IP, which incur costs.
  4. Consider Ingress for HTTP workloads — Instead of creating multiple LoadBalancer Services, use an Ingress controller to consolidate external access behind a single Load Balancer.
  5. Monitor LB health probes — Unhealthy probes mean Azure LB will not route traffic to your nodes.

Summary

In this exercise you learned:

  • LoadBalancer is a superset of ClusterIP that provisions an Azure Load Balancer
  • Azure automatically creates and configures the LB, public IP, health probes, and NSG rules
  • Public LoadBalancer exposes services to the Internet; internal LoadBalancer uses a private VNet IP
  • How to create both public and internal LoadBalancer Services in AKS
  • Where to find and diagnose Azure LB resources in the MC_ resource group
  • Common issues: pending EXTERNAL-IP, NSG blocking, health probe failures

results matching ""

    No results matching ""