Install and configure Consul.
Firewall configuration
Install a dynamically managed firewall daemon.
$ sudo apt install firewalld
List network interfaces.
$ ip --brief address
lo UNKNOWN 127.0.0.1/8 ::1/128 ens18 UP 172.16.151.111/21 metric 100 fe80::5cf7:3aff:fe6a:b34e/64
Add network interface to the public zone.
$ sudo firewall-cmd --add-interface ens18 --zone public
success
Inspect public zone.
$ sudo firewall-cmd --list-all --zone=public
public target: default icmp-block-inversion: no interfaces: ens18 sources: services: dhcpv6-client ssh ports: protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
On consul server open Server RPC port that will be used to handle requests incoming from other agents.
$ sudo firewall-cmd --add-port 8300/tcp --zone public
On consul server and agent open The Serf LAN port to handle gossip in the LAN.
$ sudo firewall-cmd --add-port 8301/tcp --zone public
$ sudo firewall-cmd --add-port 8301/udp --zone public
Inspect current configuration.
$ sudo firewall-cmd --list-all --zone=public
public (active) target: default icmp-block-inversion: no interfaces: ens18 sources: services: dhcpv6-client ssh ports: 8300/tcp 8301/tcp 8301/udp protocols: forward: yes masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Ensure that firewall configuration is permanent.
$ sudo firewall-cmd --runtime-to-permanent
Inspect service status.
$ systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2022-07-14 19:25:11 UTC; 49s ago Docs: man:firewalld(1) Main PID: 5033 (firewalld) Tasks: 4 (limit: 2241) Memory: 25.3M CPU: 746ms CGroup: /system.slice/firewalld.service └─5033 /usr/bin/python3 /usr/sbin/firewalld --nofork --nopid Jul 14 19:25:11 mgmt systemd[1]: Starting firewalld - dynamic firewall daemon... Jul 14 19:25:11 mgmt systemd[1]: Started firewalld - dynamic firewall daemon.
This is a minimal firewall configuration as there are other ports.
Install Consul application
Install dependencies.
$ sudo apt install curl unzip
Visit downloads page and download linux binary.
$ curl --silent \ --remote-name \ --output-dir /tmp \ https://releases.hashicorp.com/consul/1.12.3/consul_1.12.3_linux_amd64.zip
Move archive to persistent location.
$ sudo mv /tmp/consul_1.12.3_linux_amd64.zip /opt/
Inspect downloaded archive.
$ unzip -l /opt/consul_1.12.3_linux_amd64.zip
Archive: /opt/consul_1.12.3_linux_amd64.zip Length Date Time Name --------- ---------- ----- ---- 118259119 2022-07-13 21:19 consul --------- ------- 118259119 1 file
Extract consul binary.
$ sudo unzip -d /usr/bin /opt/consul_1.12.3_linux_amd64.zip consul
Archive: /opt/consul_1.12.3_linux_amd64.zip inflating: /usr/bin/consul
Inspect binary file permissions.
$ ls -l /usr/bin/consul
-rwxr-xr-x 1 root root 118259119 Jul 13 21:19 /usr/bin/consul
Create consul group.
$ sudo groupadd --gid 863 consul
Create consul user.
$ sudo useradd --uid 863 --gid 863 \ --shell /bin/false \ --home-dir /etc/consul.d --no-create-home \ consul
Create configuration directory.
$ sudo install --directory --group consul --owner consul --mode 700 /etc/consul.d
Create data directory.
$ sudo install --directory --group consul --owner consul --mode 700 /opt/consul
Create log directory.
$ sudo install --directory --group consul --owner consul --mode 700 /var/log/consul
Create empty environment file.
$ sudo -u consul touch /etc/consul.d/consul.env
Create empty configuration.
$ sudo -u consul touch /etc/consul.d/consul.hcl
Create systemd service – it is the official packaged one.
$ sudo tee /usr/lib/systemd/system/consul.service << 'EOF' [Unit] Description="HashiCorp Consul - A service mesh solution" Documentation=https://www.consul.io/ Requires=network-online.target After=network-online.target ConditionFileNotEmpty=/etc/consul.d/consul.hcl [Service] EnvironmentFile=-/etc/consul.d/consul.env User=consul Group=consul ExecStart=/usr/bin/consul agent -config-dir=/etc/consul.d/ ExecReload=/bin/kill --signal HUP $MAINPID KillMode=process KillSignal=SIGTERM Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
[Unit] Description="HashiCorp Consul - A service mesh solution" Documentation=https://www.consul.io/ Requires=network-online.target After=network-online.target ConditionFileNotEmpty=/etc/consul.d/consul.hcl [Service] EnvironmentFile=-/etc/consul.d/consul.env User=consul Group=consul ExecStart=/usr/bin/consul agent -config-dir=/etc/consul.d/ ExecReload=/bin/kill --signal HUP $MAINPID KillMode=process KillSignal=SIGTERM Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target
Reload systemd configuration.
$ sudo systemctl --system daemon-reload
Inspect service status.
$ systemctl status consul
○ consul.service - "HashiCorp Consul - A service mesh solution" Loaded: loaded (/lib/systemd/system/consul.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: https://www.consul.io/
Inspect consul version.
$ consul version
Consul v1.12.3 Revision 2308c75e Protocol 2 spoken by default, understands 2 to 3 (agent will automatically use protocol >2 when speaking to compatible agents)
Configure server application
Create server configuration. You can split it into multiple files, it is just easier to present it now this way.
$ sudo -u consul tee /etc/consul.d/consul.hcl << EOF # datacenter datacenter = "dc-lab-1" # data directory data_dir = "/opt/consul" # server mode server = true # bind address bind_addr = "0.0.0.0" # single-node server bootstrap = true # number of expected servers in the datacenter #bootstrap_expect = 3 # servers in the datacenter #retry_join = ["172.16.151.117", "172.16.151.118", "172.16.151.119"] # logging log_level = "info" log_file = "/var/log/consul/" log_rotate_duration = "24h" log_rotate_max_files = 30 EOF
Validate configuration.
$ sudo -u consul consul validate /etc/consul.d
skipping file /etc/consul.d/consul.env, extension must be .hcl or .json, or config format must be set bootstrap_expect > 0: expecting 3 servers Configuration is valid!
Enable server service.
$ sudo systemctl enable --now consul
Created symlink /etc/systemd/system/multi-user.target.wants/consul.service → /lib/systemd/system/consul.service.
Inspect service status.
$ systemctl status consul
● consul.service - "HashiCorp Consul - A service mesh solution" Loaded: loaded (/lib/systemd/system/consul.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2022-07-14 18:44:08 UTC; 1min 13s ago Docs: https://www.consul.io/ Main PID: 4208 (consul) Tasks: 9 (limit: 2241) Memory: 26.6M CPU: 324ms CGroup: /system.slice/consul.service └─4208 /usr/bin/consul agent -config-dir=/etc/consul.d/ Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.176Z [INFO] agent.leader: started routine: routine="intermediate cert renew watch" Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.176Z [INFO] agent.leader: started routine: routine="CA root pruning" Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.176Z [INFO] agent.leader: started routine: routine="CA root expiration metric" Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.176Z [INFO] agent.leader: started routine: routine="CA signing expiration metric" Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.176Z [INFO] agent.leader: started routine: routine="virtual IP version check" Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.184Z [INFO] agent.server: member joined, marking health alive: member=jammy partition=default Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.186Z [INFO] agent.leader: stopping routine: routine="virtual IP version check" Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.186Z [INFO] agent.leader: stopped routine: routine="virtual IP version check" Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.194Z [INFO] agent.server: federation state anti-entropy synced Jul 14 18:44:14 jammy consul[4208]: 2022-07-14T18:44:14.530Z [INFO] agent: Synced node info
List cluster members.
$ consul members
Node Address Status Type Build Protocol DC Partition Segment jammy 172.16.151.111:8301 alive server 1.12.3 2 dc-lab-1 default <all>
List current raft peers.
$ consul operator raft list-peers
Node ID Address State Voter RaftProtocol jammy 1c49ba0a-8bac-78bb-18f4-34df6adca9cd 172.16.151.111:8300 leader true 3
Configure other servers the same way, just remove bootstrap
and uncomment bootstrap_expect
and retry_join
options.
Configure Consul web user interface
Install Consul on different machine and configure it.
Create server configuration.
$ sudo -u consul tee /etc/consul.d/consul.hcl << EOF # datacenter datacenter = "dc-lab-1" # data directory data_dir = "/opt/consul" # servers in the datacenter retry_join = ["172.16.151.111"] # logging log_level = "info" log_file = "/var/log/consul/" log_rotate_duration = "24h" log_rotate_max_files = 30 ui_config{ enabled = true } EOF
Enable agent service.
$ sudo systemctl enable --now consul
Created symlink /etc/systemd/system/multi-user.target.wants/consul.service → /lib/systemd/system/consul.service.
Inspect service status.
$ systemctl status consul
● consul.service - "HashiCorp Consul - A service mesh solution" Loaded: loaded (/lib/systemd/system/consul.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2022-07-14 19:23:54 UTC; 33s ago Docs: https://www.consul.io/ Main PID: 2206 (consul) Tasks: 8 (limit: 2241) Memory: 21.4M CPU: 205ms CGroup: /system.slice/consul.service └─2206 /usr/bin/consul agent -config-dir=/etc/consul.d/ Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.795Z [INFO] agent: Retry join is supported for the following discovery methods: cluster=LAN discovery_methods="aliyun aws azure digita> Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.795Z [INFO] agent: Joining cluster...: cluster=LAN Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.795Z [INFO] agent: (LAN) joining: lan_addresses=[172.16.151.111] Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.795Z [WARN] agent.router.manager: No servers available Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.796Z [ERROR] agent.anti_entropy: failed to sync remote state: error="No known Consul servers" Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.797Z [INFO] agent.client.serf.lan: serf: EventMemberJoin: jammy 172.16.151.111 Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.797Z [INFO] agent: (LAN) joined: number_of_nodes=1 Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.797Z [INFO] agent: Join cluster completed. Synced with initial agents: cluster=LAN num_agents=1 Jul 14 19:23:54 mgmt consul[2206]: 2022-07-14T19:23:54.797Z [INFO] agent.client: adding server: server="jammy (Addr: tcp/172.16.151.111:8300) (DC: dc-lab-1)" Jul 14 19:23:57 mgmt consul[2206]: 2022-07-14T19:23:57.318Z [INFO] agent: Synced node info
List cluster members.
$ consul members
Node Address Status Type Build Protocol DC Partition Segment jammy 172.16.151.111:8301 alive server 1.12.3 2 dc-lab-1 default <all> mgmt 172.16.151.120:8301 alive client 1.12.3 2 dc-lab-1 default <default>
Install haproxy.
$ sudo apt install haproxy
Append haproxy configuration.
$ sudo tee --append /etc/haproxy/haproxy.cfg << EOF frontend http_frontend bind *:443 ssl crl /etc/haproxy/consul.pem default_backend consul_ui_backend backend consul_ui_backend server ui 127.0.0.1:8500 EOF
Generate certificate.
$ sudo -u vault openssl req -subj "/O=HashiCorp/CN=Consul" -x509 -nodes -days 1095 -newkey rsa:4096 -keyout /etc/haproxy/tls.key -out /etc/haproxy/tls.crt
$ cat /etc/haproxy/tls.crt /etc/haproxy/tls.crt | sudo tee /etc/haproxy/consul.pem
Reload service.
$ sudo systemctl reload haproxy
Use browser to access Consul UI.

Remember to open HTTPS port on the firewall and access web-ui.