HAProxy load balancer setup with netns namespaces
This example configures HAProxy with dedicated network namespaces for listener and server access. This gives a hard isolation between the public Internet, the backend servers and the management access.
interfaces:
# bonding interface used for VLAN sub-interfaces
bond0:
link:
state: up
kind: bond
bond_mode: 802.3ad
bond_ad_lacp_rate: fast
bond_xmit_hash_policy: layer3+4
bond_miimon: 100
bond_updelay: 300
# physical interfaces for bond0
lom1:
link:
state: up
kind: physical
master: bond0
identify:
parent_dev_name: "0000:06:00.0"
parent_dev_bus_name: pci
lom2:
link:
state: up
kind: physical
master: bond0
identify:
parent_dev_name: "0000:06:00.1"
parent_dev_bus_name: pci
# management access in VLAN 100
mgmt:
addresses:
- "192.0.2.80/24"
link:
state: up
kind: vlan
vlan_protocol: 802.1q
vlan_id: 100
link: bond0
routing:
routes:
- to: 0.0.0.0/0
via: 192.0.2.1
namespaces:
# namespace for HAProxy listener
public:
interfaces:
bond0.600:
addresses:
- 198.51.100.2/29
- 2001:db8:dead:c0de::10/64
link:
kind: vlan
state: up
vlan_id: 600
link: bond0
link_netns: null
routing:
routes:
- to: 0.0.0.0/0
via: 198.51.100.1
- to: ::/0
via: fe80::defa
dev: bond0.600
# namespace for HAProxy server access
backend:
interfaces:
bond0.900:
addresses:
- fd00:4242:dead:c0de::1:80::/64
link:
kind: vlan
state: up
vlan_id: 900
link: bond0
link_netns: null
routing:
routes:
- to: ::/0
via: fe80::defa
dev: bond0.900
{
networking.ifstate = {
enable = true;
settings = {
interfaces = {
# bonding interface used for VLAN sub-interfaces
bond0 = {
link = {
state = "up";
kind = "bond";
bond_mode = "802.3ad";
bond_ad_lacp_rate = "fast";
bond_xmit_hash_policy = "layer3+4";
bond_miimon = 100;
bond_updelay = 300;
};
};
# physical interfaces for bond0
lom1 = {
link = {
state = "up";
kind = "physical";
master = "bond0";
};
identify = {
parent_dev_name = "0000:06:00.0";
parent_dev_bus_name = "pci";
};
};
lom2 = {
link = {
state = "up";
kind = "physical";
master = "bond0";
};
identify = {
parent_dev_name = "0000:06:00.1";
parent_dev_bus_name = "pci";
};
};
# management access in VLAN 100
mgmt = {
addresses = [ "192.0.2.80/24"; ];
link = {
kind = "vlan";
link = "bond0";
vlan_id = 42;
state = "up";
};
};
};
routing.routes = [
{
to = "0.0.0.0/0";
via = "192.0.2.1";
}
];
# namespace for HAProxy listener
namespaces = {
public = {
interfaces = {
"bond0.600" = {
addresses = [ "198.51.100.2/29", "2001:db8:dead:c0de::1:80/64" ];
link = {
kind = "vlan";
link = "bond0";
link_netns = null;
vlan_id = 600;
state = "up";
};
};
};
routing.routes = [
{
to = "0.0.0.0/0";
via = "198.51.100.1";
}
{
to = "::/0";
via = "fe80::defa";
dev = "bond0.600";
}
];
};
# namespace for HAProxy server access
backend = {
interfaces = {
"bond0.900" = {
addresses = [ "fd00:4242:dead:c0de::1:80::/64" ];
link = {
kind = "vlan";
link = "bond0";
link_netns = null;
vlan_id = 900;
state = "up";
};
};
};
routing.routes = [
{
to = "::/0";
via = "fe80::defa";
dev = "bond0.900";
}
];
};
};
};
};
}
HAProxy
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
setcap cap_sys_admin
daemon
listen frontend
mode http
bind :80 namespace public
use_backend app
backend app
mode http
default-server namespace backend
server server1 10.0.0.11:8000
server server2 10.0.0.12:8000
{
services.haproxy = {
enable = true;
config = ''
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
setcap cap_sys_admin
daemon
listen frontend
mode http
bind :80 namespace public
use_backend app
backend app
mode http
default-server namespace backend
server server1 10.0.0.11:8000
server server2 10.0.0.12:8000
'';
};
}