使用docker做一个主从同步的redis集群

查看容器内部信息

之前用docker run -it --name redis-master redis /bin/bash创建了一个redis的docker,现在登陆发现状态已经是exit,于是就使用docker container start 容器ID号or容器名称来重新启动。如图:
paradin

然后书里说到要用docker inspect来查看所挂载volume的情况,使用命令:

1
[root@chen-docker ~]# docker inspect --format "{{ .Volumes }}" f391531120b0

但是很不幸,系统反馈给我一个错误:

1
Template parsing error: template: :1:3: executing "" at <.Volumes>: map has no entry for key "Volumes"

没有这个Volumes,那就干脆查看一下这个容器的所有信息:docker inspect f391531120b0,这个命令里面有Config、MountsHostConfigNetworkSettings等等整个容器的所有信息,比如看一下NetworkSettings相关的内容,如图:
paradin

此时使用如下命令:

1
2
3
4
[root@chen-docker ~]# docker inspect --format "{{ .NetworkSettings.IPAddress }}" f391531120b0    #注意前面的.
192.168.0.2
[root@chen-docker ~]# docker inspect --format "{{ .NetworkSettings.MacAddress }}" f391531120b0
02:42:c0:a8:00:02

这样就可以获取到内网IP和mac地址,同理换成docker inspect f391531120b0 | grep Mounts -A 10,看一下挂载信息,如图:
paradin

原来容器里的/data其实就是宿主机的/var/lib/docker/volumes/94b3c20a6d269c7498ab59ee45c560e84fed64a636767a4baa54fa7befbcd4ff/_data这个文件夹。为了验证这一点,我先到宿主机去创建一个叫aaa文件,如下:

1
2
root@f391531120b0:/data# cat aaa 
123123

再返回到宿主机上看:

1
2
3
4
5
[root@chen-docker ~]# cd /var/lib/docker/volumes/94b3c20a6d269c7498ab59ee45c560e84fed64a636767a4baa54fa7befbcd4ff/_data
[root@chen-docker _data]# ls
aaa
[root@chen-docker _data]# cat aaa
123123

这就搞定了!

主从同步排错

就是按书里写的开始配置和启动redis-slave,但是却发现同步没有成功,在redis-slave日志里发现这样的话:

1
2
3
32677:S 08 Feb 16:14:40.952 * Connecting to MASTER 172.168.10.70:6379
32677:S 08 Feb 16:14:40.952 * MASTER <-> SLAVE sync started
32677:S 08 Feb 16:14:40.953 # Error condition on socket for SYNC: Connection refused

这个的原因就是redis主服务器绑定了127.0.0.1,那么跨服务器IP的访问就会失败,从服务器用IP和端口访问主的时候,主服务器发现本机6379端口绑在了127.0.0.1上,也就是只能本机才能访问,外部请求会被过滤。所以需要修改redis-masterredis.conf,注释掉bind 127.0.0.1,如果是线上生产环境建议绑定IP地址。

重新启动redis之后,发现同步依然失败,日志变成了这样:

1
2
3
4
5
6
90:S 17 Apr 09:27:35.906 * Non blocking connect for SYNC fired the event.
90:S 17 Apr 09:27:35.907 # Error reply to PING from master: '-DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect'
90:S 17 Apr 09:27:36.908 * Connecting to MASTER 192.168.0.2:6379
90:S 17 Apr 09:27:36.909 * MASTER <-> SLAVE sync started
90:S 17 Apr 09:27:36.909 * Non blocking connect for SYNC fired the event.
90:S 17 Apr 09:27:36.909 # Error condition on socket for SYNC: Connection reset by peer

这个日志的意思是说redis在没有开启bind和密码的情况下,保护模式被开启。然后Redis的只接受来自环回IPv4和IPv6地址的连接。于是还是要修改redis-master的redis.conf关闭保护模式:portected-mode no,然后重启redis-master即可。

容器内安装ping

先检查你的容器是使用什么系统的景象,如果是ubantu那就是apt-get,安装ping的命令如下:

1
2
apt-get update
apt-get install inetutils-ping

如何让容器一直启动

如果用了一段时间的docker就会发现,我们的容器经常用了一段时间就自动退出了,docker ps已经找不到了,在docker ps -a里面了,如图:
paradin

然后我们docker start containerId想重新开启这个容器,可能这次来的更快,没几分钟容器又自己关了,由这个问题又可能引发其它很多的问题。

docker run指定的命令如果不是那些一直挂起的命令(比如运行top,不断echo),就是会自动退出的。-d命令是设置detach为true,根据官方的文档,意思是让这个命令在后台运行,但并不是一直运行,Docker容器后台运行,就必须有一个前台进程。主线程结束,容器会退出。

我们启动容器的时候不要-d命令启动,用-dit就好了,例如:

1
2
docker run -d hello-world(不要这么做)
docker run -dit hello-world(推荐)

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------