<a id="network-load-balancers"></a>

# How to configure network load balancers

#### NOTE
Network load balancers are currently available for the [OVN network](https://canonical.com/lxd/docs/latest/reference/network_ovn/index.html.md#network-ovn).

Network load balancers are similar to forwards in that they allow specific ports on an IP address (external or internal) to be forwarded to specific ports on internal IP addresses in the same network as the load balancer.

The difference between load balancers and forwards is that load balancers can be used to share ingress traffic between multiple internal backend addresses. This feature can be useful if you have limited external IP addresses or want to share a single external address and ports over multiple instances.

A load balancer is made up of:

- A single listen IP address (external or internal).
- One or more named backends consisting of an internal IP and optional port ranges.
- One or more listen ports or port ranges that are configured to forward to one or more named backends.
- One or more listen ports that are configured to forward to one or more pools of instances.

A pool of instances allows a more simplified definition of backends as it doesn’t require additional configuration of the internal IP.
A pool also uses health checks to identify offline backends to which the load balancer should not forward any traffic.

## Create a network load balancer

Use the following command to create a network load balancer:

```bash
lxc network load-balancer create <network_name> [<listen_address>] [--allocate=ipv{4,6}] [configuration_options...]
```

Example with a specified listen address:

```bash
lxc network load-balancer create my-ovn-network 192.0.2.178
```

Example with an allocated listen address:

```bash
lxc network load-balancer create my-ovn-network --allocate=ipv4
```

Each load balancer is assigned to a network.

Listen addresses are subject to restrictions. If a listen address is not specified, the `--allocate` flag must be provided. See [Requirements for listen addresses](#network-load-balancers-listen-addresses) for more information about which addresses can be load-balanced, as well as how to use the `--allocate` flag.

### Load balancer properties

Network load balancers have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-load-balancer-properties:backends"></a>
`backends`

List of backend specifications

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:backends)

| **Key:**      | `backends`   |
|---------------|--------------|
| **Type:**     | backend list |
| **Required:** | no           |

See [Configure backends](#network-load-balancers-backend-specifications).

<a id="network-load-balancer-load-balancer-properties:config"></a>
`config`

User-provided free-form key/value pairs

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:config)

| **Key:**      | `config`   |
|---------------|------------|
| **Type:**     | string set |
| **Required:** | no         |

The only supported keys are `user.*` custom keys.

<a id="network-load-balancer-load-balancer-properties:description"></a>
`description`

Description of the network load balancer

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-load-balancer-load-balancer-properties:listen_address"></a>
`listen_address`

IP address to listen on

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:listen_address)

| **Key:**      | `listen_address`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | no                 |

<a id="network-load-balancer-load-balancer-properties:ports"></a>
`ports`

List of port specifications

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-properties:ports)

| **Key:**      | `ports`   |
|---------------|-----------|
| **Type:**     | port list |
| **Required:** | no        |

See [Configure ports](#network-load-balancers-port-specifications).

<a id="network-load-balancers-listen-addresses"></a>

### Requirements for listen addresses

The following requirements must be met for valid listen addresses:

For external listen IP addresses:

- Allowed listen addresses must be defined in the uplink network’s `ipv{n}.routes` settings or the project’s [`restricted.networks.subnets`](https://canonical.com/lxd/docs/latest/reference/projects/index.html.md#project-restricted:restricted.networks.subnets) setting.
  - If you specify a listen address when creating a load balancer, it must be within the range of allowed addresses.
  - If you do not specify a listen address, you must use either `--allocate ipv4` or `--allocate ipv6`. This will allocate a listen address from the range of allowed addresses.
- The listen address must not overlap with a subnet that is in use with another network or entity in that network.

For internal listen IP addresses:

- Allowed listen addresses must not be used by the associated network’s gateway, other existing load balancers and network forwards, or instance NICs.

<a id="network-load-balancers-backend-specifications"></a>

## Configure backends

You can add backend specifications to the network load balancer to define target addresses (and optionally ports).
The backend target address must be within the same subnet as the network associated with the load balancer.

Use the following command to add a backend specification:

```bash
lxc network load-balancer backend add <network_name> <listen_address> <backend_name> <target_address> [<target_ports>]
```

Example:

```bash
lxc network load-balancer backend add my-ovn-network 192.0.2.178 test-backend 10.41.211.5
```

If no target ports are specified when adding the backend:

- The load balancer uses the listen ports defined in the [port specification]() associated with that backend, if any.
- If no such listen ports are defined, the backend has no target ports and is inactive. You must either [add a port specification]() or [edit the load balancer configuration]() to include a `target_port` value in the backend specification or a `listen_port` value in the ports specification.

If you want to forward the traffic to different ports, you have two options:

- Specify a single target port to forward traffic from all listen ports to this target port.
- Specify a set of target ports with the same number of ports as the listen ports to forward traffic from the first listen port to the first target port, the second listen port to the second target port, and so on.

### Backend properties

Network load balancer backends have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-load-balancer-backend-properties:description"></a>
`description`

Description of the backend

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-load-balancer-load-balancer-backend-properties:name"></a>
`name`

Name of the backend

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:name)

| **Key:**      | `name`   |
|---------------|----------|
| **Type:**     | string   |
| **Required:** | yes      |

<a id="network-load-balancer-load-balancer-backend-properties:target_address"></a>
`target_address`

IP address to forward to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:target_address)

| **Key:**      | `target_address`   |
|---------------|--------------------|
| **Type:**     | string             |
| **Required:** | yes                |

<a id="network-load-balancer-load-balancer-backend-properties:target_port"></a>
`target_port`

Target port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-backend-properties:target_port)

| **Key:**      | `target_port`                                                        |
|---------------|----------------------------------------------------------------------|
| **Type:**     | string                                                               |
| **Default:**  | same as [`listen_port`](#network-load-balancer-load-balancer-port-properties:listen_port) |
| **Required:** | no                                                                   |

For example: `70,80-90` or `90`

<a id="network-load-balancers-pool-specifications"></a>

## Configure pools

Pools are not directly attached to a load balancer. Instead they are configured on the network and can therefore be referenced by one or many load balancers inside this network.

Use the following command to add a pool:

```bash
lxc network load-balancer pool create <network_name> <pool_name> <key>=<value>...
```

Example:

```bash
lxc network load-balancer pool create my-ovn-network https target_port=443
```

This creates a new pool and sets `443` as the target port for all instances inside the pool.
If necessary the port can be overwritten for each instance.

### Pool properties

Network load balancer pools have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-pool-properties:healthcheck"></a>
`healthcheck`

Whether to enable or disable health checks

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:healthcheck)

| **Key:**      | `healthcheck`   |
|---------------|-----------------|
| **Type:**     | bool            |
| **Default:**  | `true`          |
| **Required:** | no              |

<a id="network-load-balancer-pool-properties:healthcheck.failure_count"></a>
`healthcheck.failure_count`

Number of failed probe attempts after which an instance is considered unhealthy.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:healthcheck.failure_count)

| **Key:**      | `healthcheck.failure_count`   |
|---------------|-------------------------------|
| **Type:**     | integer                       |
| **Default:**  | `1`                           |
| **Required:** | no                            |

<a id="network-load-balancer-pool-properties:healthcheck.interval"></a>
`healthcheck.interval`

Interval in seconds between probes of the pool’s instances.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:healthcheck.interval)

| **Key:**      | `healthcheck.interval`   |
|---------------|--------------------------|
| **Type:**     | integer                  |
| **Default:**  | `5`                      |
| **Required:** | no                       |

<a id="network-load-balancer-pool-properties:healthcheck.success_count"></a>
`healthcheck.success_count`

Number of successful probe attempts after which an instance is considered healthy.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:healthcheck.success_count)

| **Key:**      | `healthcheck.success_count`   |
|---------------|-------------------------------|
| **Type:**     | integer                       |
| **Default:**  | `1`                           |
| **Required:** | no                            |

<a id="network-load-balancer-pool-properties:healthcheck.timeout"></a>
`healthcheck.timeout`

Timeout in seconds after a probe appears to be faulty.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:healthcheck.timeout)

| **Key:**      | `healthcheck.timeout`   |
|---------------|-------------------------|
| **Type:**     | integer                 |
| **Default:**  | `3`                     |
| **Required:** | no                      |

<a id="network-load-balancer-pool-properties:protocol"></a>
`protocol`

Protocol used for ingress pool traffic.

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:protocol)

| **Key:**      | `protocol`   |
|---------------|--------------|
| **Type:**     | string       |
| **Default:**  | `tcp`        |
| **Required:** | no           |

Can be either `tcp` or `udp`.

<a id="network-load-balancer-pool-properties:target_port"></a>
`target_port`

Port used on instances for ingress pool traffic

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-pool-properties:target_port)

| **Key:**      | `target_port`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | yes             |

<a id="network-load-balancers-pool-instances-specifications"></a>

### Configure pool instances

When a load balancer port references a pool, traffic can only be forwarded to the pool if it contains one or more instances.
Use the following command to add instances to the pool:

```bash
lxc network load-balancer pool instance add <network> <pool_name> <instance_name> [<target_port>]
```

#### IMPORTANT
OVN will immediately start to send traffic to an instance added to a pool that is already referenced by a load balancer port.

The load balancer will only know the status of the new instance after the health check returns for the first time.
At that point, the instance will be removed from the list of eligible targets if there isn’t a service listening on the target port.

Example:

```bash
lxc network load-balancer pool instance add my-ovn-network http i1
```

The target port is optional and allows you to use a custom port for the instance.
If you do not provide a target port for the instance, the instance will use the pool’s target port.

<a id="network-load-balancers-port-specifications"></a>

## Configure ports

You can add port specifications to the network load balancer to forward traffic from specific ports on the listen address:

- To specific ports on one or more target backends.
- To specific ports on all instances inside a target pool

Use the following command to add a port specification for explicit target backends:

```bash
lxc network load-balancer port add <network_name> <listen_address> <protocol> <listen_ports> target_backend=<backend_name>[,<backend_name>...]
```

Example:

```bash
lxc network load-balancer port add my-ovn-network 192.0.2.178 tcp 80 target_backend=test-backend
```

You can specify a single listen port or a set of ports.
The backend(s) specified must have target port(s) settings compatible with the port’s listen port(s) setting.

Use the following command to add a port specification for all instances inside a target pool:

```bash
lxc network load-balancer port add <network_name> <listen_address> <protocol> <listen_port> target_pool=<pool_name>
```

Example:

```bash
lxc network load-balancer port add my-ovn-network 192.0.2.178 tcp 443 target_pool=https
```

### Port properties

Network load balancer ports have the following properties:

<!-- Include content from [../metadata.txt](../metadata.txt) -->

<a id="network-load-balancer-load-balancer-port-properties:description"></a>
`description`

Description of the port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:description)

| **Key:**      | `description`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

<a id="network-load-balancer-load-balancer-port-properties:listen_port"></a>
`listen_port`

Listen port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:listen_port)

| **Key:**      | `listen_port`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | yes             |

For example: `80,90-100`

<a id="network-load-balancer-load-balancer-port-properties:protocol"></a>
`protocol`

Protocol for the port or ports

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:protocol)

| **Key:**      | `protocol`   |
|---------------|--------------|
| **Type:**     | string       |
| **Required:** | yes          |

Possible values are `tcp` and `udp`.

<a id="network-load-balancer-load-balancer-port-properties:target_backend"></a>
`target_backend`

Backend name(s) to forward to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:target_backend)

| **Key:**      | `target_backend`   |
|---------------|--------------------|
| **Type:**     | backend list       |
| **Required:** | no                 |

If you do not provide a list of backends, then you must provide a pool to `target_pool`.

<a id="network-load-balancer-load-balancer-port-properties:target_pool"></a>
`target_pool`

Pool of instances to forward to

[<i class="icon"><svg><use href="#svg-arrow-right"></use></svg></i>](#network-load-balancer-load-balancer-port-properties:target_pool)

| **Key:**      | `target_pool`   |
|---------------|-----------------|
| **Type:**     | string          |
| **Required:** | no              |

If you do not provide a pool, then you must provide a list of backends to `target_backend`.

## Edit a network load balancer

Use the following command to edit a network load balancer:

```bash
lxc network load-balancer edit <network_name> <listen_address>
```

This command opens the network load balancer in YAML format for editing.
You can edit the general configuration, as well as the backend and port specifications.

Example load balancer configuration YAML file:

```yaml
listen_address: 192.0.2.178
location: ""
description: ""
config: {}
backends:
- name: test-backend
  description: ""
  target_port: ""
  target_address: 10.41.211.5
ports:
- description: ""
  protocol: tcp
  listen_port: 70,80-90
  target_backend:
  - test-backend
- description: ""
  protocol: tcp
  listen_port: 443
  target_pool: https
```

## Edit a network load balancer pool

Use the following command to edit a network load balancer pool:

```bash
lxc network load-balancer pool edit <network_name> <pool_name>
```

This command opens the network load balancer pool in YAML format for editing.
You can edit the general configuration, as well as the instances and their target port.

Example load balancer pool configuration YAML file:

```yaml
name: https
description: ""
config:
  protocol: tcp
  target_port: "443"
  healthcheck.interval: 10
instances:
- name: i1
- name: i2
- name: i3
  target_port: "8443"
used_by:
- /1.0/networks/default/load-balancers/192.0.2.178
```

## Get the state of a network load balancer pool

When a pool is referenced by a network load balancer port and contains instances, the current state of the health check can be observed for all instances in the pool.

Use the following command to get the state of a network load balancer pool:

```bash
lxc network load-balancer pool info <network_name> <pool_name>
```

The status for each of the pool’s instances is reported for each load balancer port that references the pool.

## Delete a network load balancer

Use the following command to delete a network load balancer:

```bash
lxc network load-balancer delete <network_name> <listen_address>
```

## Delete a network load balancer pool

Use the following command to delete a network load balancer pool:

```bash
lxc network load-balancer pool delete <network_name> <pool_name>
```

## Remove a network load balancer pool instance

Use the following command to remove a network load balancer pool instance:

```bash
lxc network load-balancer pool instance remove <network_name> <pool_name> <instance_name>
```

## Remove a network load balancer port

Use the following command to remove a network load balancer port:

```bash
lxc network load-balancer port remove <network_name> <listen_address> <protocol> <listen_ports>
```
