KOVACS Krisztian | b3e54fe | 2014-11-17 15:11:45 +0100 | [diff] [blame] | 1 | Linux network namespace support for HAProxy |
| 2 | =========================================== |
| 3 | |
| 4 | HAProxy supports proxying between Linux network namespaces. This |
| 5 | feature can be used, for example, in a multi-tenant networking |
| 6 | environment to proxy between different networks. HAProxy can also act |
| 7 | as a front-end proxy for non namespace-aware services. |
| 8 | |
| 9 | The proxy protocol has been extended to support transferring the |
| 10 | namespace information, so the originating namespace information can be |
| 11 | kept. This is useful when chaining multiple proxies and services. |
| 12 | |
| 13 | To enable Linux namespace support, compile HAProxy with the `USE_NS=1` |
| 14 | make option. |
| 15 | |
| 16 | |
| 17 | ## Setting up namespaces on Linux |
| 18 | |
| 19 | To create network namespaces, use the 'ip netns' command. See the |
| 20 | manual page ip-netns(8) for details. |
| 21 | |
| 22 | Make sure that the file descriptors representing the network namespace |
| 23 | are located under `/var/run/netns`. |
| 24 | |
| 25 | For example, you can create a network namespace and assign one of the |
| 26 | networking interfaces to the new namespace: |
| 27 | |
| 28 | ``` |
| 29 | $ ip netns add netns1 |
| 30 | $ ip link set eth7 netns netns1 |
| 31 | ``` |
| 32 | |
| 33 | |
| 34 | ## Listing namespaces in the configuration file |
| 35 | |
| 36 | HAProxy uses namespaces explicitly listed in its configuration file. |
| 37 | If you are not using namespace information received through the proxy |
| 38 | protocol, this usually means that you must specify namespaces for |
| 39 | listeners and servers in the configuration file with the 'namespace' |
| 40 | keyword. |
| 41 | |
| 42 | However, if you're using the namespace information received through |
| 43 | the proxy protocol to determine the namespace of servers (see |
| 44 | 'namespace * below'), you have to explicitly list all allowed |
| 45 | namespaces in the namespace_list section of your configuration file: |
| 46 | |
| 47 | ``` |
| 48 | namespace_list |
| 49 | namespace netns1 |
| 50 | namespace netns2 |
| 51 | ``` |
| 52 | |
| 53 | |
| 54 | ## Namespace information flow |
| 55 | |
| 56 | The haproxy process always runs in the namespace it was started on. |
| 57 | This is the default namespace. |
| 58 | |
| 59 | The bind addresses of listeners can have their namespace specified in |
| 60 | the configuration file. Unless specified, sockets associated with |
| 61 | listener bind addresses are created in the default namespace. For |
| 62 | example, this creates a listener in the netns2 namespace: |
| 63 | |
| 64 | ``` |
| 65 | frontend f_example |
| 66 | bind 192.168.1.1:80 namespace netns2 |
| 67 | default_backend http |
| 68 | ``` |
| 69 | |
| 70 | Each client connection is associated with its source namespace. By |
| 71 | default, this is the namespace of the bind socket it arrived on, but |
| 72 | can be overridden by information received through the proxy protocol. |
| 73 | Proxy protocol v2 supports transferring namespace information, so if |
| 74 | it is enabled for the listener, it can override the associated |
| 75 | namespace of the connection. |
| 76 | |
| 77 | Servers can have their namespaces specified in the configuration file |
| 78 | with the 'namespace' keyword: |
| 79 | |
| 80 | ``` |
| 81 | backend b_example |
| 82 | server s1 192.168.1.100:80 namespace netns2 |
| 83 | ``` |
| 84 | |
| 85 | If no namespace is set for a server, it is assumed that it is in the |
| 86 | default namespace. When specified, outbound sockets to the server are |
| 87 | created in the network namespace configured. To create the outbound |
| 88 | (server) connection in the namespace associated with the client, use |
| 89 | the '*' namespace. This is especially useful when using the |
| 90 | destination address and namespace received from the proxy protocol. |
| 91 | |
| 92 | ``` |
| 93 | frontend f_example |
| 94 | bind 192.168.1.1:9990 accept-proxy |
| 95 | default_backend b_example |
| 96 | |
| 97 | backend b_example |
| 98 | mode tcp |
| 99 | source 0.0.0.0 usesrc clientip |
| 100 | server snodes * namespace * |
| 101 | ``` |
| 102 | |
| 103 | If HAProxy is configured to send proxy protocol v2 headers to the |
| 104 | server, the outgoing header will always contain the namespace |
| 105 | associated with the client connection, not the namespace configured |
| 106 | for the server. |