> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hyko.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Metallb load balancer

This guide walks you through installing MetalLB, a load balancer implementation for bare metal Kubernetes clusters, on your Talos cluster.

## What is MetalLB?

MetalLB is a network load balancer implementation for Kubernetes clusters that don't run on supported cloud providers. It provides:

* **LoadBalancer service type** support for bare metal clusters
* **Automatic IP address assignment** from configured pools
* **Layer 2 (ARP/NDP) mode** for simple network integration
* **BGP mode** for advanced routing scenarios
* **Multiple IP address pools** for different services or tenants
* **Cloud-provider parity** bringing the LoadBalancer experience to on-premises clusters

Unlike cloud load balancers, MetalLB runs entirely within your cluster and announces IP addresses to your local network.

## Prerequisites

Before installing MetalLB, you need to:

1. Have a running Talos Kubernetes cluster (see the deployment guide)
2. Have `kubectl` configured to access your cluster
3. Have `helm` installed on your local machine
4. Know your available IP address range for load balancer services

**Important network considerations:**

* You need a range of IP addresses on your local network that are not used by DHCP
* These IPs must be in the same subnet as your cluster nodes

## Configure Namespace Security

MetalLB requires privileged access to manage network interfaces and announce IP addresses at the system level. We need to configure the namespace with appropriate Pod Security Standards.

**What are Pod Security Standards?**
Kubernetes Pod Security Standards define three policies:

* **Privileged**: Unrestricted policy (required for system-level operations)
* **Baseline**: Minimally restrictive policy
* **Restricted**: Heavily restricted policy (most secure)

MetalLB needs privileged access because it:

* Manipulates network interfaces and ARP/NDP tables
* Manages BGP sessions with network routers
* Performs low-level networking operations
* Interacts directly with the kernel networking stack

**Create the namespace with security labels:**

```bash theme={null}
kubectl create namespace metallb-system

kubectl label namespace metallb-system \
  pod-security.kubernetes.io/enforce=privileged \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/audit=privileged \
  pod-security.kubernetes.io/audit-version=latest \
  pod-security.kubernetes.io/warn=privileged \
  pod-security.kubernetes.io/warn-version=latest
```

**What each label means:**

* **enforce=privileged**: Pods violating this policy will be rejected
* **audit=privileged**: Policy violations are logged to the audit log
* **warn=privileged**: Users receive warnings for policy violations
* **version=latest**: Use the latest version of the policy standard

## Add MetalLB Helm Repository

MetalLB is distributed via Helm charts, which are packages for Kubernetes applications.

```bash theme={null}
# Add the MetalLB Helm repository
helm repo add metallb https://metallb.github.io/metallb

# Update your local Helm chart repository cache
helm repo update

# Verify the repository was added
helm search repo metallb
```

**Expected output:**

```
NAME              CHART VERSION   APP VERSION   DESCRIPTION
metallb/metallb   0.15.3          v0.15.3       A network load-balancer implementation for Kub...
```

## Install MetalLB

Now we'll install MetalLB. The installation happens in two phases: first the controller and speaker components, then the configuration.

**Install MetalLB:**

```bash theme={null}
helm install metallb metallb/metallb \
  --namespace metallb-system \
  --version v0.15.3
```

**What gets installed:**

### MetalLB Controller

* Watches for Service objects with `type: LoadBalancer`
* Assigns IP addresses from configured pools
* Manages the overall state of load balancer assignments
* Runs as a Deployment (single instance with leader election)

### MetalLB Speaker

* Announces assigned IP addresses to the network
* Runs as a DaemonSet (one pod per node)
* Handles Layer 2 (ARP/NDP) or BGP announcements
* Responds to ARP requests for assigned IPs

**Installation process takes 1-2 minutes.** Helm will:

1. Create CustomResourceDefinitions (CRDs) for MetalLB objects
2. Deploy the MetalLB controller
3. Deploy the MetalLB speaker DaemonSet on each node
4. Set up RBAC permissions
5. Create webhook configurations

## Configure MetalLB

MetalLB requires configuration to know which IP addresses to use. This is done through two custom resources: **IPAddressPool** and **L2Advertisement**.

**Create a configuration file `metallb-config.yaml`:**

```yaml theme={null}
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.240-192.168.1.250  # Replace with your IP range
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default-l2
  namespace: metallb-system
spec:
  ipAddressPools:
  - default-pool
```

**What these resources mean:**

### IPAddressPool

* Defines a pool of IP addresses MetalLB can assign
* **addresses**: List of IP ranges or CIDR blocks
  * Example range: `192.168.1.240-192.168.1.250` (11 IPs)
  * Example CIDR: `192.168.1.240/28` (16 IPs)
* You can create multiple pools for different purposes
* Replace the example IPs with your actual available range

### L2Advertisement

* Tells MetalLB to advertise IPs using Layer 2 protocols (ARP/NDP)
* **ipAddressPools**: Which IP pools to advertise via Layer 2
* Layer 2 mode is simpler but all traffic goes through one node
* For production, consider BGP mode for better load distribution

**Apply the configuration:**

```bash theme={null}
kubectl apply -f metallb-config.yaml
```

**Understanding IP Pool Selection:**

* Choose IPs in the same subnet as your nodes
* Ensure they're outside your DHCP range
* Reserve enough IPs for your expected services
* Common practice: Use the high end of your subnet (e.g., .240-.250)

## Verify Installation

**Check pod status:**

```bash theme={null}
kubectl get pods -n metallb-system
```

**Expected output (wait until all pods show `Running`):**

```
NAME                                  READY   STATUS    RESTARTS   AGE
metallb-controller-...                1/1     Running   0          2m
metallb-speaker-...                   1/1     Running   0          2m
metallb-speaker-...                   1/1     Running   0          2m
```

**Verify configuration:**

```bash theme={null}
# Check IP address pools
kubectl get ipaddresspools -n metallb-system

# Check L2 advertisements
kubectl get l2advertisements -n metallb-system
```

**Expected output:**

```
NAME           AUTO ASSIGN   AVOID BUGGY IPS   ADDRESSES
default-pool   true          false             ["192.168.1.240-192.168.1.250"]

NAME        IPADDRESSPOOLS    IPADDRESSPOOL SELECTORS   INTERFACES
default-l2  ["default-pool"]
```

## How to Use MetalLB

Now you can create LoadBalancer services in your cluster:

```yaml theme={null}
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer  # This triggers MetalLB
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: my-app
```

**MetalLB will automatically:**

1. Assign an IP from your configured pool
2. Announce that IP via Layer 2 (ARP/NDP)
3. Route traffic to your service's pods
4. Update the service with the `EXTERNAL-IP`

**You now have cloud-like LoadBalancer services on your bare metal cluster! 🎉**

### Request Specific IP

You can request a specific IP address:

```yaml theme={null}
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer
  loadBalancerIP: 192.168.1.241  # Must be in a configured pool
  # ...
```
