2017-08-31 18:19:08 +00:00
---
2020-04-07 18:55:19 +00:00
layout: docs
page_title: Partial LAN Connectivity - Configuring Network Segments
sidebar_current: docs-guides-segments
description: >-
Many advanced Consul users have the need to run clusters with segmented
networks, meaning that
not all agents can be in a full mesh. This is usually the result of business
policies enforced
via network rules or firewalls. Prior to Consul 0.9.3 this was only possible
through federation,
which for some users is too heavyweight or expensive as it requires running
multiple servers per
2017-08-31 18:19:08 +00:00
segment.
---
2019-03-21 14:35:49 +00:00
# Network Segments [Enterprise Only]
2017-09-01 18:19:39 +00:00
2019-03-21 14:35:49 +00:00
~> Note, the network segment functionality described here is available only in [Consul Enterprise](https://www.hashicorp.com/products/consul/) version 0.9.3 and later.
2017-08-31 18:19:08 +00:00
Many advanced Consul users have the need to run clusters with segmented networks, meaning that
not all agents can be in a full mesh. This is usually the result of business policies enforced
via network rules or firewalls. Prior to Consul 0.9.3 this was only possible through federation,
which for some users is too heavyweight or expensive as it requires running multiple servers per
segment.
2019-03-21 14:35:49 +00:00
This guide will cover the basic configuration for setting up multiple segments, as well as
how to configure a prepared query to limit service discovery to the services in the local agent's
network segment.
2020-04-06 20:27:35 +00:00
To complete this guide you will need to complete the
2019-03-21 14:35:49 +00:00
[Deployment Guide](https://learn.hashicorp.com/consul/advanced/day-1-operations/deployment-guide).
## Partial LAN Connectivity with Network Segments
2017-08-31 18:19:08 +00:00
By default, all Consul agents in one datacenter are part of a shared gossip pool over the LAN;
this means that the partial connectivity caused by segmented networks would cause health flapping
as nodes failed to communicate. In this guide we will cover the Network Segments feature, added
in [Consul Enterprise](https://www.hashicorp.com/products/consul/) version 0.9.3, which allows users
to configure Consul to support this kind of segmented network topology.
2019-03-21 14:35:49 +00:00
### Network Segments Overview
All Consul agents are part of the default network segment, unless a segment is specified in
their configuration. In a standard cluster setup, all agents will normally be part of this default
2020-04-06 20:27:35 +00:00
segment and as a result, part of one shared LAN gossip pool.
2017-08-31 18:19:08 +00:00
2019-03-21 14:35:49 +00:00
Network segments can be used to break
2017-08-31 18:19:08 +00:00
up the LAN gossip pool into multiple isolated smaller pools by specifying the configuration for segments
on the servers. Each desired segment must be given a name and port, as well as optionally a custom
bind and advertise address for that segment's gossip listener to bind to on the server.
A few things to note:
2017-09-01 18:19:39 +00:00
2017-08-31 18:19:08 +00:00
1. Servers will be a part of all segments they have been configured with. They are the common point
2020-04-06 20:27:35 +00:00
linking the different segments together. The configured list of segments is specified by the
2020-04-09 23:46:54 +00:00
[`segments`](/docs/agent/options#segments) option.
2017-09-01 18:19:39 +00:00
2020-04-09 23:46:54 +00:00
2. Client agents can only be part of one segment at a given time, specified by the [`-segment`](/docs/agent/options#_segment) option.
2017-09-01 18:19:39 +00:00
2017-08-31 18:19:08 +00:00
3. Clients can only join agents in the same segment as them. If they attempt to join a client in
2020-04-06 20:27:35 +00:00
another segment, or the listening port of another segment on a server, they will get a segment mismatch error.
2017-08-31 18:19:08 +00:00
Once the servers have been configured with the correct segment info, the clients only need to specify
2020-04-09 23:46:54 +00:00
their own segment in the [Agent Config](/docs/agent/options#_segment) and join by connecting to another
2017-09-01 00:39:57 +00:00
agent within the same segment. If joining to a Consul server, client will need to provide the server's
port for their segment along with the address of the server when performing the join (for example,
`consul agent -retry-join "consul.domain.internal:1234"`).
2017-08-31 18:19:08 +00:00
2019-03-21 14:35:49 +00:00
## Setup Network Segments
### Configure Consul Servers
2017-08-31 18:19:08 +00:00
2020-04-06 20:27:35 +00:00
To get started,
2019-03-21 14:35:49 +00:00
start a server or group of servers, with the following section added to the configuration. Note, you may need to
adjust the bind/advertise addresses for your setup.
2017-08-31 18:19:08 +00:00
```json
{
"segments": [
2020-04-06 20:27:35 +00:00
{
"name": "alpha",
"bind": "{{GetPrivateIP}}",
"advertise": "{{GetPrivateIP}}",
"port": 8303
},
{
"name": "beta",
"bind": "{{GetPrivateIP}}",
"advertise": "{{GetPrivateIP}}",
"port": 8304
}
2017-08-31 18:19:08 +00:00
]
}
```
2019-03-21 14:35:49 +00:00
You should see a log message on the servers for each segment's listener as the agent starts up.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1.dc1 192.168.0.4
2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1 192.168.0.4
2017/08/30 19:05:13 [INFO] consul: Started listener for LAN segment "alpha" on 192.168.0.4:8303
2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1 192.168.0.4
2017/08/30 19:05:13 [INFO] consul: Started listener for LAN segment "beta" on 192.168.0.4:8304
2017/08/30 19:05:13 [INFO] serf: EventMemberJoin: server1 192.168.0.4
```
2019-03-21 14:35:49 +00:00
Running `consul members` should show the server as being part of all segments.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(server1) $ consul members
Node Address Status Type Build Protocol DC Segment
server1 192.168.0.4:8301 alive server 0.9.3+ent 2 dc1 <all>
```
2020-04-06 20:27:35 +00:00
### Configure Consul Clients in Different Network Segments
2019-03-21 14:35:49 +00:00
2017-08-31 18:19:08 +00:00
Next, start a client agent in the 'alpha' segment, with `-join` set to the server's segment
2019-03-21 14:35:49 +00:00
address/port for that segment.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(client1) $ consul agent ... -join 192.168.0.4:8303 -node client1 -segment alpha
```
After the join is successful, we should see the client show up by running the `consul members` command
2019-03-21 14:35:49 +00:00
on the server again.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(server1) $ consul members
Node Address Status Type Build Protocol DC Segment
server1 192.168.0.4:8301 alive server 0.9.3+ent 2 dc1 <all>
client1 192.168.0.5:8301 alive client 0.9.3+ent 2 dc1 alpha
```
2019-03-21 14:35:49 +00:00
Now join another client in segment 'beta' and run the `consul members` command another time.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(client2) $ consul agent ... -join 192.168.0.4:8304 -node client2 -segment beta
```
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(server1) $ consul members
Node Address Status Type Build Protocol DC Segment
server1 192.168.0.4:8301 alive server 0.9.3+ent 2 dc1 <all>
client1 192.168.0.5:8301 alive client 0.9.3+ent 2 dc1 alpha
client2 192.168.0.6:8301 alive client 0.9.3+ent 2 dc1 beta
```
2019-03-21 14:35:49 +00:00
### Filter Segmented Nodes
2017-08-31 18:19:08 +00:00
If we pass the `-segment` flag when running `consul members`, we can limit the view to agents
2019-03-21 14:35:49 +00:00
in a specific segment.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(server1) $ consul members -segment alpha
Node Address Status Type Build Protocol DC Segment
client1 192.168.0.5:8301 alive client 0.9.3+ent 2 dc1 alpha
server1 192.168.0.4:8303 alive server 0.9.3+ent 2 dc1 alpha
```
Using the `consul catalog nodes` command, we can filter on an internal metadata key,
2019-03-21 14:35:49 +00:00
`consul-network-segment`, which stores the network segment of the node.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(server1) $ consul catalog nodes -node-meta consul-network-segment=alpha
Node ID Address DC
client1 4c29819c 192.168.0.5 dc1
```
2020-04-09 23:46:54 +00:00
With this metadata key, we can construct a [Prepared Query](/api/query) that can be used
2017-09-01 00:39:57 +00:00
for DNS to return only services within the same network segment as the local agent.
2017-08-31 18:19:08 +00:00
2019-03-21 14:35:49 +00:00
## Configure a Prepared Query to Limit Service Discovery
### Create Services
2017-08-31 18:19:08 +00:00
2019-03-21 14:35:49 +00:00
First, register a service on each of the client nodes.
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(client1) $ curl \
--request PUT \
--data '{"Name": "redis", "Port": 8000}' \
localhost:8500/v1/agent/service/register
```
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(client2) $ curl \
--request PUT \
--data '{"Name": "redis", "Port": 9000}' \
localhost:8500/v1/agent/service/register
```
2019-03-21 14:35:49 +00:00
### Create the Prepared Query
Next, write the following to `query.json` and create the query using the HTTP endpoint.
2017-08-31 18:19:08 +00:00
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(server1) $ curl \
--request POST \
--data \
'{
"Name": "",
"Template": {
"Type": "name_prefix_match"
},
"Service": {
"Service": "${name.full}",
"NodeMeta": {"consul-network-segment": "${agent.segment}"}
}
}' localhost:8500/v1/query
{"ID":"6f49dd24-de9b-0b6c-fd29-525eca069419"}
```
2019-03-21 14:35:49 +00:00
### Test the Segments with DNS Lookups
2017-08-31 18:19:08 +00:00
Now, we can replace any dns lookups of the form `<service>.service.consul` with
2019-03-21 14:35:49 +00:00
`<service>.query.consul` to look up only services within the same network segment.
2017-08-31 18:19:08 +00:00
**Client 1:**
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(client1) $ dig @127.0.0.1 -p 8600 redis.query.consul SRV
; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 redis.query.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3149
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;redis.query.consul. IN SRV
;; ANSWER SECTION:
redis.query.consul. 0 IN SRV 1 1 8000 client1.node.dc1.consul.
;; ADDITIONAL SECTION:
client1.node.dc1.consul. 0 IN A 192.168.0.5
```
**Client 2:**
2020-04-07 23:56:08 +00:00
```shell
2017-08-31 18:19:08 +00:00
(client2) $ dig @127.0.0.1 -p 8600 redis.query.consul SRV
; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 redis.query.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3149
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;redis.query.consul. IN SRV
;; ANSWER SECTION:
redis.query.consul. 0 IN SRV 1 1 9000 client2.node.dc1.consul.
;; ADDITIONAL SECTION:
client2.node.dc1.consul. 0 IN A 192.168.0.6
2017-09-06 23:42:13 +00:00
```
2019-03-21 14:35:49 +00:00
## Summary
2020-04-06 20:27:35 +00:00
In this guide you configured the Consul agents to participate in partial
2019-03-21 14:35:49 +00:00
LAN gossip based on network segments. You then set up a couple services and
2020-04-06 20:27:35 +00:00
a prepared query to test the segments.