Deploying Redis Sentinel for a Three-Server GateKeeper Cluster
Purpose
A GateKeeper cluster provides redundancy by running multiple GateKeeper servers together in the same cluster. A clustered deployment requires at least two GateKeeper servers, but Blackwall recommends that you configure three or more so that cluster coordination services, such as Redis Sentinel, can be configured reliably. The more GateKeeper servers included, the higher the overall throughput of the cluster. The cluster ensures that traffic continues to be processed, should one server become unavailable.
This guide describes how to configure a highly available Redis backend for three GateKeeper servers, where each server runs:
- GateKeeper
- Redis Server
- Redis Sentinel
- HAProxy, providing the local Redis endpoint
127.0.0.1:6380
GateKeeper doesn't connect directly to an individual Redis server. Instead, each GateKeeper instance uses its local HAProxy, as demonstrated below:
Redis Sentinel monitors the Redis instances and if the master fails, it promotes one of the replicas to become the new master. HAProxy checks the actual role of each Redis instance and routes new connections only to the current master. Three Sentinel instances with a quorum of 2 allow automatic failover if one Redis node fails.
Tip
This guide provides Redis high availability, but it does not configure load balancing for public HTTP/HTTPS traffic across the GateKeeper servers. Public traffic requires a separate load balancer, DNS failover, or another ingress mechanism with GateKeeper health checks.
Example topology
The following addresses are used in the examples:
| Server | Hostname | Private IP | Components |
|---|---|---|---|
| GK1 | gk1 |
10.114.0.11 |
GateKeeper, Redis, Sentinel, HAProxy |
| GK2 | gk2 |
10.114.0.12 |
GateKeeper, Redis, Sentinel, HAProxy |
| GK3 | gk3 |
10.114.0.13 |
GateKeeper, Redis, Sentinel, HAProxy |
During the initial deployment:
- GK1 is the initial Redis master;
- GK2 is a Redis replica;
- GK3 is a Redis replica;
- the Sentinel quorum is
2; - GateKeeper accesses Redis through
127.0.0.1:6380.
After the first failover, no specific server should be treated as the permanent master. Redis Sentinel determines the current role.
Warning
After Redis Sentinel has been started, do not replace /etc/redis/sentinel.conf or restore it from the original template. Replacing the active file with the initial configuration may return Sentinel to an outdated view of the cluster.
Prerequisites
Before starting, make sure that:
- all three servers are installed and accessible over SSH;
- bidirectional network connectivity is available between the servers' private IP addresses;
- the private IP addresses do not change after a reboot;
- all servers maintain accurate time using NTP;
- GateKeeper is already installed;
- ports
6379/tcpand26379/tcpare not accessible from the internet;
Prepare your servers
Create passwords
Two different passwords are required and the following placeholders are used throughout this guide:
- <
REDIS_PASSWORD> — for connecting to Redis; - <
SENTINEL_PASSWORD> — for connecting to Redis Sentinel.
Warning
Do not put real passwords in shell history, tickets, public documentation, or version control. For the command examples below, load Redis CLI passwords from local root-only files instead of typing passwords directly in shell commands. Once generated, store the generated values in a secure secrets-management system.
To simplify HAProxy health checks, use passwords without spaces, quotation marks, backslashes, or newline characters. Hexadecimal values are suitable.
- Generate both passwords on a secure administrative machine using the following commands.
- Using the following commands on each of the three GateKeeper servers, create credential helper files, which make administrative commands safer and easier.
- Open the created Redis CLI password file:
- Add your previously generated password to the open file:
- Open the created Sentinel CLI password file:
- Add your previously generated password to the open file::
Install packages
- Run the following commands on GK1, GK2, and GK3:
- Check the installed versions:
-
Create backup copies of the configuration files:
-
Stop Redis Sentinel until the initial configuration is complete:
Configure iptables
The following connections must be allowed between the GateKeeper servers:
| Port | Purpose |
|---|---|
6379/tcp |
Redis replication and Redis management by Sentinel |
26379/tcp |
communication between Sentinel instances |
Port 6380/tcp must listen only on 127.0.0.1 and must not be opened in iptables.
-
Run the following commands on GK1:
sudo iptables -I INPUT -p tcp -s 10.114.0.12 -d 10.114.0.11 --dport 6379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.13 -d 10.114.0.11 --dport 6379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.12 -d 10.114.0.11 --dport 26379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.13 -d 10.114.0.11 --dport 26379 -j ACCEPT -
Run the following commands on GK2:
sudo iptables -I INPUT -p tcp -s 10.114.0.11 -d 10.114.0.12 --dport 6379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.13 -d 10.114.0.12 --dport 6379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.11 -d 10.114.0.12 --dport 26379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.13 -d 10.114.0.12 --dport 26379 -j ACCEPT -
Run the following commands on GK3:
sudo iptables -I INPUT -p tcp -s 10.114.0.11 -d 10.114.0.13 --dport 6379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.12 -d 10.114.0.13 --dport 6379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.11 -d 10.114.0.13 --dport 26379 -j ACCEPT sudo iptables -I INPUT -p tcp -s 10.114.0.12 -d 10.114.0.13 --dport 26379 -j ACCEPT -
Review and persist the rules on each server:
Configure Redis
Configure the Redis instances
On each server, open and amend the Redis configuration file.
Warning
Find the existing directives and replace them. Do not leave multiple active versions of the same directive.
- Open the Redis configuration file pn all three GateKeeper servers:
-
For the open Redis configuration file on GK1, ensure that the following directives are active:
During the initial deployment, do not add abind 127.0.0.1 10.114.0.11 protected-mode yes port 6379 pidfile "/run/redis/redis-server.pid" logfile "/var/log/redis/redis-server.log" dir "/var/lib/redis" requirepass <REDIS_PASSWORD> masterauth <REDIS_PASSWORD> appendonly yes appendfsync everysec replica-read-only yes replica-priority 100replicaofdirective on GK1. -
For the open Redis configuration file on GK2, ensure that the following directives are active:
bind 127.0.0.1 10.114.0.12 protected-mode yes port 6379 pidfile "/run/redis/redis-server.pid" logfile "/var/log/redis/redis-server.log" dir "/var/lib/redis" requirepass <REDIS_PASSWORD> masterauth <REDIS_PASSWORD> appendonly yes appendfsync everysec replica-read-only yes replica-priority 100 replicaof 10.114.0.11 6379 - For the open Redis configuration file on GK3, ensure that the following directives are active:
bind 127.0.0.1 10.114.0.13 protected-mode yes port 6379 pidfile "/run/redis/redis-server.pid" logfile "/var/log/redis/redis-server.log" dir "/var/lib/redis" requirepass <REDIS_PASSWORD> masterauth <REDIS_PASSWORD> appendonly yes appendfsync everysec replica-read-only yes replica-priority 100 replicaof 10.114.0.11 6379
Allow Redis configuration changes
Redis Sentinel changes the roles of Redis instances during failover. Redis must be able to persist the updated configuration by using CONFIG REWRITE.
- Run the following commands on all three servers:
- On all three servers, verify the owner and permissions:
- Check that the
/etc/redisdirectory is owned by root, and theredisuser is not able to create or delete files in it. - Check that the
/etc/redis/redis.conffile is writable by theredisgroup.
Start the initial Redis master
- On GK1, enable the Redis service to start automatically, restart it to apply the configuration, and verify that it is running, using the following commands:
-
Test your connection, using:
Expected result:
-
Check the role, using:
Expected result from GK1:
4. Verify that the configuration can be persisted:Expected result:
Start the Redis Replicas
- On GK2 and GK3, enable the Redis service to start automatically, restart it to apply the configuration, and verify that it is running:
-
On both servers, check the replication status:
Expected parameters:
Depending on the Redis version, secondary nodes may be referred to as a
replica, although therolefield in theINFO replicationoutput may still returnslave. -
On GK1, check the number of connected replicas:
Expected parameters:
-
Do not proceed to the Sentinel configuration until both replicas show:
Verify successful data replication
- For testing purposes, create a temporary key on GK1:
- Check that the key created in the previous step exists on GK2 and GK3:
- Ensure that both replicas return the same value.
- Delete the temporary key on GK1:
Configure Redis Sentinel
Create configuration
- Create a separate
/etc/redis/sentinel.conffile on GK1, GK2, and GK3. - On each of the three servers, open the file created in the previous step:
-
Make the following amendments on each of the three servers:
port 26379 bind 127.0.0.1 10.114.0.11 protected-mode yes requirepass <SENTINEL_PASSWORD> sentinel monitor mymaster 10.114.0.11 6379 2 sentinel auth-pass mymaster <REDIS_PASSWORD> sentinel down-after-milliseconds mymaster 10000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1port 26379 bind 127.0.0.1 10.114.0.12 protected-mode yes requirepass <SENTINEL_PASSWORD> sentinel monitor mymaster 10.114.0.11 6379 2 sentinel auth-pass mymaster <REDIS_PASSWORD> sentinel down-after-milliseconds mymaster 10000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1port 26379 bind 127.0.0.1 10.114.0.13 protected-mode yes requirepass <SENTINEL_PASSWORD> sentinel monitor mymaster 10.114.0.11 6379 2 sentinel auth-pass mymaster <REDIS_PASSWORD> sentinel down-after-milliseconds mymaster 10000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1The same
SENTINEL_PASSWORDmust be used by all three Sentinel instances. -
Set the permissions on each server:
Start Sentinel sequentially
-
Start Sentinel on GK1 first:
-
Check the current master:
. /root/.redis-cli-sentinel.env redis-cli -h 127.0.0.1 -p 26379 \ SENTINEL get-master-addr-by-name mymasterExpected result:
-
Then start Sentinel on GK2:
-
Wait until GK1 and GK2 discover each other. Then start Sentinel on GK3:
Verifying Sentinel deployment
-
Run the following command on each server and check that the result confirms that a quorum and a majority sufficient for failover are available.
-
Check the current master:
-
Check the discovered replicas:
-
Check the discovered Sentinel instances:
Make sure that each Sentinel sees:
- one Redis master
- two Redis replicas
- the other two Sentinel instances
- a quorum of
2
Configure HAProxy
HAProxy must listen for the Redis endpoint only on the local address 127.0.0.1:6380. It must then:
- connect to each Redis instance;
- authenticate with Redis;
- request replication information;
- consider only the server with the master role to be available;
- close existing connections if a server is no longer the master.
Configure the local Redis endpoint
To configure HAProxy:
-
Open the HAProxy configuration file on each server:
-
Use the following configuration:
global log /dev/log local0 log /dev/log local1 notice user haproxy group haproxy daemon maxconn 4096 defaults log global mode tcp retries 3 timeout connect 3s timeout client 1m timeout server 1m frontend redis_local bind 127.0.0.1:6380 mode tcp default_backend redis_current_master backend redis_current_master mode tcp option tcp-check tcp-check connect tcp-check send AUTH\ <REDIS_PASSWORD>\r\n tcp-check expect string +OK tcp-check send INFO\ replication\r\n tcp-check expect string role:master tcp-check send QUIT\r\n tcp-check expect string +OK server gk1 10.114.0.11:6379 check inter 2s fall 2 rise 1 on-marked-down shutdown-sessions server gk2 10.114.0.12:6379 check inter 2s fall 2 rise 1 on-marked-down shutdown-sessions server gk3 10.114.0.13:6379 check inter 2s fall 2 rise 1 on-marked-down shutdown-sessions -
Restrict access to the configuration file because it contains the Redis password:
-
Validate the syntax:
-
If the configuration is valid, enable and start HAProxy:
Verify local HAProxy endpoint
-
Run the following command on each of the three GateKeeper servers:
Expected result:
-
Check the role of the Redis server selected by HAProxy:
The result must begin with:
-
Test writing and reading through HAProxy:
-
Check the listener:
The endpoint must listen only on:
It must not listen on
0.0.0.0:6380or on the server's private IP address.
Configure GateKeeper
-
Open the following file on each GateKeeper server:
-
Add or update:
-
Make sure the file does not contain multiple active
REDIS_HOSTorREDIS_PASSWORDlines. -
Check the available GateKeeper services:
-
Restart GateKeeper:
-
Check the status:
-
All expected services must start successfully.
Verify the cluster
-
On GK1, run the following command:
. /root/.redis-cli-redis.env redis-cli -h 127.0.0.1 -p 6379 \ INFO replication | grep -E 'role:|connected_slaves:'Initially, the expected output is:
-
On GK2 and GK3, run the following command:
. /root/.redis-cli-redis.env redis-cli -h 127.0.0.1 -p 6379 \ INFO replication | grep -E 'role:|master_host:|master_link_status:'Initially, the expected output is:
-
On all three servers, verify the local Redis endpoint:
Expected result:
-
On all three servers, verify the current master through Sentinel:
. /root/.redis-cli-sentinel.env redis-cli -h 127.0.0.1 -p 26379 \ SENTINEL get-master-addr-by-name mymasterAll three Sentinel instances must return the same master address.
-
On all three servers, verify the quorum:
-
Verify the services
Test automatic failover
This tests may be performed during an approved maintenance window to check automatic failover success.
- Identifying the Current Master
Run the following command on any server:
. /root/.redis-cli-sentinel.env
redis-cli -h 127.0.0.1 -p 26379 \
SENTINEL get-master-addr-by-name mymaster
With the initial configuration, the result should point to:
-
Make a test value by creating a key through the local HAProxy instance:
-
Stop the current Redis master server. If GK1 is the current master, run the following command on GK1:
Do not stop Sentinel when testing only a Redis process failure.
-
Verify that a new master is selected. Run the following command on GK2 or GK3:
watch -n 1 \ '. /root/.redis-cli-sentinel.env && redis-cli -h 127.0.0.1 -p 26379 SENTINEL get-master-addr-by-name mymaster'If failover is completed successfully, the returned address must change to:
or:
-
Check the local HAProxy endpoint:
If failover is completed successfully, the expected result is:
-
Check the existing key:
Verify that writes are possible:
-
Bring the stopped Redis instance back online by running the following commands on the stopped server:
Do not manually assign the recovered server as the master. Sentinel must automatically reconfigure the recovered former master as a replica of the current master.
-
Check the role of the recovered node:
. /root/.redis-cli-redis.env redis-cli -h 127.0.0.1 -p 6379 \ INFO replication | grep -E 'role:|master_host:|master_link_status:'Expected output:
Verify that all three Sentinel instances point to the same master.
-
After the failover test is completed successfully, reboot each node one at a time using the following sequence:
- Make sure that
SENTINEL CKQUORUM mymastercompletes successfully. - Reboot one Redis replica.
- Wait for it to return.
- Make sure that the replica shows
master_link_status:up. - Check the Sentinel quorum again.
- Only then proceed to the next node and repeat these steps.
Do not reboot two Sentinel instances at the same time.
- Make sure that
-
After rebooting each server, run:
sudo systemctl is-active redis-server sudo systemctl is-active redis-sentinel sudo systemctl is-active haproxyCheck the local endpoint:
Expected result: