Jumpserverの高可用性クラスターの展開:(4)Redisセンチネルモードの高可用性展開

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サービスを復元します。

おすすめ

転載: blog.51cto.com/dusthunter/2545996