LoxiLB Octavia Provider Driver
An OpenStack Octavia provider driver that uses LoxiLB — an eBPF/XDP-based load balancer — as the data plane for Octavia load balancers.
The driver implements the octavia-lib provider contract, translating Octavia
load-balancer / listener / pool / member / health-monitor operations into LoxiLB
REST API calls. It supports two deployment topologies and is validated against the
upstream octavia-tempest-plugin on OpenStack 2025.1 Epoxy (with 2025.2
Flamingo support).
Features
- eBPF/XDP data plane — load balancing powered by LoxiLB.
- Two deployment topologies:
amphora_style— the driver provisions and manages a dedicated LoxiLB VM per load balancer (Nova-booted), mirroring the amphora model.external— the driver programs an existing, operator-managed LoxiLB cluster via its REST API.
- High availability —
SINGLE,ACTIVE_STANDBY, andACTIVE_ACTIVEtopologies; BFD-based failover for active/standby (amphora_style). - Load-balancing algorithms —
ROUND_ROBIN, weighted round-robin (member weights),SOURCE_IP,SOURCE_IP_PORT, andLEAST_CONNECTIONS. - Health monitors —
HTTP,HTTPS,TCP,UDP_CONNECT, andPINGmapped to LoxiLB endpoint health probes. - Flexible VIP networking — L2 (
l2_aap) and BGP (bgp) VIP modes; selectable NAT mode (SNAT/DNAT/FULLNAT/ONEARM). - Split-process design — a synchronous provider driver inside
octavia-apiplus an asynchronousoctavia-loxilb-controller-workerfor long-running provisioning.
How it works
┌───────────────────────────┐
openstack │ octavia-api │
loadbalancer ─────▶ │ LoxiLBProviderDriver │ (in-process provider driver)
create ... └────────────┬──────────────┘
│ RPC cast (oslo.messaging, topic loxilb_octavia)
▼
┌───────────────────────────┐
│ octavia-loxilb-controller │ (cotyledon service, TaskFlow)
│ -worker │
└────────────┬──────────────┘
│ LoxiLB REST API (/netlox/v1/..., :11111)
▼
amphora_style: driver-managed LoxiLB VM(s) │ external: existing
booted per load balancer via Nova │ LoxiLB cluster
Authoritative state lives in Octavia's database; LoxiLB owns runtime LB-service
state. The driver keeps an Octavia↔LoxiLB ID mapping (LoxiLB has no unique IDs for
sub-resources) persisted to id_mapping_storage_path.
Requirements
| Component | Requirement |
|---|---|
| OpenStack | Octavia on 2025.1 Epoxy (validated) or 2025.2 Flamingo |
| Python | 3.10 – 3.12 |
octavia-lib |
>= 3.8.0 |
| Services | Octavia API + driver-agent, Nova, Neutron, Keystone, Glance, a message bus (RabbitMQ), MySQL/MariaDB |
| LoxiLB | A reachable LoxiLB exposing /netlox/v1/... on :11111 — either an external cluster (external mode) or the LoxiLB VM image registered in Glance (amphora_style mode) |
octavia-driver-agent must be running: the driver pushes provisioning and operating
status through the driver-agent's status socket (octavia_lib's DriverLibrary), so
without it load balancers never leave PENDING_CREATE.
For the LoxiLB VM image (amphora_style), see docs/LOXILB-VM-IMAGES.md.
Installation
Use docs/INSTALL.md as the authoritative operator runbook.
The README section below is only a quick-start overview: pip install alone is
not enough to produce a working deployment.
At minimum, a real deployment must also:
- apply the driver's database migrations,
- configure
[api_settings]and[loxilb], - provide topology-specific resources and credentials for
amphora_style, - install and start
octavia-loxilb-controller-worker, and - restart
octavia-apiand verify thatloxilbappears inopenstack loadbalancer provider list.
Install the package into the same Python environment that octavia-api and the
Octavia worker run from (so the entry points are discoverable):
pip install octavia-loxilb-driver
Version note. These instructions describe 1.1.0 (this repository). The latest release published to PyPI at the time of writing is 1.0.3, which predates the
octavia-loxilb-db-manageconsole script and the driver's database migrations. Check withpip show octavia-loxilb-driver; if you get anything older than 1.1.0, install from source instead:pip install "git+https://github.com/loxilb-io/octavia-loxilb-driver.git@main"
Containerized control planes (Kolla-Ansible, OpenStack-Helm, TripleO) must install
the package into the Octavia API/worker container images (or a persistent overlay),
not just a transient docker exec. Example for Kolla-Ansible:
sudo docker exec -u root octavia_api /var/lib/kolla/venv/bin/pip install octavia-loxilb-driver
sudo docker exec -u root octavia_worker /var/lib/kolla/venv/bin/pip install octavia-loxilb-driver
The version note above applies here too — check pip show octavia-loxilb-driver inside
each container and fall back to the git+https://... install if it reports < 1.1.0.
Console scripts
Installing the package provides three console scripts:
| Command | Purpose |
|---|---|
octavia-loxilb-setup |
Bootstrap/inspect OpenStack resources for the driver |
octavia-loxilb-controller-worker |
The asynchronous controller-worker service (run via systemd) |
octavia-loxilb-db-manage |
Apply the driver's database migrations |
Configuration
1. Enable the provider in Octavia
In /etc/octavia/octavia.conf:
[api_settings]
enabled_provider_drivers = amphora:Amphora provider,loxilb:LoxiLB provider driver
The LoxiLB driver runs in-process inside
octavia-api; it does not require an entry inenabled_provider_agents(it ships nooctavia.driver_agent.provider_agentsentry point, so adding one makesoctavia-driver-agentfail to load it).octavia-driver-agentitself must still be running — the driver reports status through its status socket.
2. Configure the [loxilb] section
[loxilb]
# --- Deployment topology ---
# amphora_style | external
deployment_topology = amphora_style
# l2_aap | bgp
vip_mode = l2_aap
# SNAT | DNAT | FULLNAT | ONEARM
nat_mode = FULLNAT
# SINGLE | ACTIVE_STANDBY | ACTIVE_ACTIVE
default_topology = SINGLE
# --- LoxiLB REST API ---
# Required for 'external' mode (comma-separated cluster endpoints). In
# 'amphora_style' the driver discovers the endpoint of each VM it boots.
api_endpoints = http://192.0.2.10:11111,http://192.0.2.11:11111
api_version = v6.0
api_timeout = 30
api_retries = 3
api_use_ssl = false
# none | password | token | tls ('password' is the basic-auth value)
loxilb_auth_type = none
# --- Controller-worker RPC ---
rpc_topic = loxilb_octavia
# --- ID-mapping persistence (must be writable by the octavia user) ---
id_mapping_storage_path = /var/lib/octavia/loxilb_id_mappings.json
# --- amphora_style: driver-managed LoxiLB VM provisioning ---
image_id = <glance id of the LoxiLB VM image>
flavor_id = <nova flavor id>
network_id = <tenant/data network id>
mgmt_network_id = <octavia lb-mgmt-net id>
security_group_ids = <sg id>[,<sg id>...]
# optional: enables SSH into LoxiLB VMs
key_name = <nova keypair name>
use_mgmt_network = true
INI note: oslo.config does not strip trailing
#comments.key = value # noteis read as the literal valuevalue # note. Options with a fixed choice list (deployment_topology,vip_mode,nat_mode,default_topology,loxilb_auth_type) and typed options such asapi_use_sslabort startup withConfigFileValueError; free-form options such askey_namesilently take the polluted value. Keep comments on their own lines, as above.
3. Configure OpenStack identity (amphora_style)
amphora_style provisions Nova VMs and Neutron ports, so the driver needs an
OpenStack identity (Keystone). The runtime currently reads these values from the
[loxilb] group, so putting them only under [service_auth] is not sufficient
for driver-managed VM provisioning:
[loxilb]
auth_url = https://keystone.example.com:5000
auth_type = password
username = octavia
password = <octavia service password>
project_name = service
user_domain_name = Default
project_domain_name = Default
A complete, deployment-focused walkthrough is in docs/INSTALL.md. A full sample config ships inside the installed package — print its path with the Octavia venv's python:
python -c "import octavia_loxilb_driver, os; print(os.path.join(os.path.dirname(octavia_loxilb_driver.__file__), 'etc/octavia.conf.sample'))"
4. Apply migrations and start the controller-worker
Run these with the Octavia venv's python / console scripts:
octavia-loxilb-db-manage --config-file /etc/octavia/octavia.conf upgrade head
# the unit file ships inside the installed package - resolve it
UNIT=$(python -c "import octavia_loxilb_driver, os; print(os.path.join(os.path.dirname(octavia_loxilb_driver.__file__), 'install/octavia-loxilb-controller-worker.service'))")
sudo cp "$UNIT" /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now octavia-loxilb-controller-worker
sudo systemctl restart <your-octavia-api-service>
The shipped unit is production-oriented:
User=octaviaandExecStart=/usr/local/bin/octavia-loxilb-controller-worker. If you installed the driver into a venv (DevStack/opt/stack/data/venv/bin, Kolla/var/lib/kolla/venv/bin) or Octavia runs as a different user, the unit will fail to start until you override both. See docs/INSTALL.md — DevStack override for the controller-worker unit.
See docs/INSTALL.md for deployment-specific service names (for example, DevStack vs. containerized control planes).
Usage
This is a post-install smoke example, not the full operator deployment procedure.
It assumes the package is installed in the Octavia runtime venv, database
migrations are applied, octavia-loxilb-controller-worker is running, and, for
amphora_style, the image/network/security-group/auth settings are already
configured. For the full operator workflow, use docs/INSTALL.md.
Octavia locks the whole load-balancer tree while a provisioning operation is in flight,
so every mutating command below uses --wait. Without it the next command fails with
HTTP 409 Load Balancer ... is immutable and cannot be updated. In amphora_style the
first create boots a Nova VM, so it can take minutes.
# Confirm the provider is registered
openstack loadbalancer provider list # 'loxilb' should be listed
# Create a load balancer backed by LoxiLB
LB_ID=$(openstack loadbalancer create --name web-lb \
--vip-subnet-id <vip-subnet> --provider loxilb --wait -f value -c id)
# Listener -> pool -> members
openstack loadbalancer listener create --name l1 \
--protocol TCP --protocol-port 80 --wait "$LB_ID"
POOL_ID=$(openstack loadbalancer pool create --name p1 \
--lb-algorithm ROUND_ROBIN --protocol TCP --listener l1 --wait -f value -c id)
openstack loadbalancer member create --address 10.0.0.11 \
--protocol-port 80 --subnet-id <member-subnet> --wait "$POOL_ID"
openstack loadbalancer member create --address 10.0.0.12 \
--protocol-port 80 --subnet-id <member-subnet> --wait "$POOL_ID"
# Health monitor
openstack loadbalancer healthmonitor create --name hm1 \
--type TCP --delay 5 --timeout 3 --max-retries 3 --wait "$POOL_ID"
openstack loadbalancer show "$LB_ID"
# Clean up the smoke resources when finished
openstack loadbalancer delete --cascade --wait "$LB_ID"
Selecting topology per load balancer
Cloud-wide defaults come from [loxilb]. Per-load-balancer overrides (e.g.
ACTIVE_STANDBY, vip_mode) are set via an Octavia flavor:
openstack loadbalancer flavorprofile create --name loxilb-as \
--provider loxilb --flavor-data '{"loadbalancer_topology": "ACTIVE_STANDBY"}'
openstack loadbalancer flavor create --name loxilb-active-standby \
--flavorprofile loxilb-as --enable
openstack loadbalancer create --name ha-lb --provider loxilb \
--flavor loxilb-active-standby --vip-subnet-id <vip-subnet> --wait
Supported feature matrix
| Capability | Support |
|---|---|
| Protocols | TCP, UDP |
| Algorithms | ROUND_ROBIN, weighted RR, SOURCE_IP, SOURCE_IP_PORT, LEAST_CONNECTIONS |
| Health monitors | HTTP, HTTPS, TCP, UDP_CONNECT, PING |
| Topologies | SINGLE, ACTIVE_STANDBY, ACTIVE_ACTIVE |
| Deployment models | amphora_style (driver-managed VMs), external (existing cluster) |
| VIP modes | l2_aap, bgp |
| NAT modes | SNAT, DNAT, FULLNAT, ONEARM |
Roadmap: TLS termination and L7 policies are planned for later releases (
v1.x/v2). See the project roadmap for status.
Troubleshooting
Provider not listed by openstack loadbalancer provider list:
the package must be installed in the same venv as octavia-api, and
enabled_provider_drivers must include loxilb. Restart octavia-api after changes.
Load balancer stuck in PENDING_CREATE:
check the controller-worker is running and bound to the RPC topic —
sudo systemctl status octavia-loxilb-controller-worker and
sudo rabbitmqctl list_queues name consumers | grep loxilb_octavia (consumers ≥ 1).
Controller-worker fails at startup with DB / migration errors:
run octavia-loxilb-db-manage --config-file /etc/octavia/octavia.conf upgrade head
and then inspect sudo journalctl -u octavia-loxilb-controller-worker --no-pager.
Controller-worker cannot reach a LoxiLB VM (amphora_style):
the worker runs in the host network and must have a route to the LoxiLB VM's
management NIC. Use a routable management network (a Flat/VLAN provider network is
recommended over a tenant overlay the host cannot reach). Verify with
curl http://<loxilb-mgmt-ip>:11111/netlox/v1/config/loadbalancer/all.
See docs/TROUBLESHOOTING.md for more.
Documentation
| Document | Description |
|---|---|
| Installation Guide | Operator install/configure walkthrough |
| VM Images Guide | LoxiLB VM image distribution & registration |
| Troubleshooting | Common issues and fixes |
Contributing
Contributions are welcome.
git clone https://github.com/loxilb-io/octavia-loxilb-driver.git
cd octavia-loxilb-driver
pip install -e .
python -m pytest octavia_loxilb_driver/tests/unit/ -v
Please run ruff format, ruff check, and the relevant tests (or
pre-commit run --all-files) before submitting changes.
Support
- Issues: https://github.com/loxilb-io/octavia-loxilb-driver/issues
- LoxiLB: https://github.com/loxilb-io/loxilb
License
Apache License 2.0 — see LICENSE.
An OpenStack Octavia provider driver for LoxiLB, by the LoxiLB / NetLOX team and contributors.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file octavia_loxilb_driver-1.1.0.tar.gz.
File metadata
- Download URL: octavia_loxilb_driver-1.1.0.tar.gz
- Upload date:
- Size: 386.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bee90bfacbe1b8e0e2b1cf4745d3a8cd0531e5a76a0c824f87147265bc2d2fe
|
|
| MD5 |
8798a0902a7ba0cba9463c6119382f88
|
|
| BLAKE2b-256 |
90c22e8bb0e855626cc0cf86506e0fae813517fc9dbf18ebcd5f81fa8a029ee1
|
File details
Details for the file octavia_loxilb_driver-1.1.0-py3-none-any.whl.
File metadata
- Download URL: octavia_loxilb_driver-1.1.0-py3-none-any.whl
- Upload date:
- Size: 850.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a728f3ba1b436d9afb0fbafa18c188ef0fd879ef1cfa4601856e04ceac1c1d71
|
|
| MD5 |
bad870c4fb12498656e27bb44409ee94
|
|
| BLAKE2b-256 |
7e86dfb5353e82fbe4f9fcf75e016ce002dc4289f53d05325eb58aa8cf04c1a3
|