LoginSignup
1
0

Redis Server にフォワードする HAProxy を IP Sharing で冗長化する (Akamai)

Last updated at Posted at 2023-08-03

Redis Server をクラスタ化しないマスター/レプリカ構成の場合、クライアントが常にマスターサーバーに接続できるように HAProxy を手前に配置するパターンがあります。HAProxy が SPOF (Single Point of Failure) になるので、本記事では HAProxy を冗長化するパターンを説明します。

redis-haproxy-ipsharing.jpg

本記事では Private IP を使う例を説明します。VLAN を使うケースは別の記事で説明予定です。

HAProxy の IP Sharing 化については下記の資料を参照します。

Redis Sentinel の準備

以下の記事を参考にして、Redis Sentinel を使った 3 ノード構成と HAProxy と Redis Client の環境を用意します。

追加の HAProxy の準備

先に用意した HAProxy の構成を追加で一台作成します。それぞれ 2.4.22 で動作しています。

ord-haproxy1:~# haproxy -v
HAProxy version 2.4.22-0ubuntu0.22.04.1 2023/03/22 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.22.html
Running on: Linux 6.2.9-x86_64-linode160 #1 SMP PREEMPT_DYNAMIC Wed Apr  5 15:30:32 EDT 2023 x86_64
ord-haproxy2:~# haproxy -v
HAProxy version 2.4.22-0ubuntu0.22.04.1 2023/03/22 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.22.html
Running on: Linux 6.2.9-x86_64-linode160 #1 SMP PREEMPT_DYNAMIC Wed Apr  5 15:30:32 EDT 2023 x86_64
ord-redisclient:~# redis-cli -v
redis-cli 6.0.16

Redis Client からの動作確認

2つの HAProxy を配置し、それぞれ、Redis Sentinel を構成したノードに接続しています。
redis-haproxy-2-haproxy.jpg

ord-redisclient:~# redis-cli -h ord-haproxy1 --tls --cacert redissentinel-ord_ca.crt info replication | egrep role
role:master
ord-redisclient:~# redis-cli -h ord-haproxy2 --tls --cacert redissentinel-ord_ca.crt info replication | egrep role
role:master

このときの /etc/hosts の情報です。

# Redis
192.168.XXX.1 ord-redissentinel1 redis-1
192.168.XXX.2 ord-redissentinel2 redis-2
192.168.XXX.3 ord-redissentinel3 redis-3

192.168.0.1 ord-haproxy1
192.168.0.2  ord-haproxy2
192.168.XXX.11 ord-redisclient

この状態では 各 Redis Server の Firewalld では Redis Client からのアクセスも許可しているので、それぞれにアクセスすると redis-2redis-3 がレプリカであることが分かります。

ord-redisclient:~# redis-cli -h redis-1 --tls --cacert redissentinel-ord_ca.crt info replication | egrep role
role:master

ord-redisclient:~# redis-cli -h redis-2 --tls --cacert redissentinel-ord_ca.crt info replication | egrep role
role:slave

ord-redisclient:~# redis-cli -h redis-3 --tls --cacert redissentinel-ord_ca.crt info replication | egrep role
role:slave

IP Sharing の導入

redis-haproxy-2-haproxy-ipsharing.jpg

IP Sharing は一つの IP を複数のノードで共有することができる技術です。一つのノードだけがその IP を使うことができ、内部的な障害検知によってIPを保持しているノードがダウンしたときに別のノードがそのIPを引き取ることができます。

下図のように2つの HAProxy があり、それぞれ 192.168.0.1192.168.0.2 を持っています。haproxy1 はさらに別の 192.168.0.3 を持っている状態です。
redis-ipsharing-before.jpg

haproxy2 のネットワーク設定で 192.168.0.3 を IP Sharing として登録し、適切な設定をすると、haproxy1 の障害時に haproxy2 が 192.168.0.3 を使うことができます。
redis-ipsharing-after.jpg

haproxy1 に Private IP を追加

linode-haproxy1-2-privateip-mark.jpg

追加するには Cloud Manager からサポートサービスに連絡する必要があります。

haproxy2 に Shared IP として追加

haproxy2 のネットワーク設定から IP Sharing を選択します。
linode-haproxy2-ipsharing-button.jpg

IP Sharing の画面から、 haproxy1 に追加した 192.168.0.3 を選択します。
linode-haproxy2-sharedip-popup-comment.jpg

追加されれば、''IP Sharing uploaded successfully`` のようなメッセージが表示されるので、ポップアップ画面を閉じます。

linode-haproxy2-ipsharing-done.jpg

haproxy2 のネットワーク設定で追加した IP が Shared として登録されています。

linode-haproxy2-network-sharedip.jpg

ネットワークに Shared IP を加える (haproxy1 と haproxy2 の共通設定)

先程の作業はプラットフォーム上の設定です。次に Linux 上の設定を行います。

/etc/netplan/01-netcfg.yaml

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: yes
    lo: # ここから追加
      match:
        name: lo
      addresses: 
        - 192.168.0.3/32 # /17 ではなく #32 ですので注意

設定を反映させます。

netplan apply

設定後、双方のサーバーの lo デバイスに 登録した Private IP アドレスが表示されます。

ord-haproxy1:/etc/netplan# ip -4 a show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.3/32 scope global lo
       valid_lft forever preferred_lft forever
ord-haproxy2:/etc/netplan# ip -4 a show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.0.3/32 scope global lo
       valid_lft forever preferred_lft forever

lelastic のインストールと設定

lelastic は Linode の独自ツールです。エラスティックな IP をできるだけ簡単に使用できるように設計されたクライアントです。

以下のコマンドを実行します。

version=v0.0.6
curl -LO https://github.com/linode/lelastic/releases/download/$version/lelastic.gz
gunzip lelastic.gz
chmod 755 lelastic
sudo mv lelastic /usr/local/bin/

lelastic.service のファイルを作成する

ord-haproxy2:~# vi /etc/systemd/system/lelastic.service

ファイルは以下のようにします。[ID][role] は後で編集します。

[Unit]
Description= Lelastic
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/lelastic -dcid [ID] -[role] &
ExecReload=/bin/kill -s HUP $MAINPID

[Install]
WantedBy=multi-user.target

[ID] はデータセンターの番号を入れます。下記のページの表に記載があります。

[role] には Shared IP をプライマリで動かすホスト側(haproxy1) では primary を、共有されるホスト側(haproxy2) では secondary と書き換えます。

HAproxy 1 の設定

ExecStart=/usr/local/bin/lelastic -dcid 18 -primary  &

-loglevel debug などを追記すると、/var/log/syslog により詳細なログが記録されます。

HAproxy 2 の設定

ExecStart=/usr/local/bin/lelastic -dcid 18 -secondary  &

lelastic の起動 (haproxy1 と haproxy2 の共通作業)

chmod 644 /etc/systemd/system/lelastic.service
systemctl start lelastic
systemctl enable lelastic

HAProxy の Bind 設定の変更

redis-haproxy-binding.jpg

haproxy1

frontend ft_redis
#   HAProxy Private IP address
#   bind 191.168.0.1:6379 name redis
#   shared IP address
    bind 192.168.0.3:6379 name redis
    default_backend bk_redis

次のような設定にすることもできます。

bind *:6379 name redis

haproxy2

frontend ft_redis
#   HAProxy Private IP address
#   bind 191.168.0.2:6379 name redis
#   shared IP address
    bind 192.168.0.3:6379 name redis
    default_backend bk_redis

Redis Client から IP Sharing が動作するかを確認

現在の状態です。

redis-sentinel-haproxy-ipsharing-1.jpg

Redis クライアントに IP Sharing のアドレスを登録

IP Sharing のアドレスを /etc/hosts に登録します。

192.168.XXX.1 ord-redissentinel1 redis-1
192.168.XXX.2 ord-redissentinel2 redis-2
192.168.XXX.3 ord-redissentinel3 redis-3
# END redis servers
192.168.0.1 ord-haproxy1
192.168.0.2  ord-haproxy2
192.168.0.3 ord-haproxy # 追加した行です
192.168.XXX.11 ord-redisclient

Redis-cli からの接続確認 (その 1)

ord-redisclient:~# redis-cli -h ord-haproxy --tls --cacert redissentinel-ord_ca.crt ping
PONG
ord-redisclient:~# redis-cli -h ord-haproxy --tls --cacert redissentinel-ord_ca.crt info replication | grep role
role: master

Read/Write もできる状態です。

ord-redisclient:~# redis-cli -h ord-haproxy --tls --cacert redissentinel-ord_ca.crt
ord-haproxy:6379> set scott tiger
OK
ord-haproxy:6379> get scott
"tiger"
ord-haproxy:6379> get scott
"tiger"
ord-haproxy:6379> set scott lion
OK
ord-haproxy:6379> get scott
"lion"
ord-haproxy:6379>

Primary と動作しているホストで lelastic を停止

マスターサーバーのプロセスを停止します。

ord-haproxy1:/etc/haproxy# systemctl stop lelastic

サーバー停止中でも同様に動作します。

この仕組みでは systemctl stop haproxy は検知できません。

Redis-cli からの接続確認 (その 2)

一瞬接続エラーが出ますが、すぐに新しいコマンドに対して応答が返ってきます。

ord-haproxy:6379> get scott
Could not connect to Redis at ord-haproxy:6379: SSL_connect failed: unexpected eof while reading
not connected> get scott
"lion"

redis-2 がマスターに昇格していますが、その状況をクライアント側は気にすることなく接続できています。

ord-haproxy1:/etc/haproxy# redis-cli -h redis-2 --tls --cacert /etc/haproxy/tls/redissentinel-ord_ca.crt info replication | grep role
role:master

redis-sentinel-haproxy-ipsharing-2.jpg

Secondary と動作しているホストで lelastic を停止

ord-haproxy2:/etc/systemd/system# systemctl stop lelastic

Redis-cli からの接続確認 (その 3)

応答はなくなります。

ord-haproxy:6379> get scott

redis-sentinel-haproxy-ipsharing-3.jpg

Primary と動作しているホストで lelastic を再開

ord-haproxy1:/etc/haproxy# systemctl start lelastic

Redis-cli からの接続確認 (その 4)

すぐに接続されます。

ord-haproxy:6379> get scott
"lion"
(65.31s)
ord-haproxy:6379> get scott
"lion"
ord-haproxy:6379> set scott tiger
OK
ord-haproxy:6379> get scott
"tiger"

redis-sentinel-haproxy-ipsharing-4.jpg

Redis マスターサーバーの停止

redis-1:~# systemctl stop redis-server

redis-2 がマスターに昇格しています。

ord-haproxy1:/etc/haproxy# redis-cli -h redis-2 --tls --cacert /etc/haproxy/tls/redissentinel-ord_ca.crt info replication | grep role
role:master

Redis-cli からの接続確認 (その 5)

redis-2 がマスターに昇格していますが、その状況をクライアント側は気にすることなく接続できています。

ord-haproxy:6379> get scott
Could not connect to Redis at ord-haproxy:6379: SSL_connect failed: unexpected eof while reading
not connected> get scott
"lion"
ord-haproxy:6379> get scott
"lion"
(65.31s)
ord-haproxy:6379> get scott
"lion"

redis-sentinel-haproxy-ipsharing-5.jpg

止めたプロセスを再開します。

redis-1:~# systemctl start redis-server
ord-haproxy2:/etc/systemd/system# systemctl start lelastic

redis-sentinel-haproxy-ipsharing-7.jpg

まとめ

Redis Sentinel、HAProxy、IP Sharing を利用することで、高可用性の Redis サーバーを提供できます。利用するデータセンターの地域によって IP Sharing を利用したフェールオーバーの方式が変わることがありますので、ドキュメントを注意深く確認しましょう。

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