在上一篇文章《在一台centos7服务器上搭建redis集群以及哨兵sentinel》中,我们提到了一个很重要的知识点,大家可以去看看。
在这里,我们会反复提到这个知识点,对于docker下部署redis sentinel非常重要。
部署环境
- 假设该宿主机服务器的ip是:192.168.1.100,docker0的ip是:172.17.0.1
- 使用redis的镜像是:docker pull redis:5.0.4
- redis只搭建1主1从(网上很多都是1主2从,没有这个必要),3个sentinel(3个是必须的,否则在failover的时候就会出现一些不必要的问题)
- 6379:redis server,docker的volume目录在 /data/redis-6379
6380: redis server,docker的volume目录在 /data/redis-6380
26379:redis sentinel,docker的volume目录在 /data/redis-26379
26380:redis sentinel,docker的volume目录在 /data/redis-26380
26381:redis sentinel,docker的volume目录在 /data/redis-26381
部署过程
部署redis-6379
1,mkdir -p /data/redis-6379/conf && mkdir -p /data/redis-6379/data && chmod 666 -r /data/redis-6379 && cd /data/redis-6379/conf
这里的chmod 666 非常重要,原因有下面2个:
我们从redis Dockerfile中可以看到,docker中的redis用户和用户组是 redis,
RUN mkdir /data && chown redis:redis /data
redis在进行sentinel,failover的时候会改写配置文件,redis的用户是redis,而宿主机的目录是另外的人,所以需要改变目录权限
2,vi redis.conf,内容如下:
requirepass “123456”
masterauth “123456”
slave-announce-ip “192.168.1.100”
slave-announce-port 6379
重点来了,这里的masterauth,已经从上一篇文章中解释了。
还有2个配置:slave-announce-ip,slave-announce-port这2个呢?原因和masterauth一样的,当发生failover的时候,这个原先是主的redis就会成为从,所以这2个配置是给主在成为从的时候使用的。但是为什么要在docker环境中用这2个配置,在上一篇文章中为什么不用呢?因为在docker环境下,假如不用这2个配置,那么在连接到主服务器上后,ip地址会变成172.17.0.1这个docker0地址,同时端口始终是6379。等下我们可以看看。
3,加入 docker-compose.yml 以下内容
redis-6379:
image: redis:5.0.4
container_name: redis-6379
volumes:
- /data/redis-6379/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /data/redis-6379/data:/data
ports:
- 6379:6379
command: redis-server /usr/local/etc/redis/redis.conf
4,运行docker-compose
docker-compose up -d redis-6379
5,登录redis控制台
docker exec -it redis-6379 /bin/bash
redis-cli
auth 123456
info
可以看到role: master
exit
exit
部署redis-6380
1,mkdir -p /data/redis-6380/conf && mkdir -p /data/redis-6380/data && chmod 666 -r /data/redis-6380 && cd /data/redis-6380/conf
2,vi redis.conf,内容如下:
requirepass “123456”
masterauth “123456”
slaveof 192.168.1.100 6379
slave-announce-ip “192.168.1.100”
slave-announce-port 6380
3,加入 docker-compose.yml 以下内容
redis-6380:
image: redis:5.0.4
container_name: redis-6380
volumes:
- /data/redis-6380/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /data/redis-6380/data:/data
ports:
- 6380:6379
command: redis-server /usr/local/etc/redis/redis.conf
4,运行docker-compose
docker-compose up -d redis-6380
5,登录redis控制台
docker exec -it redis-6379 /bin/bash #注意这里是登录6379这个主redis容器
redis-cli
auth 123456
info
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.1.100,port=6380,state=online,offset=561,lag=1
这里可以看到 slave的ip是正确的。假如我们在 6380 的配置中没有设置slave-announce-ip “192.168.1.100” 和 slave-announce-port 6380的话,那么将在这里看到的是 slave0:ip=172.17.0.1,port=6379,state=online,offset=561,lag=1,如此的设置当然会在failover的时候发生异常了。所以从这里能很清楚明白这2个配置的重要性。
exit
exit
部署redis-26379
1,mkdir -p /data/redis-26379/conf && mkdir -p /data/redis-26379/data && chmod 666 -r /data/redis-26379 && cd /data/redis-26379/conf
2,vi sentinel.conf,内容如下:
protected-mode no
port 26379
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel auth-pass mymaster 123456
sentinel announce-ip “192.168.1.100”
sentinel announce-port 26379
这里的2个配置 sentinel announce-ip 和 sentinel announce-port 和 上面的那2个意思大致差不多,假如不这么设置的话,那么在 sentinel 的ip通信中就会出现 172.17.0.1:26379 这样错误的值。下面会进一步说到。
3,加入 docker-compose.yml 以下内容
redis-26379:
image: redis:5.0.4
container_name: redis-26379
volumes:
- /data/redis-26379/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf
- /data/redis-26379/data:/data
ports:
- 26379:6379
command: redis-server /usr/local/etc/redis/sentinel.conf
4,运行docker-compose
docker-compose up -d redis-26379
部署redis-26380
1,mkdir -p /data/redis-26380/conf && mkdir -p /data/redis-26380/data && chmod 666 -r /data/redis-26380 && cd /data/redis-26380/conf
2,vi sentinel.conf,内容如下:
protected-mode no
port 26379
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel auth-pass mymaster 123456
sentinel announce-ip “192.168.1.100”
sentinel announce-port 26380
3,加入 docker-compose.yml 以下内容
redis-26380:
image: redis:5.0.4
container_name: redis-26380
volumes:
- /data/redis-26380/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf
- /data/redis-26380/data:/data
ports:
- 26380:6379
command: redis-server /usr/local/etc/redis/sentinel.conf
4,运行docker-compose
docker-compose up -d redis-26380
5,cat /data/redis-26379/conf/sentinel.conf #注意这里查看 redis-26379
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 192.168.1.100 6380
sentinel known-sentinel mymaster 192.168.1.100 26380 75f969e584d6cae9f23a6f9da6069d8c69873452
从这里能注意到2件事情:
a,看到“Generated by CONFIG REWRITE”这句注释,说明redis对配置文件进行了修改。这就是为什么我们一开始就把配置文件所在的volumn的权限设置为666的原因:chmod 666 -r /data/redis-xxx,假如上面没有修改,那么就会报错:CONFIG REWRITE failed: Permission denied,这个错误不影响启动,但是会影响发生failover后的一些问题,所以一定要事先设置好权限。
b,看到 192.168.1.100 26380 这个配置,这就是前面所讲到的 sentinel announce-ip, sentinel announce-port 的作用,假如没有设置,那么这里将是 172.17.0.1 26379 这个错误的ip。
cat /data/redis-26380/conf/sentinel.conf,也能看到如此的情况,不多说
部署redis-26381
这里不多说,和 redis-26380类似。
测试
咱们用 https://github.com/champbay/redis-sentinel 这个工程来进行测试
启动这个工程后,可以看到不断的往 redis 中插入 test-i 这样的值
然后,docker stop redis-6379,马上可以看到这个工程开始报错,大概过了5秒钟(因为我上面设置的是5秒钟),又恢复正常了,说明 redis sentinel已经起效了。
我们查看一下 6380 的配置文件,cat /data/redis-6380/conf/redis.conf,看到 slaveof 已经不见了,间接说明成为了主。通过进入redis-6380容器,redis-cli看一下info,可以看到确实成为了master。这里也说明需要事先修改一下配置文件的权限,否则这里就会报错。
我们再次启动 docker start redis-6379,稍等一会,查看6379的配置文件,发现最后多了一行 slaveof 192.168.1.100 6380,(slaveof == replicaof),说明已经成为了从,从 redis-cli也能看出。