github.com/outbrain/consul@v1.4.5/website/source/docs/guides/segments.html.markdown.erb (about)

     1  ---
     2  layout: "docs"
     3  page_title: "Partial LAN Connectivity - Configuring Network Segments"
     4  sidebar_current: "docs-guides-segments"
     5  description: |-
     6    Many advanced Consul users have the need to run clusters with segmented networks, meaning that
     7    not all agents can be in a full mesh. This is usually the result of business policies enforced
     8    via network rules or firewalls. Prior to Consul 0.9.3 this was only possible through federation,
     9    which for some users is too heavyweight or expensive as it requires running multiple servers per
    10    segment.
    11  ---
    12  
    13  # Network Segments
    14  
    15  ## Partial LAN Connectivity with Network Segments
    16  
    17  [//]: # ( ~> The network segment functionality described here is available only in )
    18  [//]: # (   [Consul Enterprise](https://www.hashicorp.com/products/consul/) version 0.9.3 and later. )
    19  
    20  <%= enterprise_alert :consul %>
    21  
    22  Many advanced Consul users have the need to run clusters with segmented networks, meaning that
    23  not all agents can be in a full mesh. This is usually the result of business policies enforced
    24  via network rules or firewalls. Prior to Consul 0.9.3 this was only possible through federation,
    25  which for some users is too heavyweight or expensive as it requires running multiple servers per
    26  segment.
    27  
    28  By default, all Consul agents in one datacenter are part of a shared gossip pool over the LAN;
    29  this means that the partial connectivity caused by segmented networks would cause health flapping
    30  as nodes failed to communicate. In this guide we will cover the Network Segments feature, added
    31  in [Consul Enterprise](https://www.hashicorp.com/products/consul/) version 0.9.3, which allows users
    32  to configure Consul to support this kind of segmented network topology.
    33  
    34  This guide will cover the basic configuration for setting up multiple segments, as well as
    35  how to configure a prepared query to limit service discovery to the services in the local agent's
    36  network segment.
    37  
    38  ## Configuring Network Segments
    39  
    40  All Consul agents are part of the default network segment, `""`, unless a segment is specified in
    41  their configuration. In a standard cluster setup all agents will normally be part of this default
    42  segment and as a result, part of one shared LAN gossip pool. Network segments can be used to break
    43  up the LAN gossip pool into multiple isolated smaller pools by specifying the configuration for segments
    44  on the servers. Each desired segment must be given a name and port, as well as optionally a custom
    45  bind and advertise address for that segment's gossip listener to bind to on the server.
    46  
    47  A few things to note:
    48  
    49  1. Servers will be a part of all segments they have been configured with. They are the common point
    50  linking the different segments together. The configured list of segments is specified by the
    51  [`segments`](/docs/agent/options.html#segments) option.
    52  
    53  2. Client agents can only be part of one segment at a given time, specified by the [`-segment`]
    54  (/docs/agent/options.html#_segment) option.
    55  
    56  3. Clients can only join agents in the same segment as them. If they attempt to join a client in
    57  another segment, or the listening port of another segment on a server, they will get a segment mismatch error.
    58  
    59  Once the servers have been configured with the correct segment info, the clients only need to specify
    60  their own segment in the [Agent Config](/docs/agent/options.html#_segment) and join by connecting to another
    61  agent within the same segment. If joining to a Consul server, client will need to provide the server's
    62  port for their segment along with the address of the server when performing the join (for example,
    63  `consul agent -retry-join "consul.domain.internal:1234"`).
    64  
    65  ## Getting Started
    66  
    67  To get started, follow the [bootstrapping guide](/docs/guides/bootstrapping.html) to
    68  start a server or group of servers, with the following section added to the configuration (you may need to
    69  adjust the bind/advertise addresses for your setup):
    70  
    71  ```json
    72  {
    73  ...
    74    "segments": [
    75      {"name": "alpha", "bind": "{{GetPrivateIP}}", "advertise": "{{GetPrivateIP}}", "port": 8303},
    76      {"name": "beta", "bind": "{{GetPrivateIP}}", "advertise": "{{GetPrivateIP}}", "port": 8304}
    77    ]
    78  }
    79  ```
    80  
    81  You should see a log message on the servers for each segment's listener as the agent starts up:
    82  
    83  ```text
    84  2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1.dc1 192.168.0.4
    85  2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1 192.168.0.4
    86  2017/08/30 19:05:13 [INFO] consul: Started listener for LAN segment "alpha" on 192.168.0.4:8303
    87  2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1 192.168.0.4
    88  2017/08/30 19:05:13 [INFO] consul: Started listener for LAN segment "beta" on 192.168.0.4:8304
    89  2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1 192.168.0.4
    90  ```
    91  
    92  Running `consul members` should show the server as being part of all segments:
    93  
    94  ```text
    95  (server1) $ consul members
    96  Node     Address           Status  Type    Build      Protocol  DC   Segment
    97  server1  192.168.0.4:8301  alive   server  0.9.3+ent  2         dc1  <all>
    98  ```
    99  
   100  Next, start a client agent in the 'alpha' segment, with `-join` set to the server's segment
   101  address/port for that segment:
   102  
   103  ```text
   104  (client1) $ consul agent ... -join 192.168.0.4:8303 -node client1 -segment alpha
   105  ```
   106  
   107  After the join is successful, we should see the client show up by running the `consul members` command
   108  on the server again:
   109  
   110  ```text
   111  (server1) $ consul members
   112  Node     Address           Status  Type    Build      Protocol  DC   Segment
   113  server1  192.168.0.4:8301  alive   server  0.9.3+ent  2         dc1  <all>
   114  client1  192.168.0.5:8301  alive   client  0.9.3+ent  2         dc1  alpha
   115  ```
   116  
   117  Now join another client in segment 'beta' and run the `consul members` command another time:
   118  
   119  ```text
   120  (client2) $ consul agent ... -join 192.168.0.4:8304 -node client2 -segment beta
   121  ```
   122  
   123  ```text
   124  (server1) $ consul members
   125  Node     Address           Status  Type    Build      Protocol  DC   Segment
   126  server1  192.168.0.4:8301  alive   server  0.9.3+ent  2         dc1  <all>
   127  client1  192.168.0.5:8301  alive   client  0.9.3+ent  2         dc1  alpha
   128  client2  192.168.0.6:8301  alive   client  0.9.3+ent  2         dc1  beta
   129  ```
   130  
   131  If we pass the `-segment` flag when running `consul members`, we can limit the view to agents
   132  in a specific segment:
   133  
   134  ```text
   135  (server1) $ consul members -segment alpha
   136  Node     Address           Status  Type    Build      Protocol  DC   Segment
   137  client1  192.168.0.5:8301  alive   client  0.9.3+ent  2         dc1  alpha
   138  server1  192.168.0.4:8303  alive   server  0.9.3+ent  2         dc1  alpha
   139  ```
   140  
   141  Using the `consul catalog nodes` command, we can filter on an internal metadata key,
   142  `consul-network-segment`, which stores the network segment of the node:
   143  
   144  ```text
   145  (server1) $ consul catalog nodes -node-meta consul-network-segment=alpha
   146  Node     ID        Address      DC
   147  client1  4c29819c  192.168.0.5  dc1
   148  ```
   149  
   150  With this metadata key, we can construct a [Prepared Query](/api/query.html) that can be used
   151  for DNS to return only services within the same network segment as the local agent.
   152  
   153  First, register a service on each of the client nodes:
   154  
   155  ```text
   156  (client1) $ curl \
   157      --request PUT \
   158      --data '{"Name": "redis", "Port": 8000}' \
   159      localhost:8500/v1/agent/service/register
   160  ```
   161  
   162  ```text
   163  (client2) $ curl \
   164      --request PUT \
   165      --data '{"Name": "redis", "Port": 9000}' \
   166      localhost:8500/v1/agent/service/register
   167  ```
   168  
   169  Next, write the following to `query.json` and create the query using the HTTP endpoint:
   170  
   171  ```text
   172  (server1) $ curl \
   173      --request POST \
   174      --data \
   175  '{
   176     "Name": "",
   177     "Template": {
   178       "Type": "name_prefix_match"
   179     },
   180     "Service": {
   181       "Service": "${name.full}",
   182       "NodeMeta": {"consul-network-segment": "${agent.segment}"}
   183     }
   184  }' localhost:8500/v1/query
   185  
   186  {"ID":"6f49dd24-de9b-0b6c-fd29-525eca069419"}
   187  ```
   188  
   189  Now, we can replace any dns lookups of the form `<service>.service.consul` with
   190  `<service>.query.consul` to look up only services within the same network segment:
   191  
   192  **Client 1:**
   193  
   194  ```text
   195  (client1) $ dig @127.0.0.1 -p 8600 redis.query.consul SRV
   196  
   197  ; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 redis.query.consul SRV
   198  ; (1 server found)
   199  ;; global options: +cmd
   200  ;; Got answer:
   201  ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3149
   202  ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
   203  ;; WARNING: recursion requested but not available
   204  
   205  ;; QUESTION SECTION:
   206  ;redis.query.consul.		IN	SRV
   207  
   208  ;; ANSWER SECTION:
   209  redis.query.consul.	0	IN	SRV	1 1 8000 client1.node.dc1.consul.
   210  
   211  ;; ADDITIONAL SECTION:
   212  client1.node.dc1.consul. 0	IN	A	192.168.0.5
   213  ```
   214  
   215  **Client 2:**
   216  
   217  ```text
   218  (client2) $ dig @127.0.0.1 -p 8600 redis.query.consul SRV
   219  
   220  ; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 redis.query.consul SRV
   221  ; (1 server found)
   222  ;; global options: +cmd
   223  ;; Got answer:
   224  ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3149
   225  ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
   226  ;; WARNING: recursion requested but not available
   227  
   228  ;; QUESTION SECTION:
   229  ;redis.query.consul.		IN	SRV
   230  
   231  ;; ANSWER SECTION:
   232  redis.query.consul.	0	IN	SRV	1 1 9000 client2.node.dc1.consul.
   233  
   234  ;; ADDITIONAL SECTION:
   235  client2.node.dc1.consul. 0	IN	A	192.168.0.6
   236  ```