博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(记录贴)Docker构建Tomcat、Nginx、Haproxy、Mysql集群
阅读量:2400 次
发布时间:2019-05-10

本文共 10739 字,大约阅读时间需要 35 分钟。

前言

原本是选择在自己的云服务器上搭建Docker,但是建集群的时候发现Mysql只能启动一个实例,第二个实例运行后会自动关闭,经过排查发现是渣渣服务器的内存不够支撑多实例。

于是还是借助虚拟机环境来搭建,也能模拟多台服务器安装的情况。

本博客作为记录篇,用于Docker下快速搭建

Tomcat、Mysql、Nginx、Haproxy集群环境

目录

安装虚拟机

VMware中文破解版

链接:https://pan.baidu.com/s/1zSxo5u_PrJhTuxNqShIvEA

提取码:w2es

CentOS7镜像

官方镜像地址http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1810.iso

XobaXterm

一开始我是用Putty连接+WinSCP传输文件,后来发现新的工具XobaXterm功能还挺多的。

和VM一起都放在上面的网盘里了

安装CentOS的虚拟机步骤就不复述了,为方便测试直接选用root账号登录,不嫌麻烦也可以用sudo获取root操作权限。

Docker安装

/-/y是指后续Y/N操作都以Y执行yum install -y docker//安装后执行显示版本则成功docker version

配置镜像加速

至 获取镜像加速地址

手动修改/etc/docker/daemon.json为
{
个人的加速地址
}
或者直接执行网址内的shell脚本

创建网关

//创建网关 避免每次重启ip变化

docker network create --subnet=172.18.0.0/16 mynetwork

Tomcat容器装载

//拉取tomcat镜像docker pull tomcat//运行普通容器docker run --name tomcat -d tomcat//复制webapp出来 因为这个目录不是运行生成的就会直接被覆盖 容器运行后生成的不会被覆盖可以不复制docker cp tomcat:/usr/local/tomcat/webapps /docker/tomcat/webapps///删除容器docker stop tomcatdocker rm tomcat//运行正式容器 启动双实例共用webappsdocker run \-p 12001:8080 \--restart=always \--privileged=true \--name tomcat_02 \-v /docker/tomcat/tomcat_02/webapps:/usr/local/tomcat/tomcat/webapps \--network=mynetwork \--ip 172.18.0.12 \-d tomcat

Mysql容器装载

//拉取mysql镜像 不加版本默认下最新版docker pull mysql:5.7.17//创建配置文件 内容在下面touch /docker/mysql/conf/my_01.cnf//创建挂载文件 需要与下面启动配置与my.cnf中配置的对应 配置文件存放路径:/docker/mysql/conf/my.conf数据文件存放路径:/docker/mysql/data日志文件存放路径:/docker/mysql/logs//查看镜像Image_iddocker images//启动mysql容器  启动失败使用docker logs --tail=30 mysql 查看//运行正式容器 启动双实例docker run \-p  22001:3306 \--restart=always \--privileged=true \--name mysql_02 \-e MYSQL_ROOT_PASSWORD=123456 \-v /docker/mysql/mysql_02/conf/my.cnf:/etc/mysql/my.cnf \-v /docker/mysql/mysql_02/logs:/usr/local/mysql/logs \-v /docker/mysql/mysql_02/data:/usr/local/mysql/data \--network=mynetwork \--ip 172.18.0.22 \-d mysql

my.cnf配置

[client]default-character-set=utf8port=3306[mysql]default-character-set=utf8 [mysqld]character-set-server=utf8collation-server=utf8_unicode_cidatadir=/usr/local/mysql/datasql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION[mysqld_safe]log_error=/usr/local/mysql/logs/mysql_error.logslow_query_log = 1#超过1秒则为慢查询long_query_time = 1 slow_query_log_file = /usr/local/mysql/logs/mysql_slow.log

再通过Navicat进行连接测试

看Mysql版本,可能需要开通远程登录权限,另外如果真实环境使用的话,服务器防火墙及云服务器安全组之类的都需要设置
在这里插入图片描述

Nginx装载

Nginx主要是web服务器,具备负载均衡LB的功能,多进程模式,社区活跃,然后是因为Nginx在负载均衡下的能力比Haproxy差一点,以及它不支持TCP,要实现Mysql的负载均衡要使用插件,所以后面又使用Haproxy作为负载均衡中间件使用。

//拉取nginx镜像docker pull nginx//运行普通容器docker run --name nginx -d nginx//复制容器运行必备的配置文件 直接挂载的话会被覆盖成空文件导致运行失败 容器运行后生成的不会被覆盖可以不复制docker cp nginx:/etc/nginx/nginx.conf /docker/nginx/conf///删除容器docker stop nginxdocker rm nginx//运行正式容器 docker run \-p 31001:80 \--restart=always \--privileged=true \--name nginx \-v /docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \-v /docker/nginx/conf/conf.d:/etc/nginx/conf.d \-v /docker/nginx/html:/usr/share/nginx/html \-v /docker/nginx/logs:/var/log/nginx \--network=mynetwork \--ip 172.18.0.31 \-d nginx:latest

nginx.conf

user  nginx;worker_processes  4; #工作进程数,为CPU的核心数或者两倍error_log  /var/log/nginx/error.log warn;pid        /var/run/nginx.pid;events {     use epoll;   #Linux最常用支持大并发的事件触发机制     worker_connections  65535;}http {    include       /etc/nginx/mime.types;    default_type  application/octet-stream;    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for"';    access_log  /var/log/nginx/access.log  main;    sendfile        on;    #tcp_nopush     on;    keepalive_timeout  120;    #gzip  on;    #gzip  on;    limit_conn_zone $binary_remote_addr zone=perip:10m;   #添加limit_zone,限制同一IP并发数    include /etc/nginx/conf.d/*.conf;   #包含nginx虚拟主机配置文件目录}

conf.f/myhost

upstream test {  ip_hash;  #server 192.168.65.129:18080 weight=1;#根据上面IIS配置  #server 192.168.65.129:18081 weight=1;#根据上面IIS配置  server 172.18.0.3:8080 weight=1;  server 172.18.0.2:8080 weight=1;}server {        listen       80;         server_name  localhost;         #charset GB2312;         location /         {               proxy_redirect off;               proxy_set_header        Host $host;               proxy_set_header        X-Real-IP $remote_addr;              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;               proxy_pass http://test;        }         # 查看nginx的并发连接数配置        location /NginxStatus        {             stub_status             on;             access_log              off;             auth_basic              "NginxStatus";        }        access_log  off;        error_page 404  /404.html;        error_page   500 502 503 504 /404.html;        location = /404.html {            root   html;        }        limit_conn perip 200;   #同一ip并发数为200,超过会返回503}

Haproxy装载

//拉取haproxy镜像docker pull haproxy//创建配置文件 内容往下touch /docker/haproxy/config/haproxy.cfg//运行正式实例 同样创建多个实例 这里挂载的keepalived后续使用docker run \-p 32001:8888 -p 32002:3306 \--restart=always \--privileged=true \--name haproxy_02 \-v /docker/haproxy/haproxy_02/config:/usr/local/etc/haproxy \-v /docker/haproxy/haproxy_02/keepalived.conf:/etc/keepalived/keepalived.conf \--network=mynetwork \--ip 172.18.0.32 \-d haproxy

haproxy.cfg

需要在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测,用户名可在配置文件中配置

global	#工作目录	chroot /usr/local/etc/haproxy	#日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info	log 127.0.0.1 local5 info	#守护进程运行	daemon defaults	log	global	mode	http	#日志格式	option	httplog	#日志中不记录负载均衡的心跳检测记录	option	dontlognull    #连接超时(毫秒)	timeout connect 5000    #客户端超时(毫秒)	timeout client  50000	#服务器超时(毫秒)    timeout server  50000 #监控界面	listen  admin_stats	#监控界面的访问的IP和端口	bind  0.0.0.0:8888	#访问协议    mode        http	#登录的URI相对地址    stats uri   /	#统计报告格式    stats realm     Global\ statistics	#登陆帐户信息    stats auth  test:test#数据库负载均衡listen  proxy-mysql	#访问的IP和端口(前面ip=0代表任何ip都可访问)	bind  0.0.0.0:3306      #网络协议	mode  tcp	#负载均衡算法(轮询算法)	#轮询算法:roundrobin	#权重算法:static-rr	#最少连接算法:leastconn	#请求源IP算法:source     balance  roundrobin	#日志格式    option  tcplog	#在MySQL中创建一个没有权限的haproxy用户,密码为空。Haproxy使用这个账户对MySQL数据库心跳检测    option  mysql-check user haproxy    server  NODE1 172.18.0.21:3306 check weight 1 maxconn 2000      server  NODE2 172.18.0.21:3306 check weight 1 maxconn 2000  	#使用keepalive检测死链    option  tcpka

打开监控界面正常

在这里插入图片描述
然后通过Navicat连接Haproxy去查数据库就会发现查询结果是在两个数据库之间按权值跳跃的。

keepalived搭建

keepalived的实现是要在docker服务内创建,所以要进入各自的宿主机进行安装

//进入容器docker exec -it haproxy_01 bash//安装keepalivedapt-get updateapt-get -y install keepalived//配置文件在haproxy的时候映射过,这里就不创建了 内容在下面有//开启keepalivedservice keepalived start//安装pingapt-get install iputils-ping//ip a 查看是否加入网卡 如果存在的话会显示keepalived配置的ipip a //容器及宿主机各自都测试是否连通ping 172.18.0.100

各自的容器和各自的keepalived都ping通后,宿主机也需要安装keepalived,宿主机的keepalived只是作为一个中转,因为外部Ip是没法直接访问到容器内部keepalived生成的vip的。

//宿主机安装keepalivedyum install -y keepalived//修改配置文件/etc/keepalived 在下面有//开启keepalivedservice keepalived start//然后ping虚拟ip 如果ping通而在外部网络不能访问 有防火墙就开端口 有安全组就设置白名单

成功在keepalived的虚拟ip上登录

在这里插入图片描述

容器keepalived.conf

多个容器的配置完全一样,但是要保证他们相互都能Ping通

vrrp_instance  VI_1 {    state  MASTER    interface eth0    virtual_router_id  100    priority  100    advert_int  1    authentication {        auth_type  PASS        auth_pass  123456    }    virtual_ipaddress {        172.18.0.100    }}

宿主机keepalived.conf

vrrp_instance VI_1 {    state MASTER#这里是宿主机的网卡,可以通过ip a查看当前自己电脑上用的网卡名是哪个    interface ens33    virtual_router_id 100    priority 100    advert_int 1    authentication {        auth_type PASS        auth_pass 1111    }    virtual_ipaddress {	#这里是指定的一个宿主机上的虚拟ip,要外部能访问到的,作为中转连接至容器内keepalived172.18.0.100       	192.168.65.222    }}#接受监听数据来源的端口,网页入口使用virtual_server 192.168.65.222 8888 {    delay_loop 3    lb_algo rr     lb_kind NAT    persistence_timeout 50    protocol TCP    #haproxy的对应ip端口    real_server 172.18.0.100 8888 {        weight 1    }}#接受监听数据来源的端口,数据库使用virtual_server 192.168.65.222 3306 {    delay_loop 3    lb_algo rr     lb_kind NAT    persistence_timeout 50    protocol TCP#haproxy的对应ip端口    real_server 172.18.0.100 3306 {        weight 1    }}

MySql集群

首先,通过VM的克隆生成一个新的虚拟机,并运行Docker与Mysql。

或者直接用上述容器生成指令生成多个不同端口Mysql容器
在这里插入图片描述

然后在找资料的过程发现Mysql集群方案实在是有点多,一时不知道做哪种方案。

Replication集群方案(主从同步)

简单原理

1.master上将操作记录到二进制bin-log里面去

2.slaves读取bin-log日志到本地的中继日志relay-log
3.slaves执行relay-log里的事件

复制类型

1.基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时, 会自动选着基于行的复制。

2.基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍。从mysql5.0开始支持。
3.混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
和redis的aof有点类似

实现
主master配置

vi /etc/my.cnf 如果是docker容器修改挂载文件即可

[mysqld]server-id=1		#这个id全局唯一,slaves上的id不能与之冲突log-bin=mysql-bin	#必须开启二进制日志功能

重启数据库并进入执行语句

GRANT REPLICATION SLAVE ON *.* to 'test'@'%' identified by '123456';	#创建一个同步账户,用来同步数据用flush privileges;show master status;#记下数据内容file和position 要再slave中用#这里可以锁住所有表来防止slave部署过程中的修改,但是部署好最后要记得解锁
从slave配置

vi /etc/my.cnf 如果是docker容器修改挂载文件即可

[mysqld]server-id=2		#这个id,全局唯一,不能与master,或者其他slaves冲突log-bin=mysql-bin	#slaves上没有必要开启bin-log功能,当slave作为其他slave的master时除外#binlog-do-db=databasename1,databasename2      #这个参数是指定需要复制的数据库名字,默认复制所有#binlog-ignore-db=databasename1,databasename2  #这个参数是指定不需要复制的数据库名字

重启数据库并进入执行语句

#stop SLAVE;change master to master_host='192.168.65.129',#如果是同服务器Docker部署的就使用服务器内部IP与端口master_port=9001,master_user='test',master_password='123456',master_log_file='mysql-bin.000007',#上面记录的值master_log_pos=311;#上面记录的值start SLAVE;show slave status;

非常关键 如果是采用VM复制的虚拟机,要修改宿主机挂载文件的/docker/mysql/data_01/auth.cnf的id,这个id不能重复,或者进容器内find / -name "auto.cnf"再修改,不过要安装vim比较麻烦

如果Slave_Sql_Running是NO,可以尝试执行

stop slave ;set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;start slave ;show slave STATUS;

总而言之,如果运行失败一定要去看日志文件

docker logs -f --tail=30 mysql01

同步效果

测试了同服务器不同docker容器及不同服务器下的集群

192.168.65.129_9001
192.168.65.129_9002
192.168.65.130_9001
注意
服务器内部使用docker连接的话需要使用内部的IP及容器内部端口
服务器之间则直接使用外部IP与外部端口
在这里插入图片描述

PXC集群方案

docker pull percona/percona-xtradb-cluster//创建挂载目录docker volume rm  v1docker volume rm  v2docker volume rm  v3docker volume create --name v1docker volume create --name v2docker volume create --name v3//查看目录docker volume inspect v1 //创建网络docker network create --subnet=172.19.0.0/24 pxc//开防火墙firewall-cmd --zone=public --add-port=3301/tcp --permanentfirewall-cmd --zone=public --add-port=3302/tcp --permanentfirewall-cmd --reloaddocker run \-p 3301:3306 \--name=node1 \--privileged=true \-e CLUSTER_NAME=cluster1 \-e MYSQL_ROOT_PASSWORD=root  \-e XTRABACKUP_PASSWORD=root \--net=pxc \--ip 172.19.0.2 \-d pxcdocker run \-p 3302:3306 \--name=node2 \--privileged=true \-e CLUSTER_NAME=cluster1 \-e MYSQL_ROOT_PASSWORD=root  \-e XTRABACKUP_PASSWORD=root \ -e CLUSTER_JOIN=node1 \--net=pxc \--ip 172.19.0.3 \-d pxc

转载地址:http://veiob.baihongyu.com/

你可能感兴趣的文章
我的个人论坛*
查看>>
DBA notes
查看>>
bonny-erp
查看>>
linux公社
查看>>
广州劳动保障网
查看>>
linux伊甸园
查看>>
榕树下
查看>>
Linux下的压缩文件剖析(zt)
查看>>
xp优化19招
查看>>
e龙旅行网
查看>>
fuyuncat
查看>>
我看看中文网
查看>>
Unix 高级用户命令 lsof 和 fuser (zt)
查看>>
dbasupport
查看>>
使用logrotate 管理Linux日誌檔(zt)
查看>>
第一次安装完linux不能上网的解决办法?
查看>>
zlc158
查看>>
linux安装完后的操作!
查看>>
(redhat) 在tcp/ip层次上创建虚拟接口.
查看>>
Apache
查看>>