1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Redis Sentinel を VLAN と keepalived でセキュアかつ冗長化する (Akamai)

Posted at

Redis Sentinel は Redis の高可用性ソリューションです。アプリケーションからも高可用性を担保するために HAProxy を冗長化するパターンがあります。Akamai のクラウドでは IP Sharing 機能が提供されており、Private IP を使って HAProxy を冗長化することができます。手順については以下の記事が参考になります。

Redis Sentinel の環境を完全にプライベートのネットワークに閉じて構築するために、VLAN 対応する記事も紹介しています。

HAProxy の冗長化、VLAN 対応はそれぞれ個別に実現することを確認していますが、本記事は2つの要素(冗長化とセキュリティ)を合わせた方法を説明します。主な確認事項は VLAN 上の HAProxy の冗長化として keepalived を使うことになります。最終的には下図の構成となります。

Redis-VLAN-HAProxy.jpg

Public IP と Private IP とは違って、VLAN は内部のネットワークに閉じているので、lelastic のようなツールを使う必要はありません。

VLAN 内では自由に IP を使えるので、IP Sharing は不要です。

Redis Sentinel の VLAN 環境を用意する

以下の記事を参照して VLAN の環境を用意します。

本記事ではまず下図のような構成を前提として用意しました。
redis-vlan-1.jpg

/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 クライアントから動作するように設定します。
redis-vlan-haproxy2.jpg

Linode の Clone 機能を使い、作業を簡素化します。

Clone

Cloud Manager 上で、Clone を選択します。
clone.jpg

clone-linode.jpg
Clone Linode タブの中で、Clone 元のインスタンスを選択します。
clone-source-host.jpg
地域と Linode Plan を選択します。
clone-region.jpg
名称を自由に変えます。
redissentinel-nj_haproxy2.jpg
VLAN の設定を変更します。10.0.0.23/24 を割り当てます。
haproxy2-vlan.jpg
作られた後のインターフェースです。
haproxy2-vlan-2.jpg
クローン後は自動でインスタンスは立ち上がりません。 Power On ボタンを押して起動します。
haproxy2-poweron.jpg

起動後、セキュリティ設定を再確認し、その中で次のようにホスト名を変更します。

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 がない状況です。
haproxy2-setup-complete.jpg

keepalived の設定

keepalivedを HAProxy 1/2 にインストールし、10.0.0.31 の Virtual IP (VIP) を動くように設定します。

haproxy-keepalived.jpg

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.stateMASTER ではなく 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

この後下図のように動作することを見ていきます。
redis-keepalived-haproxy.jpg

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-after-haproxy1-reboot.jpg

まとめ

Redis Sentinel は Redis の高可用性ソリューションです。VLAN を使うことで、セキュアなネットワークの構築ができます。そして、HAProxy で全体の利便性を高めながら、Keepalived を使うことで HAProxy の高可用性の環境を構築することができます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?