Docker应用:容器间通信与Mariadb数据库主从复制

笔者今天搞了一天利用Mariadb数据库容器完成主从复制。总结下来有五个方面的内容,从VirtualBox到容器通信,最后到数据库主从复制,记录自己的配置完成过程。整个过程有些小细节需要注意,在虚拟机里面可能会被各种IP地址搞晕。数据库主从复制对于笔者来说其实轻车熟路了,比较以往在树莓派上配置过很多次,如果需要详细的配置过程请翻阅笔者以前的文章,不吝赐教!
Docker真的是太劲了,下一次在此基础上试一下利用中间件完成数据库读写分离、负载均衡等等, Docker在闪耀!
【Docker应用:容器间通信与Mariadb数据库主从复制】记录一个问题:在测试容器host网络时,通过宿主IP地址居然无法连接数据库,一时无法解决,待往后研究吧!
文章结构如下:
一、VirtualBox的网络连接设置
二、使用同一个镜像运行两个容器
三、容器间通信
四、容器内工具安装
五、Mariadb数据库主从复制
一、VirtualBox的网络连接设置
开始测试前来说明一下VirtualBox的网络连接问题。因平时笔者再家中时直接使用VirtualBox的桥接网络会分配一个独立的IP地址,但是公司因为有上网认证,linux系统没有认证上不了网,于是笔者只能使用仅主机(Host-Only)网络。关于VirtualBox的几个网络配置阐述一下。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
1、Bridged Adapter(网桥模式)。
通过主机网卡,架设了一条桥,直接连入到网络。虚拟机能被分配独立的IP,所有网络功能完全和在网络中的真实机器一样。
2、Host-only Adapter(主机模式)
在主机中模拟出一张专供虚拟机使用的网卡,所有虚拟机都是连接到该网卡上的,我们可以通过设置这张网卡来实现上网及其他很多功能,在适配器选项里面可以看到虚拟的网卡。host-only网卡默认IP段为192.168.56.X。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
3、Network Address Translation(网络地址转换)
虚拟机访问网络的所有数据都是由主机提供的,并不真实存在于网络中。只能单向访问,虚拟机可以通过网络访问到其他主机。
4、Internal(内网模式)
虚拟机与外网完全断开,只实现虚拟机于虚拟机之间的内部网络模式。
既然linux接入外网无法获得IP地址,不能上网,不能使用Bridged Adapter(网桥模式)。但是主机有与虚拟机通信的需求,那么就配置成Host-only Adapter(主机模式),虚拟机里面是192.168.56.X的IP地址,外部网络可以通过这个ip地址来访问虚拟机。那么你可能要问了,不同网段怎么通信呢?就是虚拟网卡192.168.56.1来作为网关来通信的。
在虚拟机里面要设置网络开机启动。笔者使用的是centos7,有两种方法来设置,一个是桌面右上角网络里面设置开机启动,二是修改配置文件。重点是定位到你的自己IP地址的网卡,比如笔者的是enp0s3,然后设置ONBOOT=yes 。
如果修改了其他参数,可以执行sudo systemctl restart network.service重启网络服务。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
二、使用同一个镜像运行两个容器 接上一篇文章-Docker应用:Mariadb数据库安装与使用,笔者将mariadb-test重命名为 mariadb-master。
docker rename mariadb-testmariadb-master
然后利用mariadb镜像再运行一个容器。
docker run -itd --name mariadb-slave -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mariadb
注意端口号要与3306区别开来。前面的端口为本地主机端口3307(不能写为3306,因为占用了),映射到容器的3306端口。docker ps查看运行的容器:
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
在cmd中远程连接也正常,注意默认端口是3306,需要指定3307.
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
三、容器间通信 docker创建了三个网络,用docker network ls命令查看bridge、host、none。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
1、bridge网络
Docker安装时会创建一个为docker0(网关)的Linux bridge。如果不指定-network,创建的容器默认都会挂到docker0上,运行ip adrr可以查看docker0的IP地址。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
运行docker network inspect bridge看一下bridge 网络的配置信息:
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片


掩码"Subnet": "172.17.0.0/16",网关 "Gateway": "172.17.0.1"
mariadb-master的IP地址为:172.17.0.2/16
mariadb-slave的IP地址为:172.17.0.3/16
也可以进入容器来查看IP地址:
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
因容器内没有ping工具,在虚拟机上ping两个ip地址成功。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
因启动 Docker 容器的时候,使用默认的网络是不支持指派固定IP的,如果要指定固定IP地址就需要在 Docker 中创建自定义网络。
2、host网络
连接到host网络的容器共享Docker host的网络栈,容器的网络配置与host完全一样。host模式类似于桥接模式,与宿主机在同一个网络中,没有独立IP地址,要考虑端口冲突问题。容器将不会虚拟出自己的网卡,但是容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
docker run -itd --name mariadb-test --network=host -e MYSQL_ROOT_PASSWORD=123456 mariadb

使用host网络的mariadb数据库容器,进入容器后查看IP地址和宿主机是一样的。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
如果你指定了端口,host网络不支持端口映射,也会有相应的提示:WARNING: Published ports are discarded when using host network mode 。
使用命令 netstat -tulpn | grep 3306 来查看监听端口正在被使用,但是值得奇怪的时,在局域网中通过宿主IP地址居然无法连接数据库,估计是root用户的权限问题,运行容器里面可以加上-e MYSQL_ROOT_HOST=% 或进入日期后修改root用户的权限。因为笔者接下里的配置时基于bridge网络,利用容器内部IP来通信的。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
这种方式类似于在宿主机上安装了一个标准mariadb服务器,容器内部的服务端使用宿主机的IP地址和端口,不需要进行NAT。host最大的优势就是网络性能比较好,但是要考虑端口冲突,同时网络隔离性不好。
3、none网络
这个网络下的容器除了loopback,没有其他任何网卡,可以通过-network=none指定使用none网络,这种网络隔离性十分好。
2021年3月11日晚:
在虚拟机上使用Host-only Adapter(主机模式),可以完成宿主机与虚拟机通信,但是碍于centos不能认证上网,不能安装编辑器(容器里面没有vi nano 等),于是笔者只能回家完工。改为Bridged Adapter(网桥模式)启动,数据库还是使用bridge网络,所以IP地址有变动:
虚拟机IP地址为:192.168.31.120
宿主机IP地址为:192.168.31.40
mariadb-master容器:172.17.0.2/16,外部地址192.168.31.120:3306
mariadb-slave容器:172.17.0.3/16,外部地址192.168.31.120:3307
四、容器内工具安装 因为要配置编辑器和网络工具,需要上网安装。容器内没有vi vim nano编辑器,没有yum安装工具,但有apt和ap-get工具,于是就可可以使用来安装需要的工具。或者参考笔者的文章做数据持久化处理,映射配置文件到宿主机上。
安装前要apt update(或者apt-getupdate,较慢)更新软件列表,不然可能找不到软件。
1、安装ping工具
apt install inetutils-ping
在mariadb-master容器可以ping172.17.0.3,测试成功;
在mariadb-slave容器可以ping172.17.0.2,测试成功;
那么意味着使用容器内的IP可以完成容器相互通信。
2、安装nano编辑器
apt install nano
五、Mariadb数据库主从复制 1、进入mariadb-master容器
docker exec -it mariadb-master bash
2、进入数据库mysql -hlocalhost -uroot -P3306 -p123456
新建数据库test,然后建立一张表cards:
DROP TABLE IF EXISTS `cards`;
CREATE TABLE IF NOT EXISTS `cards` (
`card_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`card_number` varchar(100) DEFAULT NULL COMMENT '卡号',
PRIMARY KEY (`card_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;


接下来就是参照笔者以前的文章配置主从复制了。
3、退出到数据库修改50-server.cnf配置文件
server-id = 1
log_bin= /var/log/mysql/mysql-bin.log
expire_logs_days= 10
binlog_do_db= test
4、创建同步账号sync,密码sync。
grant replication slave on *.* to 'sync'@'172.17.0.3' identified by 'sync';
flush privileges;
5、进入mariadb-slave容器
docker exec -it mariadb-slave bash
6、和master一样,新建数据库test,然后建立一张表card,但先不要插入数据。
7、退出到数据库修改50-server.cnf配置文件
server-id = 2
完成配置文件的修改后,需要重启两个docker容器使其配置文件生效。注意的是,容器内的service命令不能使用,所以命令service mysqld restart是不成功的,需要重启容器来使配置生效。
docker restart mariadb-master
docker restart mariadb-slave
8、slave定位指向到master
在slave数据库中运行:
CHANGE MASTER TO master_host='172.17.0.2', master_port=3306,master_user='sync',master_password='sync',master_use_gtid=current_pos;
开启从机slave:
start slave;
查看从机的状态,两个进程状态、Slave_IO_Running、Slave_SQL_Running,GTID状态:
show slave status \G;
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
9、在master中插入几行数据(命令行或Navicat 都行),比如:
insert into cards(card_number) values ("8f6331c4-5738-11eb-95ac-d017c22b48f2");
10、在slave中select查看数据和master中使同步的。
Docker应用:容器间通信与Mariadb数据库主从复制
文章图片
2021年4月12日
鉴于在容器内使用apt安装工具会造成容器非必要的膨胀,在后面的操作中建议将配置文件的目录映射到宿主机,使用宿主机的工具对其进行修改,同时也可以使配置持久化。详情参考笔者后面的文章-Docker映射配置文件到宿主机。

    推荐阅读