单容器部署redis 集群


  之前看了很多容器部署 redis 集群的文章,但大多都是将不同的redis节点部署在不通的容器中,当然这个是很规范的,实现了灾备,适合用于生产,可我只是为了自己临时测试,也不想弄那么多容器
  所以想在单个容器中部署 redis 集群,测试就方便,一旦我想部署一套新的 redis 集群,只需要把镜像拷过来,然后docker run 就 ok 了
  这里面有两个难点,当时困了我一阵儿,一个是,我们是部署在容器中,和部署在物理机上是不一样的,需要新增配置项,这点之前是没意识到的,就完全沿用了,我之前在物理机上部署 redis 集群的方法,结果不同redis 节点之间一直打不通,困了我一阵
  另一个是,在打通不同 redis 节点的时候,需要手动输入 yes,这里需要写个 expect 的脚本,不然总不能每次在新的宿主机上新建完容器,还需要自己手动操作一把吧,那也太麻烦了

一、容器部署redis注意点总结

  • 容器部署和物理机部署相比,需要新加配置项如下
cluster-announce-ip
cluster-announce-port
cluster-announce-bus-port

  这三个配置项都是为了保证容器中redis节点的通信用的

  • 如何处理手动输入 yes ,我是利用的 expect,按照命令如下
apt-get install expect

我之前还尝试过用命令

apt-get install tcl tk expect

死活装不成功,其实你在安装 expect 的时候,tcl 和tk会自动安装的

二、安装细节

2.1、 每一个 redis 节点的配置文件如下:

# redis_30001_cluster.conf
bind 0.0.0.0
port 30001
cluster-enabled yes
cluster-config-file "nodes-30001.conf"
logfile "/root/redis-cluster/30001/data/redis-server-30001.log"
dbfilename "dump-30001.rdb"
daemonize yes
appendonly yes
cluster-node-timeout 15000
dir "/root/redis-cluster/30001/data"
protected-mode no
cluster-announce-ip 192.168.10.98
cluster-announce-port 30001
cluster-announce-bus-port 40001

  一般都是部署6个节点,最终实现3主3备,使用时,只需要把配置中的端口号改一改,然后对应的目录也需要新建

2.1 、dockefile 文件

FROM redis:5.0.7

MAINTAINER songbw@credithc.com

RUN apt update 
RUN apt install -y expect

WORKDIR /root
COPY redis_map_file . 
RUN chmod +x start.sh
RUN chmod +x core.ex

EXPOSE 30001
EXPOSE 30002
EXPOSE 30003
EXPOSE 30004
EXPOSE 30005
EXPOSE 30006

EXPOSE 40001
EXPOSE 40002
EXPOSE 40003
EXPOSE 40004
EXPOSE 40005
EXPOSE 40006

ENTRYPOINT ["./start.sh"]

  这里基础镜像我用的是redis 的 5.0.7 版本,目录 redis_map_file 的结构如下:

.
|____redis-cluster
| |____30003
| | |____cfg
| | | |____redis_30003_cluster.conf
| | |____data
| | | |____dump-30003.rdb
| | | |____redis-server-30003.log
| | | |____appendonly.aof
| | | |____nodes-30003.conf
| |____del_nodes_cluster.sh
| |____modify_ip.sh
| |____30002
| | |____cfg
| | | |____redis_30002_cluster.conf
| | |____data
| | | |____redis-server-30002.log
| | | |____appendonly.aof
| | | |____dump-30002.rdb
| | | |____nodes-30002.conf
| |____30004
| | |____cfg
| | | |____redis_30004_cluster.conf
| | |____data
| | | |____dump-30004.rdb
| | | |____nodes-30004.conf
| | | |____appendonly.aof
| | | |____redis-server-30004.log
| |____30006
| | |____cfg
| | | |____redis_30006_cluster.conf
| | |____data
| | | |____nodes-30006.conf
| | | |____appendonly.aof
| | | |____redis-server-30006.log
| | | |____dump-30006.rdb
| |____30001
| | |____cfg
| | | |____redis_30001_cluster.conf
| | |____data
| | | |____dump-30001.rdb
| | | |____redis-server-30001.log
| | | |____appendonly.aof
| | | |____nodes-30001.conf
| |____30005
| | |____cfg
| | | |____redis_30005_cluster.conf
| | |____data
| | | |____dump-30005.rdb
| | | |____appendonly.aof
| | | |____nodes-30005.conf
| | | |____redis-server-30005.log
|____core.ex
|____start.sh

  每一个节点的配置单独用一个目录存放,所以存在 30001 到 30006 6个目录,每个目录下存在一个cfg目录和一个data目录,cfg 目录存放当前节点的配置,data目录下的文件都是启动redis以后自动生成的,初始状态是空的就行
  上面给出了 30001端口redis节点的配置,其它 redis节点的配置,只需要把配置中的 30001 改成对应的端口号就行了
  至于脚本 del_nodes_cluster.sh 和脚本 modify_ip.sh 可以忽略调,因为我已经将里面的shell 代码写入了 start.sh 中,del_nodes_cluster.sh 的作用是清理 data 目录下的数据,因为当 ip 改变时,说明是在新的机器上部署 redis 集群,此时需要把 data 下的数据全部删掉,modify_ip.sh 的作用时用来修改 redis 配置中的 ip 的

start.sh 的内容如下:

#!/bin/bash

redis_cluster_dir='/root/redis-cluster'

#Write a function to modify the IP address
function modify_cfg_ip()
{
    conf_files=`find $redis_cluster_dir -name redis*conf`
    for file in $conf_files
    do
        ip=`sed -n '13p' $file|awk '{print $2}'`
        echo "current state.["$ip"]""["$file"]"
        if [ -n "$1" ];then
            echo "start modify ip.["$1"]"
            sed -i  "13s/${ip}/$1/g" $file
            echo "finish modify ip."
        fi
    done
}

#Write a function to delete unnecessary data
function del_old_data()
{
    find $redis_cluster_dir -name \*aof|xargs -I {} rm -rf {}
    find $redis_cluster_dir -name \*rdb|xargs -I {} rm -rf {}
    find $redis_cluster_dir -name \*log|xargs -I {} rm -rf {}
    find $redis_cluster_dir -name nodes\*conf|xargs -I {} rm -rf {}
}

#Start Redis node  
function start_redis_node()
{
    redis-server ~/redis-cluster/30001/cfg/redis_30001_cluster.conf
    redis-server ~/redis-cluster/30002/cfg/redis_30002_cluster.conf
    redis-server ~/redis-cluster/30003/cfg/redis_30003_cluster.conf
    redis-server ~/redis-cluster/30004/cfg/redis_30004_cluster.conf
    redis-server ~/redis-cluster/30005/cfg/redis_30005_cluster.conf
    redis-server ~/redis-cluster/30006/cfg/redis_30006_cluster.conf
}

#HOST_IP=192.168.10.32
redis_1_cfg='/root/redis-cluster/30001/cfg/redis_30001_cluster.conf'
#get ip in configure
conf_ip=`sed -n '13p' $redis_1_cfg|awk '{print $2}'`

echo "ip["$conf_ip"]["$HOST_IP"]"

if [ "$HOST_IP" != "$conf_ip" ];then
    echo "IP has changed, rebuilding the cluster"
    modify_cfg_ip $HOST_IP
    del_old_data
    start_redis_node 
    /root/core.ex $HOST_IP
else
    echo "Start Redis directly"
    start_redis_node
fi

#service ssh start && tail -f /var/log/wtmp
tail -f /dev/null

  脚本并不难,大的逻辑,是判断 ip 是否改变,如果 ip 改变,说明在新的宿主机上部署,此时需要做四件事情,一是删除 data 目录下的数据,二是修改redis配置中的ip 为新的宿主机的ip,三是启动redis节点,四是调用脚本 core.ex,用来打通不同的 redis节点,构建集群
  如果 ip 不变,说明一直在同一台宿主机上运行,直接启动 redis 节点就可以了

自动输入yes 的 脚本 core.ex 的内容如下:

#!/usr/bin/expect
set ip [lindex $argv 0]
set timeout -1
spawn redis-cli --cluster create $ip:30001 $ip:30002 $ip:30003 $ip:30004 $ip:30005 $ip:30006 --cluster-replicas 1
expect {
    "accept" {send "yes\r";exp_continue}
}

  这个脚本也不难,是在构建redis集群的过程中,实现,自动输入yes

2.2、新建容器

新建容器的命令如下:

docker run -itd -e HOST_IP=10.23.34.42 -p 30001:30001 -p 40001:40001 -p 30002:30002 -p 40002:40002 -p 30003:30003 -p 40003:40003 -p 30004:30004 -p 40004:40004 -p 30005:30005 -p 40005:40005 -p 30006:30006 -p 40006:40006 --name=voice_redis_cluster 96375884cb72

  这些端口号,在 redis通信过程中都要用到,所以都透出来了,HOST_IP 存放的是宿主机的ip,如上面所说,会根据此ip 和当前redis配置中的ip 进行对比,来进行不同的动作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值