Redis Sentinel の環境を Marketplace から 60 分で構築する

# Redis Sentinel
``Redis`` はオープンソースのインメモリ型データ構造ストアであり、組み込みのトランザクション、レプリケーションを備えています。Redis はマスターとレプリカの[Redis Replication](https://redis.io/docs/management/replication/) 構成を取れますが、高可用性に重点を置いた別の展開構成として ``Redis Sentinel`` があります。[Redis Sentinel](https://redis.io/docs/management/sentinel/) はマスターサーバーの障害を検知し、動的にレプリカをマスターに昇格させることができます。マスターとレプリカは常に同じデータを持つように構成されます。Redis にはマスターを複数持ち、データをシャーディングし複数のサーバーに分散可能な ``Redis Cluster`` もあります。[Redis Cluster](https://redis.io/docs/management/scaling/) はデータを分散するため、負荷を分散できる長所がありますが、高可用性を保つにはそれぞれのマスターのレプリカが必要になり、要件によっては冗長すぎる構成になります。Redis Sentinel は最小構成 3 台で実現できる容易に高可用性を担保できるバランスの良い機能です。

:::note
Redis Sentinel のプロセスを 3 つ以上にすれば、Redis Server は マスターとレプリカの 2 台構成でも可能ですが、本記事では 3 台構成の例を紹介します。
:::

本記事は以下の文書を参考にし、初めての方が容易に Redis Sentinel が構成できることを目的としています。60 分以内に、Redis Sentinel の構成をインストールして確認することができます。

https://www.linode.com/docs/products/tools/marketplace/guides/redis-cluster/

# インストールされる構成
アカマイ社が展開するクラウドサービスのマーケットプレイスを使って安価なコストで Redis Sentinel をデプロイします。5 台まで選択できますが、今回は 3 台構成とします。展開されたコンピュートインスタンス (Linode) は Private IP を使って互いに通信します。マーケットプレイスはクラスタ環境をワンクリックで設定できるスクリプトが用意されており、Redis Sentinel はその中の一つです。
![Redis Sentinel Diagram Tokyo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/28e5214c-c280-79ba-7bf3-65c2d36a1621.jpeg)


インストールされるのは、Redis 公式サイト https://redis.io/docs/management/sentinel/ の basic setup with three boxes のパターンになります。
```
       +----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+

Configuration: quorum = 2
```
全体は３つのノードで構成され、1つの ``Master (M)`` ノードと２つの ``Replica (R)`` ノードとして動作します。それぞれのノードには ``Sentinel (S)`` のエージェントが動作しており、Sentinel がどのサーバーが Master となるべきかを決定します。Sentinel プロセスの多数決投票が行われ、この構成であれば 2 つが合意したサーバーをマスターに決定します (quorum = 2)。

# インストールされるプロセスとコマンド
マーケットプレイスからインストールされる主な構成要素は以下となります。
- redis server
- redis sentinel
- redis-cli 
- firewalld

firewalld は Redis サーバーを保護するために導入します。不要であれば止めることができます。今回は不必要なアクセスを許可しないため、firewalld を継続利用します。

# インストール
www.linode.com から Linode Console にログインし、Marketplace から Redis Sentinel を選択します。

![marketplace.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/26ab1c9a-d41f-486b-d62f-1bc58273d01b.jpeg)

Linode API Token と sudo コマンドが利用できるユーザーアカウント名を入力します。
![marketplace-config-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/816f5560-a67e-6437-d9b3-5f1ca2e25a8f.jpeg)
トークンの取得方法は以下を参考にしてください。

https://qiita.com/110hideki/items/91491d684cd794632652#linode-%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%AB%E3%81%8B%E3%82%89%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B

次に Redis サーバーと TLS 接続するための自己証明書に関する情報を入力します。
![marketplace-config-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/9be5677f-ef03-eb8d-3e95-4df49b7dfc97.jpeg)

クラスタ設定をします。SSH Keys を全てのノードに加えるようにします。クラスタは 3 台構成を選択します。
![redis-cluster-settings.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/34f8091a-bf01-fc2d-feb2-29f31c5ad8de.jpeg)


Image は Ubuntu となります。Region は日本を選択します。
![marketplace-config-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/5ab5745b-f9a4-8eb4-19ce-2dad34a3663b.jpeg)

次のコンピュートリソースのモデルを選択します。Redis はインメモリのデータストアになりますので High Memory のタイプが推奨ですが、今回は Linode 2GB (2GB メモリ）を選択します。

![marketplace-config-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/6eb332ae-026b-1356-d3b6-11ba58a8efe7.jpeg)

管理が容易になるように、ラベルとタグを付けます。
![marketplace-config-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/aa9485a6-e843-169c-62e5-51c8d93f0a1b.jpeg)

作成するインスタンスの Root パスワードを入力します。必要であれば、User の SSH Key を選択します。設定しておけばセキュアに、かつ、ログインが容易になります。
![marketplace-config-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/1f40a8cc-9cd1-89b3-34cf-2986972d6df6.jpeg)

Create Linode のボタンを押します。このワンクリックで 3 ノードのクラスタが作成できます。
![marketplace-config-7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/1a6177aa-049e-354d-c026-e10b234fddc6.jpeg)

:::note
Create Using Command Line をクリックすれば、Linode API (cURL) と Linode CLI のシンタックスが表示されます。内部で呼び出される StackScript の ID と入力値なども見ることができます。
:::

最終的に 3 台のノードが作成されます。
![marketplace-config-8-mask.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/acc18944-6121-312d-cf9e-22c068192ee6.jpeg)


23 分ほどでインストレーションが終了しました。


# 確認方法
新規作成されたインスタンスの名前を見ます。ラベル名の末尾に 1/2/3 のいずれかの数字が入っています。インスタンスの (Public) IP Address をコピーします。

![linode-redis1-publicip.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/1668fc70-1afe-d820-ea11-cc7e869ea3a5.jpeg)


ssh でログインします。

```
% ssh user@{Public_IP_Address}
```

``/etc/hosts`` には Redis Sentinel Cluster の３つの Private IP が登録されています。ホスト名を使って、どのようにサーバーの役割が変わっていくかに注目すると分かりやすくなります。
```
# Redis
192.168.198.87 redissentinel-tokyo1
192.168.198.103 redissentinel-tokyo2
192.168.198.112 redissentinel-tokyo3
# END redis servers
```

Linode Console には Private IP が登録されています。
![linode-redis1-privateip-mask.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/f99f97ad-1da2-207d-c569-79a292c8ece8.jpeg)


以下のドキュメントに記載あるように、作成したユーザーアカウントの配下の ``~/.deployment-secrests.txt`` に Redis サーバーにアクセスできる情報が書かれています。root ユーザーの配下ではないので注意ください。

https://www.linode.com/docs/products/tools/marketplace/guides/redis-cluster/#obtaining-usernames-and-passwords

ユーザー名が User の場合の例です。

```
user@redissentinel-tokyo1:~$ cat .deployment-secrets.txt
# BEGIN ANSIBLE MANAGED BLOCK
# system user

user: user
password: YOUR_ACCOUNT_LINUX_PASSWORD

# redis password
redis-cli --askpass --tls --cacert /etc/redis/tls/ca.crt:
y+8erSZr9YHAUIzA19zkxaS/8d+kjx4tMJXXXXXXXXXX
# END ANSIBLE MANAGED BLOCK
```

ファイル内に Redis サーバーに接続するためのパスワードが記載されています。環境変数 ``REDISCLI_AUTH`` を使えば ``redis-cli`` コマンドを利用するときにパスワードの入力を省略できます。``~/.bashrc`` に登録すればログインすると動的に設定されます。なお、環境変数の設定はこの後の説明のため root ユーザーの環境で実施しますが、一般ユーザー環境でも実行は可能です。
![redis1-rediscli_auth-export-mask.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/31785e39-c4f8-9152-3ece-d1383cc09055.jpeg)

すぐに設定内容を反映するように、 ``source`` コマンドで有効にします。

```
source .bashrc
```

``echo`` で設定されていることを確認します。
![redis1-rediscli_auth-echo-mask.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/5c1db764-0f15-5171-dae1-a8925f0d8cb9.jpeg)


:::note warn
パスワードの取り扱いに注意してください。
:::

## Master (redissentinel-tokyo1) からの接続テスト

ここまでの作業で、``redis-cli`` を使うまでの準備が整いました。``~/.deployment-secrests.txt``　に記載されているコマンドを起動します。``--askpass`` は省略可能です。``/etc/redis/tls/ca.crt`` は root 権限でないとアクセスできないようになっていますので、一般ユーザーで実行するにはファイルをアクセスできる場所にコピーしてください。
```
redis-cli --tls --cacert /etc/redis/tls/ca.crt
```
ログインに成功したら、``ping`` コマンドを打ちます。``PONG`` が返却されれば動作できています。
```
root@redissentinel-tokyo1:~# redis-cli --tls --cacert /etc/redis/tls/ca.crt
127.0.0.1:6379> ping
PONG
```
``info replication`` コマンドを打つと、``role:master`` が見えます。これはこのサーバーがマスターサーバーであることを意味します。
```
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.198.112,port=6379,state=online,offset=397294,lag=1
slave1:ip=192.168.198.103,port=6379,state=online,offset=397294,lag=1
master_failover_state:no-failover
master_replid:fac9e97e4769636aa327dbdf17c54bbfe8e2a5dc
master_replid2:e545c6cdcac628dbf0851c2521c3c8efa6b9df07
master_repl_offset:397581
second_repl_offset:5818
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:5818
repl_backlog_histlen:391764
```
データを操作します。``scott`` キーに ``tiger`` のデータを挿入できました。
```
127.0.0.1:6379> get scott
(nil)
127.0.0.1:6379> set scott tiger
OK
127.0.0.1:6379> get scott
"tiger"
127.0.0.1:6379> quit
```

:::note 
次のようにポート 26379 を使えば、Sentnel にも接続できます。
```
redis-cli --tls --cacert /etc/redis/tls/ca.crt -p 26379
```
:::

## 一つ目のレプリカ (redissentinel-tokyo2) からの接続テスト
``-h`` オプションを使って、ホストを切り替えます。
```
redis-cli -h redissentinel-tokyo2 --tls --cacert /etc/redis/tls/ca.crt
```
``ping`` は動作しています。``role:slave`` が表示されています。
```
root@redissentinel-tokyo1:~# redis-cli -h redissentinel-tokyo2 --tls --cacert /etc/redis/tls/ca.crt
redissentinel-tokyo2:6379> ping
PONG
redissentinel-tokyo2:6379> info replication
# Replication
role:slave
master_host:192.168.198.87
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:429878
slave_repl_offset:429878
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:fac9e97e4769636aa327dbdf17c54bbfe8e2a5dc
master_replid2:e545c6cdcac628dbf0851c2521c3c8efa6b9df07
master_repl_offset:429878
second_repl_offset:5818
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:68
repl_backlog_histlen:429811
redissentinel-tokyo2:6379>
```
データを操作します。Read (get) はできますが、Write (set) はできません。Redis のレプリカサーバーは Write できないので、Read Only 用途としてサービスを提供できます。
```
redissentinel-tokyo2:6379> get scott
"tiger"
redissentinel-tokyo2:6379> set scott lion
(error) READONLY You can't write against a read only replica.
redissentinel-tokyo2:6379>
```

## ２つ目のレプリカ (redissentinel-tokyo3) からの接続テスト
``-h`` オプションを使って、ホストを切り替えます。
```
redis-cli -h redissentinel-tokyo3 --tls --cacert /etc/redis/tls/ca.crt
```

``ping`` は動作しています。``role:slave`` が表示されています。
```
root@redissentinel-tokyo1:~# redis-cli -h redissentinel-tokyo3 --tls --cacert /etc/redis/tls/ca.crt
redissentinel-tokyo3:6379> ping
PONG
redissentinel-tokyo3:6379> info replication
# Replication
role:slave
master_host:192.168.198.87
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_read_repl_offset:445061
slave_repl_offset:445061
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:fac9e97e4769636aa327dbdf17c54bbfe8e2a5dc
master_replid2:e545c6cdcac628dbf0851c2521c3c8efa6b9df07
master_repl_offset:445061
second_repl_offset:5818
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:68
repl_backlog_histlen:444994
```
データを操作します。Read (get) はできますが、Write (set) はできません。
```
redissentinel-tokyo3:6379> get scott
"tiger"
redissentinel-tokyo3:6379> set scott tiger3
(error) READONLY You can't write against a read only replica.
```

# ファイル構成
Redis のコンフィグファイル、ログファイルを確認します。
## /etc/redis/ 
```
root@redissentinel-tokyo1:~# cd /etc/redis
root@redissentinel-tokyo1:/etc/redis# ls -l
total 252
-rw-r----- 1 redis redis 107058 Jun 29 14:06 redis.conf
-rw-r--r-- 1 redis redis 106589 Dec 16  2022 redis.conf.bak
-rw-r----- 1 redis redis  15699 Jun 29 14:07 sentinel.conf
-rw-r--r-- 1 redis redis  14894 Jun 29 14:03 sentinel.conf.bak
drwxr-xr-x 2 redis redis   4096 Jun 29 14:06 tls
root@redissentinel-tokyo1:/etc/redis#
```


Redis Replication の[ページ](https://redis.io/docs/management/replication/)にレプリカの maxmemory について注意事項が書かれています。レプリカは ``maxmemory`` を無視し、マスターとレプリカの一貫性を保つように初期設計されています。デフォルトではレプリカはevictしないので、maxmemoryで設定されたメモリよりも多くのメモリを使用してしまう可能性があります（レプリカでより大きくなるバッファがあったり、データ構造でより多くのメモリを使用したりすることがあるためです）。レプリカを監視し、マスタが設定されたmaxmemory設定に到達する前に、実際にメモリ不足の状態に陥ることがないように、レプリカに十分なメモリがあることを確認してください。

この動作を変更するには、レプリカがmaxmemoryを無視しないようにします。使用する設定ディレクティブは以下の通りです：

```
replica-ignore-maxmemory no
```
現在の設定は redis-cli でも確認できます。
```
root@redisclient:~# redis-cli -h redissentinel-tokyo1 --tls --cacert redissentinel-tokyo_ca.crt
redissentinel-tokyo1:6379> config get replica-ignore-maxmemory
1) "replica-ignore-maxmemory"
2) "yes"
```

## /var/log/redis/

```
root@redissentinel-tokyo1:/etc/redis# cd /var/log/redis
root@redissentinel-tokyo1:/var/log/redis# ls -l
total 12
-rw-rw---- 1 redis adm 3824 Jun 29 14:07 redis-sentinel.log
-rw-rw---- 1 redis adm 7620 Jun 29 14:29 redis-server.log
```


# プロセス
## redis-server
```
root@redissentinel-tokyo1:/var/log/redis# lsof +c 15 -i :6379 | grep redis-server
redis-server   21223 redis    6u  IPv4  88791      0t0  TCP localhost:redis (LISTEN)
redis-server   21223 redis    7u  IPv6  88792      0t0  TCP localhost:redis (LISTEN)
redis-server   21223 redis    8u  IPv4  88793      0t0  TCP redissentinel-tokyo1:redis (LISTEN)
redis-server   21223 redis    9u  IPv4  88970      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo1:56444 (ESTABLISHED)
redis-server   21223 redis   10u  IPv4  88985      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo1:56458 (ESTABLISHED)
redis-server   21223 redis   11u  IPv4  88986      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo3:38680 (ESTABLISHED)
redis-server   21223 redis   12u  IPv4  88988      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo2:57826 (ESTABLISHED)
redis-server   21223 redis   13u  IPv4  88993      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo3:38692 (ESTABLISHED)
redis-server   21223 redis   14u  IPv4  88995      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo2:35624 (ESTABLISHED)
redis-server   21223 redis   15u  IPv4  88996      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo2:35634 (ESTABLISHED)
redis-server   21223 redis   16u  IPv4  89541      0t0  TCP redissentinel-tokyo1:redis->redissentinel-tokyo3:38696 (ESTABLISHED)
```
## redis-sentinel
```
root@redissentinel-tokyo1:/etc/redis# lsof +c 15 -i :26379
COMMAND          PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
redis-sentinel 21283 redis    6u  IPv4  88959      0t0  TCP localhost:26379 (LISTEN)
redis-sentinel 21283 redis    7u  IPv6  88960      0t0  TCP localhost:26379 (LISTEN)
redis-sentinel 21283 redis    8u  IPv4  88961      0t0  TCP redissentinel-tokyo1:26379 (LISTEN)
redis-sentinel 21283 redis   15u  IPv4  88981      0t0  TCP redissentinel-tokyo1:54848->redissentinel-tokyo3:26379 (ESTABLISHED)
redis-sentinel 21283 redis   16u  IPv4  88982      0t0  TCP redissentinel-tokyo1:60110->redissentinel-tokyo2:26379 (ESTABLISHED)
redis-sentinel 21283 redis   17u  IPv4  89475      0t0  TCP redissentinel-tokyo1:26379->redissentinel-tokyo3:60696 (ESTABLISHED)
redis-sentinel 21283 redis   18u  IPv4  89477      0t0  TCP redissentinel-tokyo1:26379->redissentinel-tokyo2:57536 (ESTABLISHED)
```

## サービス自動起動の確認
```
root@redissentinel-tokyo1:~# systemctl is-enabled redis-server
disabled
root@redissentinel-tokyo1:~# systemctl is-enabled redis-sentinel
disabled
```
サーバーが停止したときは手動で起動することを前提としています。自動起動するには、以下のようにします。
```
root@redissentinel-tokyo1:~# systemctl enabled redis-server

root@redissentinel-tokyo1:~# systemctl enabled redis-sentinel
```

# Redis Client の設定
Redis Server 内で redis-cli を使って接続確認をしましたが、多くのケースでは別のサーバーで動作するアプリケーションから Redis Server に接続されます。Linode インスタンスを追加し、追加されたサーバーをアプリケーションと見なして Redis に接続できることを確認します。
![Redis Sentinel Diagram + Client.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/4b494794-cbf0-bcbe-5427-5fc3a12dedbe.jpeg)
接続確認するだけなので、一番安価な $5 プランの Nanode 1GB を選択します。Region は Redis Server を構築した場所と同じ Tokyo を選択します。Distributeion も Redis Server との操作性の互換を重視し、Ubuntu にします。
![redis-client-server.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/bf4bb394-67af-6d69-2b50-74dddb67e0b2.jpeg)

Public IP を使わずに Redis Server にアクセスしたいので、Private IP をオンにします。
![redis-client-server-privateip.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/e036d4fa-9e37-ef99-66fb-cec7f4bb9ca4.jpeg)

必要なアップデートをします。
```
apt update && apt upgrade
```

Redis Server の IP アドレスをホストファイルに登録して、この後、ホスト名で redis-cli を使えるように準備します。
```
# Redis
192.168.198.87 redissentinel-tokyo1
192.168.198.103 redissentinel-tokyo2
192.168.198.112 redissentinel-tokyo3
# END redis servers
```

ping で疎通確認します。
```
root@redisclient:~# ping redissentinel-tokyo1
PING redissentinel-tokyo1 (192.168.198.87) 56(84) bytes of data.
64 bytes from redissentinel-tokyo1 (192.168.198.87): icmp_seq=1 ttl=60 time=0.428 ms
64 bytes from redissentinel-tokyo1 (192.168.198.87): icmp_seq=2 ttl=60 time=0.569 ms
```

Redis Server の ``/etc/redis/tls/ca.crt`` をコピーして、Client の Linode サーバーにコピーします。redis-cli で同じ証明書情報を使う必要があります。
```
root@redissentinel-tokyo1:~# cat /etc/redis/tls/ca.crt
```

redis-cli をインストールします。
```
apt install redis-tools
```

redis-cli で接続を試みます。
```
root@redisclient:~# redis-cli -h redissentinel-tokyo1 --tls --cacert redissentinel-tokyo_ca.crt
Could not connect to Redis at redissentinel-tokyo1:6379: No route to host
```

``No route to host`` は Redis Sentinel のサーバーにインストールされている ``firewalld``がブロックしているからです。そのため、firewalld に クライアントの Private IP を登録する必要があります。

Private IP アドレスを取得します。 ``192.168.139.199`` になります。
```
root@redisclient:~# ip -4 a show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet {Public_IP}/24 brd XXX.XXX.XXX.XXX scope global eth0
       valid_lft forever preferred_lft forever
    inet 192.168.139.199/17 brd 192.168.255.255 scope global eth0
       valid_lft forever preferred_lft forever
```
Linode Console の Network タブからも同じ情報が見られます。
![redis-client-network-privateip-mask.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/82a66c3b-491d-a603-d746-4c9e9b142c7a.jpeg)


得られた Private IP を Redis Server で動いている firewalld に設定します。

# firewalld の設定
Redis Master サーバーにログインします。``firewalld`` が起動していることを確認します。

```
root@redissentinel-tokyo1:/etc/firewalld# ps auxw|egrep firewalld
root       20936  0.0  1.9 128280 39212 ?        Ssl  Jun29   0:00 /usr/bin/python3 /usr/sbin/firewalld --nofork --nopid
```

firewalld の確認には firewall-cmd が使えます。
```
root@redissentinel-tokyo1:/etc/firewalld# firewall-cmd -V
1.1.1
```

```
root@redissentinel-tokyo1:/etc/firewalld# firewall-cmd --state
running
```
有効なゾーン設定を確認します。
```
root@redissentinel-tokyo1:/etc/firewalld# firewall-cmd --get-active-zone
internal
  sources: 192.168.198.87 192.168.198.103 192.168.198.112
```
internal zone の設定が有効になっていることが分かります。この中に Redis Sentinel サーバーの Public IP のアドレスが登録されている。

firewalld の設定ファイルは ``/etc/firewalld/`` 配下にあります。
```
root@redissentinel-tokyo1:/etc/firewalld# pwd
/etc/firewalld
root@redissentinel-tokyo1:/etc/firewalld# ls -l
total 32
-rw-r--r-- 1 root root 2485 Jun 29 14:03 firewalld.conf
drwxr-xr-x 2 root root 4096 Mar 28  2022 helpers
drwxr-xr-x 2 root root 4096 Mar 28  2022 icmptypes
drwxr-xr-x 2 root root 4096 Mar 28  2022 ipsets
-rw-r--r-- 1 root root  268 Mar 28  2022 lockdown-whitelist.xml
drwxr-xr-x 2 root root 4096 Mar 28  2022 policies
drwxr-xr-x 2 root root 4096 Mar 28  2022 services
drwxr-xr-x 2 root root 4096 Jun 29 14:04 zones
```

zones の下に internal.xml があります。
```
root@redissentinel-tokyo1:/etc/firewalld# cd zones
root@redissentinel-tokyo1:/etc/firewalld/zones# ls
internal.xml  internal.xml.old
```

ファイルの中には Redis Sentinel のサーバーの Private IP が登録されています。
```
root@redissentinel-tokyo1:/etc/firewalld/zones#cat internal.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Internal</short>
  <description>For use on internal networks. You mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="mdns"/>
  <service name="samba-client"/>
  <service name="dhcpv6-client"/>
  <service name="redis"/>
  <service name="redis-sentinel"/>
  <source address="192.168.198.87"/>
  <source address="192.168.198.103"/>
  <source address="192.168.198.112"/>
  <forward/>
</zone>
```

以下の行を加えます。
```
  <source address="192.168.139.199"/>
```

firewalld を再起動します。
```
firewall-cmd --reload
```

status を確認します。
```
root@redissentinel-tokyo1:/etc/firewalld/zones# 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 2023-06-30 08:59:35 UTC; 24s ago
       Docs: man:firewalld(1)
   Main PID: 29722 (firewalld)
      Tasks: 2 (limit: 2234)
     Memory: 21.7M
        CPU: 958ms
     CGroup: /system.slice/firewalld.service
             └─29722 /usr/bin/python3 /usr/sbin/firewalld --nofork --nopid

Jun 30 08:59:35 redissentinel-tokyo1 systemd[1]: Starting firewalld - dynamic firewall daemon...
Jun 30 08:59:35 redissentinel-tokyo1 systemd[1]: Started firewalld - dynamic firewall daemon.
```

Redis クライアントから再度接続します。
```
root@redisclient:~# redis-cli -h redissentinel-tokyo1 --tls --cacert redissentinel-tokyo_ca.crt
redissentinel-tokyo1:6379>
```
エラーは表示されません。``firewalld`` の設定が有効化されていることが分かります。
```
redissentinel-tokyo1:6379> ping
(error) NOAUTH Authentication required.
```
ping では認証エラーが出ました。``REDISCLI_AUTH`` の設定漏れです。設定して再度トライします。

```
root@redisclient:~# export REDISCLI_AUTH='REDISのパスワードを設定してください'
root@redisclient:~# redis-cli -h redissentinel-tokyo1 --tls --cacert redissentinel-tokyo_ca.crt
redissentinel-tokyo1:6379> ping
PONG
```
読み込みと書き込みに成功しています。
```
redissentinel-tokyo1:6379> get scott
"tiger"
redissentinel-tokyo1:6379> set scott dixon
OK
redissentinel-tokyo1:6379> get scott
"dixon"
```
role コマンドで Master サーバーであることも再確認できます。
```
redissentinel-tokyo1:6379> role
1) "master"
2) (integer) 14510424
3) 1) 1) "192.168.198.112"
      2) "6379"
      3) "14510424"
   2) 1) "192.168.198.103"
      2) "6379"
      3) "14510424"
```
firewalld の設定と再起動を他の２つのレプリカサーバーでも実行します。

最終的に全てのサーバーと接続できれば成功です。

```
root@redisclient:~# redis-cli -h redissentinel-tokyo2 --tls --cacert redissentinel-tokyo_ca.crt
redissentinel-tokyo2:6379> ping
PONG
redissentinel-tokyo2:6379> get scott
"dixon"
redissentinel-tokyo2:6379> quit
root@redisclient:~# redis-cli -h redissentinel-tokyo3 --tls --cacert redissentinel-tokyo_ca.crt
redissentinel-tokyo3:6379> ping
PONG
redissentinel-tokyo3:6379> get scott
"dixon"
```

# まとめ
Akamai の cloud computing services を使って Redis Sentinel Cluster を容易に構築し、アプリケーションを想定した別のサーバーからアクセスもできました。また、firewalld の設定によってアクセス制御もできることもわかりました。