107 lines
3.5 KiB
Plaintext
107 lines
3.5 KiB
Plaintext
Linux network namespace support for HAProxy
|
|
===========================================
|
|
|
|
HAProxy supports proxying between Linux network namespaces. This
|
|
feature can be used, for example, in a multi-tenant networking
|
|
environment to proxy between different networks. HAProxy can also act
|
|
as a front-end proxy for non namespace-aware services.
|
|
|
|
The proxy protocol has been extended to support transferring the
|
|
namespace information, so the originating namespace information can be
|
|
kept. This is useful when chaining multiple proxies and services.
|
|
|
|
To enable Linux namespace support, compile HAProxy with the `USE_NS=1`
|
|
make option.
|
|
|
|
|
|
## Setting up namespaces on Linux
|
|
|
|
To create network namespaces, use the 'ip netns' command. See the
|
|
manual page ip-netns(8) for details.
|
|
|
|
Make sure that the file descriptors representing the network namespace
|
|
are located under `/var/run/netns`.
|
|
|
|
For example, you can create a network namespace and assign one of the
|
|
networking interfaces to the new namespace:
|
|
|
|
```
|
|
$ ip netns add netns1
|
|
$ ip link set eth7 netns netns1
|
|
```
|
|
|
|
|
|
## Listing namespaces in the configuration file
|
|
|
|
HAProxy uses namespaces explicitly listed in its configuration file.
|
|
If you are not using namespace information received through the proxy
|
|
protocol, this usually means that you must specify namespaces for
|
|
listeners and servers in the configuration file with the 'namespace'
|
|
keyword.
|
|
|
|
However, if you're using the namespace information received through
|
|
the proxy protocol to determine the namespace of servers (see
|
|
'namespace * below'), you have to explicitly list all allowed
|
|
namespaces in the namespace_list section of your configuration file:
|
|
|
|
```
|
|
namespace_list
|
|
namespace netns1
|
|
namespace netns2
|
|
```
|
|
|
|
|
|
## Namespace information flow
|
|
|
|
The haproxy process always runs in the namespace it was started on.
|
|
This is the default namespace.
|
|
|
|
The bind addresses of listeners can have their namespace specified in
|
|
the configuration file. Unless specified, sockets associated with
|
|
listener bind addresses are created in the default namespace. For
|
|
example, this creates a listener in the netns2 namespace:
|
|
|
|
```
|
|
frontend f_example
|
|
bind 192.168.1.1:80 namespace netns2
|
|
default_backend http
|
|
```
|
|
|
|
Each client connection is associated with its source namespace. By
|
|
default, this is the namespace of the bind socket it arrived on, but
|
|
can be overridden by information received through the proxy protocol.
|
|
Proxy protocol v2 supports transferring namespace information, so if
|
|
it is enabled for the listener, it can override the associated
|
|
namespace of the connection.
|
|
|
|
Servers can have their namespaces specified in the configuration file
|
|
with the 'namespace' keyword:
|
|
|
|
```
|
|
backend b_example
|
|
server s1 192.168.1.100:80 namespace netns2
|
|
```
|
|
|
|
If no namespace is set for a server, it is assumed that it is in the
|
|
default namespace. When specified, outbound sockets to the server are
|
|
created in the network namespace configured. To create the outbound
|
|
(server) connection in the namespace associated with the client, use
|
|
the '*' namespace. This is especially useful when using the
|
|
destination address and namespace received from the proxy protocol.
|
|
|
|
```
|
|
frontend f_example
|
|
bind 192.168.1.1:9990 accept-proxy
|
|
default_backend b_example
|
|
|
|
backend b_example
|
|
mode tcp
|
|
source 0.0.0.0 usesrc clientip
|
|
server snodes * namespace *
|
|
```
|
|
|
|
If HAProxy is configured to send proxy protocol v2 headers to the
|
|
server, the outgoing header will always contain the namespace
|
|
associated with the client connection, not the namespace configured
|
|
for the server.
|