Redis Sentinel は Redis の高可用性ソリューションです。アプリケーションからも高可用性を担保するために HAProxy を冗長化するパターンがあります。Akamai のクラウドでは IP Sharing 機能が提供されており、Private IP を使って HAProxy を冗長化することができます。手順については以下の記事が参考になります。
Redis Sentinel の環境を完全にプライベートのネットワークに閉じて構築するために、VLAN 対応する記事も紹介しています。
HAProxy の冗長化、VLAN 対応はそれぞれ個別に実現することを確認していますが、本記事は2つの要素(冗長化とセキュリティ)を合わせた方法を説明します。主な確認事項は VLAN 上の HAProxy の冗長化として keepalived
を使うことになります。最終的には下図の構成となります。
Public IP と Private IP とは違って、VLAN は内部のネットワークに閉じているので、lelastic
のようなツールを使う必要はありません。
VLAN 内では自由に IP を使えるので、IP Sharing は不要です。
Redis Sentinel の VLAN 環境を用意する
以下の記事を参照して VLAN の環境を用意します。
/etc/hosts
VLAN の IP は以下のように設定します。
# VLAN
10.0.0.11 redis-1v # Redis Server 1
10.0.0.12 redis-2v # Redis Server 2
10.0.0.13 redis-3v # Redis Server 3
10.0.0.1 vlan-router # Act as a Router
10.0.0.21 vlan-haproxy1 # HAProxy 1
10.0.0.22 vlan-redisclient $ Application
10.0.0.23 vlan-haproxy2 # HAProxy 2
10.0.0.31 vlan-haproxy # HAProxy (VIP)
HAProxy を追加する
次に下記の記事を参考に haproxy2 を用意します。
下図の vlan-haproxy2
を用意し、Redis クライアントから動作するように設定します。
Linode の Clone 機能を使い、作業を簡素化します。
Clone
Cloud Manager 上で、Clone
を選択します。
Clone Linode タブの中で、Clone 元のインスタンスを選択します。
地域と Linode Plan を選択します。
名称を自由に変えます。
VLAN の設定を変更します。10.0.0.23/24
を割り当てます。
作られた後のインターフェースです。
クローン後は自動でインスタンスは立ち上がりません。 Power On
ボタンを押して起動します。
起動後、セキュリティ設定を再確認し、その中で次のようにホスト名を変更します。
hostnamectl set-hostname hproxy2
haproxy.cfg on haproxy2
Bind 設定は次のようにします。
frontend ft_redis
bind *:6379 name redis
default_backend bk_redis
haproxy1 でも同様な設定にします。設定変更した場合、 haproxy
を再起動します。
systemctl restart haproxy
firewalld on Redis1/2/3
Redisの各サーバーで 新しい haproxy2 と VIP からアクセスできるように firewalld
の設定変更をします。10.0.0.31
は、このあとで設定する Virtual IP 用の設定です。
<source address="10.0.0.23"/>
<source address="10.0.0.31"/>
設定変更後、firewalld
を再起動します。
firewall-cmd --reload
haproxy2 からの確認
全ての Redis Server に接続できることを確認します。
haproxy2:~# redis-cli -h redis-1v --tls --cacert ca.crt info replication | grep role
role:slave
haproxy2:~# redis-cli -h redis-2v --tls --cacert ca.crt info replication | grep role
role:master
haproxy2:~# redis-cli -h redis-3v --tls --cacert ca.crt info replication | grep role
role:slave
haproxy1 からの確認
haproxy1 からつながることを確認します。
haproxy1:~# redis-cli -h vlan-haproxy2 --tls --cacert ca.crt info replication | grep role
role:master
haproxy1:~# redis-cli -h vlan-haproxy1 --tls --cacert ca.crt info replication | grep role
role:master
これまでの作業で下図の構成となります。まだ keepalived
は動いてないので VIP がない状況です。
keepalived の設定
keepalived
を HAProxy 1/2 にインストールし、10.0.0.31
の Virtual IP (VIP) を動くように設定します。
keepalived のインストール
haproxy1 と haproxy2 に keepalived
をインストールします。
apt install keepalived
keepalived.conf の設定
haproxy1 と happroxy2 で keepalived.conf
を設定します。設定内容はそれぞれ異なります。
vi /etc/keepalived/keepalived.conf
haproxy1 の設定
vrrp_instance Instance1 {
state MASTER
interface eth0
virtual_router_id 10
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass passWord
}
unicast_src_ip 10.0.0.21
unicast_peer {
10.0.0.23
}
virtual_ipaddress {
10.0.0.31
}
}
haproxy2 の設定
haproxy1 との違いです。
1.state
が MASTER
ではなく BACKUP
とする
2. priority を 100
ではなく 99
とする
3. Unicast_src_ip
を自分自身の IP とする
4. unicast_peer
を相手の IP とする
vrrp_instance Instance1 {
state BACKUP
interface eth0
virtual_router_id 10
priority 99
advert_int 1
authentication {
auth_type PASS
auth_pass passWord
}
unicast_src_ip 10.0.0.23
unicast_peer {
10.0.0.21
}
virtual_ipaddress {
10.0.0.31
}
}
keepalived の起動
haproxy1/2 で keepalived
を動かします。
sudo systemctl enable keepalived
sudo systemctl start keepalived
haproxy1 の IP の確認
eth0
デバイスに 10.0.0.31
が割り当てられています。
haproxy1:/etc/keepalived# ip -4 a show dev eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 10.0.0.21/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 10.0.0.31/32 scope global eth0
valid_lft forever preferred_lft forever
HAProsxy2 の IP の確認
eth0
デバイスに 10.0.0.31
は割り当てられていません。
haproxy2:/etc/keepalived# ip -4 a show dev eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 10.0.0.23/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
keepalived の動作確認
Redisc Client (10.0.0.22) で3つの端末を立ち上げて、次の3つのコマンドを起動します。
ping 10.0.0.31
ping 10.0.0.21
redis-cli -h vlan-haproxy --tls --cacert redis-nj_ca.crt
haproxy1 で reboot します。
reboot
haproxy1 への ping の結果
haproxy1 を reboot したことで、Redis Client (10.0.0.22) からの ping は途中で応答がなくなります。
64 bytes from 10.0.0.21: icmp_seq=42 ttl=64 time=0.767 ms
64 bytes from 10.0.0.21: icmp_seq=43 ttl=64 time=2.02 ms
64 bytes from 10.0.0.21: icmp_seq=44 ttl=64 time=3.16 ms
64 bytes from 10.0.0.21: icmp_seq=45 ttl=64 time=1.37 ms
64 bytes from 10.0.0.21: icmp_seq=46 ttl=64 time=0.628 ms
VIP への ping の結果
haproxy1 が持っていた 10.0.0.31
が haproxy2 に引き継がれるかを確認します。先程の 10.0.0.21
に到達できないタイミングで 10.0.0.31
は到達できています。
64 bytes from 10.0.0.31: icmp_seq=42 ttl=64 time=0.467 ms
64 bytes from 10.0.0.31: icmp_seq=43 ttl=64 time=0.446 ms
64 bytes from 10.0.0.31: icmp_seq=44 ttl=64 time=0.355 ms
64 bytes from 10.0.0.31: icmp_seq=45 ttl=64 time=0.447 ms
64 bytes from 10.0.0.31: icmp_seq=46 ttl=64 time=0.365 ms
64 bytes from 10.0.0.31: icmp_seq=47 ttl=64 time=0.435 ms
64 bytes from 10.0.0.31: icmp_seq=48 ttl=64 time=0.372 ms
64 bytes from 10.0.0.31: icmp_seq=49 ttl=64 time=0.369 ms
64 bytes from 10.0.0.31: icmp_seq=50 ttl=64 time=0.357 ms
このとき、haproxy2 の IP は次のように変更されています。keepalived が動作し、haproxy2 が 10.0.0.31
を持っています。
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 10.0.0.23/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 10.0.0.31/32 scope global eth0
valid_lft forever preferred_lft forever
Redis Client から HAProxy 経由で Redis Server に接続する
haproxy1 を shutdown しても、継続して Redis Server に接続できています。
redisclient:~# redis-cli -h vlan-haproxy --tls --cacert redis-nj_ca.crt
vlan-haproxy:6379> role
1) "master"
2) (integer) 407029129
3) 1) 1) "10.0.0.13"
2) "6379"
3) "407029129"
2) 1) "10.0.0.11"
2) "6379"
3) "407029129"
vlan-haproxy:6379> <- このタイミングで haproxy1 を shutdown
vlan-haproxy:6379> get scott
"tiger"
vlan-haproxy:6379> role
1) "master"
2) (integer) 407050682
3) 1) 1) "10.0.0.13"
2) "6379"
3) "407050416"
2) 1) "10.0.0.11"
2) "6379"
3) "407050416"
Reboot 後
haproxy1 が立ち上がったことで、haproxy2 の IP から 10.0.0.31
が見えなくなります。
@haproxy2:/etc/keepalived# ip -4 a show dev eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 10.0.0.23/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
haproxy2 の keepalived.conf
の中の次の行の設定によって、haproxy1 の設定値よりも優先度が低いと判断され、IP は haproxy1 に優先権が与えられます。
priority 99
haproxy1 にログインして、IP を確認します。
@haproxy1:~# ip -4 a show dev eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 10.0.0.21/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 10.0.0.31/32 scope global eth0
valid_lft forever preferred_lft forever
/var/log/syslog
keepalived
のログは /var/log/syslog
に記録されます。haproxy1/2のログを見ると、それぞれ、 Master と BACKUP の遷移が見られます。
haproxy2
Jul 19 16:21:00 haproxy2 Keepalived_vrrp[44007]: (Instance1) Entering MASTER STATE
Jul 19 16:23:55 haproxy2 Keepalived_vrrp[44007]: (Instance1) Master received advert from 10.0.0.21 with higher priority 100, ours 99
Jul 19 16:23:55 haproxy2 Keepalived_vrrp[44007]: (Instance1) Entering BACKUP STATE
Jul 19 16:39:16 haproxy2 Keepalived_vrrp[44007]: (Instance1) Entering MASTER STATE
Jul 19 16:41:59 haproxy2 Keepalived_vrrp[44007]: (Instance1) Master received advert from 10.0.0.21 with higher priority 100, ours 99
Jul 19 16:41:59 haproxy2 Keepalived_vrrp[44007]: (Instance1) Entering BACKUP STATE
haproxy1
Jul 19 16:20:59 haproxy1 Keepalived[528]: Stopping
Jul 19 16:20:59 haproxy1 systemd[1]: Stopping Keepalive Daemon (LVS and VRRP)...
Jul 19 16:23:50 haproxy1 systemd[1]: Starting Keepalive Daemon (LVS and VRRP)...
Jul 19 16:23:51 haproxy1 Keepalived[541]: Starting Keepalived v2.2.4 (08/21,2021)
Jul 19 16:23:51 haproxy1 Keepalived[541]: Running on Linux 6.2.9-x86_64-linode160 #1 SMP PREEMPT_DYNAMIC Wed Apr 5 15:30:32 EDT 2023 (built for Linux 5.15.27)
Jul 19 16:23:51 haproxy1 Keepalived[541]: Command line: '/usr/sbin/keepalived' '--dont-fork'
Jul 19 16:23:51 haproxy1 Keepalived[541]: Configuration file /etc/keepalived/keepalived.conf
Jul 19 16:23:51 haproxy1 Keepalived[541]: NOTICE: setting config option max_auto_priority should result in better keepalived performance
Jul 19 16:23:51 haproxy1 Keepalived[541]: Starting VRRP child process, pid=550
Jul 19 16:23:51 haproxy1 Keepalived[541]: Startup complete
Jul 19 16:23:51 haproxy1 systemd[1]: Started Keepalive Daemon (LVS and VRRP).
Jul 19 16:23:51 haproxy1 Keepalived_vrrp[550]: (Instance1) Entering BACKUP STATE (init)
Jul 19 16:23:52 haproxy1 Keepalived_vrrp[550]: (Instance1) received lower priority (99) advert from 10.0.0.23 - discarding
Jul 19 16:23:53 haproxy1 Keepalived_vrrp[550]: (Instance1) received lower priority (99) advert from 10.0.0.23 - discarding
Jul 19 16:23:54 haproxy1 Keepalived_vrrp[550]: (Instance1) received lower priority (99) advert from 10.0.0.23 - discarding
Jul 19 16:23:55 haproxy1 Keepalived_vrrp[550]: (Instance1) Entering MASTER STATE
Jul 19 16:39:16 haproxy1 Keepalived[541]: Stopping
Jul 19 16:39:16 haproxy1 systemd[1]: Stopping Keepalive Daemon (LVS and VRRP)...
Jul 19 16:41:55 haproxy1 systemd[1]: Starting Keepalive Daemon (LVS and VRRP)...
Jul 19 16:41:55 haproxy1 Keepalived[537]: Starting Keepalived v2.2.4 (08/21,2021)
Jul 19 16:41:55 haproxy1 Keepalived[537]: Running on Linux 6.2.9-x86_64-linode160 #1 SMP PREEMPT_DYNAMIC Wed Apr 5 15:30:32 EDT 2023 (built for Linux 5.15.27)
Jul 19 16:41:55 haproxy1 Keepalived[537]: Command line: '/usr/sbin/keepalived' '--dont-fork'
Jul 19 16:41:55 haproxy1 Keepalived[537]: Configuration file /etc/keepalived/keepalived.conf
Jul 19 16:41:55 haproxy1 Keepalived[537]: NOTICE: setting config option max_auto_priority should result in better keepalived performance
Jul 19 16:41:55 haproxy1 Keepalived[537]: Starting VRRP child process, pid=547
Jul 19 16:41:56 haproxy1 Keepalived[537]: Startup complete
Jul 19 16:41:56 haproxy1 systemd[1]: Started Keepalive Daemon (LVS and VRRP).
Jul 19 16:41:56 haproxy1 Keepalived_vrrp[547]: (Instance1) Entering BACKUP STATE (init)
Jul 19 16:41:56 haproxy1 Keepalived_vrrp[547]: (Instance1) received lower priority (99) advert from 10.0.0.23 - discarding
Jul 19 16:41:57 haproxy1 Keepalived_vrrp[547]: (Instance1) received lower priority (99) advert from 10.0.0.23 - discarding
Jul 19 16:41:58 haproxy1 Keepalived_vrrp[547]: (Instance1) received lower priority (99) advert from 10.0.0.23 - discarding
Jul 19 16:41:59 haproxy1 Keepalived_vrrp[547]: (Instance1) Entering MASTER STATE
最終的に元の状態に戻ります。
まとめ
Redis Sentinel は Redis の高可用性ソリューションです。VLAN を使うことで、セキュアなネットワークの構築ができます。そして、HAProxy で全体の利便性を高めながら、Keepalived を使うことで HAProxy の高可用性の環境を構築することができます。