Jumpserver自体はRedisの高可用性展開をサポートしていないため、Redisセンチネルモードを使用して、Redis自体のアクティブノードとスタンバイノード間のデータ同期とフェイルオーバーを実現しますが、JumpserverはRedisマスターノードのIPスイッチングを認識できないため、この記事ではRedisセンチネルモード+ KeepalivedフローティングIPを採用します。 Redisの高可用性は、KeepalivedがRedisマスターノードの障害IPスイッチングを監視することにより、フローティングIPが常にRedisクラスターマスターノードに続くことを認識し、JumpserverはフローティングIPに接続するだけで常にRedisクラスターマスターノードに接続できます。
1.ファイアウォールを構成します
6379:Redisリスニングポート
26379:Redis-Sentinelリスニングポート
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.255.200.1/30" port protocol="tcp" port="6379" accept"
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.255.200.1/30" port protocol="tcp" port="26379" accept"
firewall-cmd --reload
2.redisをインストールします
yum install -y redis
# 创建数据保存目录,将数据保存至SSD磁盘
mkdir /ssd/redis
mkdir /ssd/redis-sentinel
chown -R redis:redis /ssd/redis
chown -R redis:redis /ssd/redis-sentinel
3.redis構成ファイルを変更します
# 以下仅列出需要修改的配置项
vi /etc/redis.conf
# 修改数据保存位置
dir "/ssd/redis"
# 设置密码
requirepass xxxxxxxx
# 主服务器密码,与前面设置的密码一致
masterauth xxxxxxxx
# 指定主服务器,集群主服务器(第一个启动的节点)不需要配置,其它2个从节点需要配置
slaveof 10.255.200.1 6379
4.redis-sentinel構成ファイルを変更します
# 备份原始配置文件
cp /etc/redis-sentinel.conf /etc/redis-sentinel.conf.bak
# 以下配置为全部配置项,只保留了必要配置,其它配置项可全部删除或根据需要修改
vi /etc/redis-sentinel.conf
# 监听IP及端口设置
bind 0.0.0.0
protected-mode no
port 26379
# 修改数据保存位置
dir "/ssd/redis-sentinel"
logfile "/var/log/redis/sentinel.log"
# 设置监控的主服务器信息及认证密码,密码需与前面Redis配置的密码一致
sentinel monitor redismaster 10.255.200.1 6379 2
sentinel auth-pass redismaster xxxxxxxx
# 将故障切换时间改为5秒,默认值为30秒
sentinel down-after-milliseconds redismaster 5000
sentinel failover-timeout redismaster 30000
supervised systemd
5.redis高可用性クラスターを開始します
# 注意启动的顺序。首先是主节点的Redis服务进程,然后启动从机的Redis服务进程,最后启动3个哨兵的服务进程
systemctl start redis
systemctl status redis
systemctl enable redis
systemctl start redis-sentinel
systemctl status redis-sentinel
systemctl enable redis-sentinel
6.クラスターステータスの確認とデータ同期ステータスの確認
# 查看Redis集群相关状态,xxxxxxxx 为认证密码,应重点关注当前节点的role是否与实际情况一致(1主2从),master_host 是否是主节点IP,master_link_status 是否为 up 。
redis-cli -a xxxxxxxx info replication
# 查看Redis-Sentinel集群相关状态,xxxxxxxx 为认证密码,应重点关注主节点 ip 是否与实际情况一致,flags 标识是否为 master ,主节点正常时 flags不应为s_down / o_down ,num-slaves 从节点数是否为 2 ,num-other-sentinels 其它哨兵节点数是否为 2 ,quorum 认定主节点故障的“法定人数”是否为 2 。
redis-cli -p 26379 -a xxxxxxxx sentinel master redismaster
# 可以通过在主节点写入/删除数据,在从节点验证数据同步是否正常
redis-cli
# 授权认证
auth xxxxxxxx
# 主节点写入数据
set test hello-world
# 3个节点读取数据,验证是否同步
get test
# 主节点删除数据
del test
# 3个节点再次读取数据,验证是否均己删除
get test
7.クラスタースイッチの検証
# 停止主节点redis服务
systemctl stop redis
# 等待约5秒,在其它节点上验证集群状态
redis-cli -a xxxxxxxx info replication
redis-cli -p 26379 -a xxxxxxxx sentinel master redismaster
# 也可通过日志查看集群切换过程
tail -100 /var/log/redis/sentinel.log
8.リディスマスターノードと切り替えるフローティングIPを実装するようにkeepalivedを構成します
# redis集群状态检查脚本,需注意脚本字符串比较时回车换行的处理
# 首先检查 redis 服务是否正常运行,再检查当前节点是否为主节点,再检查当前节点是否持有浮动IP
vi /etc/keepalived/check_redis.sh
#!/bin/bash
</dev/tcp/127.0.0.1/6379
if [ $? -eq 0 ]; then
ROLE=`redis-cli -a xxxxxxxx info replication | grep role`
MASTER=`echo -e "role:master\r\n"`
if [ "$ROLE" == "$MASTER" ]; then
exit 0
fi
MASTERIP=`ip add | grep 10.255.200.4 | wc -l`
if [ $MASTERIP -eq 0 ]; then
exit 0
fi
fi
exit 1
# 编写 Redis 集群切换邮件通知脚本,修改通知标题及正文内容
cp /etc/keepalived/email_tengine.sh /etc/keepalived/email_redis.sh
vi /etc/keepalived/email_redis.sh
#!/bin/bash
contact='[email protected]'
notify() {
mailsubject="[Devops Redis VIP 切换] $(hostname) -> $1"
mailbody="[$(date +'%F %T')]: Devops Redis VIP 切换, $(hostname) 切换为 $1 !"
echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
notify master
;;
backup)
notify backup
;;
fault)
notify fault
;;
*)
echo "Usage: $(basename $0) {master|backup|fault}"
exit 1
;;
esac
# 修改keepalived配置,添加一个新的VRRP实例,并添加相关的状态检查脚本
# 注意新的VRRP实例名称以及虚拟路由器ID应与之前的Tengine相关配置不同
# 注意 keepalived 3个节点须工作在非抢占模式下,角色均设置为BACKUP,优先级相同。
vi /etc/keepalived/keepalived.conf
vrrp_script chk_redis {
script "/etc/keepalived/check_redis.sh"
interval 1
}
vrrp_instance VI_REDIS {
state BACKUP
nopreempt
interface bond-app
virtual_router_id 52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass xxxxxxxx
}
virtual_ipaddress {
10.255.200.4/24
}
track_script {
chk_redis
}
notify_master "/etc/keepalived/email_redis.sh master"
notify_backup "/etc/keepalived/email_redis.sh backup"
notify_fault "/etc/keepalived/email_redis.sh fault"
}
# 重新启动 keepalived 服务
systemctl restart keepalived
systemctl status keepalived
# 检查浮动IP是否在主节点上
redis-cli -a xxxxxxxx info replication | grep role
ip add
# 停用主节点redis服务,进行集群切换验证,验证浮动IP是否跟随主节点
# 具体操作参考前面“集群切换验证”内容
9.極端な場合のRedisサービスリカバリ
Redisセンチネルモードは、2つのセンチネルがメインサービスが応答していないことを監視するときにクラスターを切り替えるように構成されています。これにより、クラスタースイッチングの信頼性を確保できますが、極端な場合、クラスター内の3つのノードのうち2つが一時的に提供できない場合があります。サービスの場合、この時点でのクラスター内の番兵の数は、クラスター切り替えの「クォーラム」を満たしていないため、存続するRedisノードの役割は、常にスレーブノードの役割である可能性があります。このとき、Redisサービスを手動で再起動して、役割を次のようにする必要があります。マスターノードはRedisサービスを復元します。