(记录贴)Docker构建Tomcat、Nginx、Haproxy、Mysql集群

前言

原本是选择在自己的云服务器上搭建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 tomcat
docker rm tomcat
//运行正式容器 启动双实例共用webapps
docker 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_id
docker 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=utf8
port=3306

[mysql]
default-character-set=utf8
 
[mysqld]
character-set-server=utf8
collation-server=utf8_unicode_ci
datadir=/usr/local/mysql/data
sql_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.log
slow_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 nginx
docker 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
//安装keepalived
apt-get update
apt-get -y install keepalived

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

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

//宿主机安装keepalived
yum install -y keepalived
//修改配置文件/etc/keepalived 在下面有
//开启keepalived
service 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  v1
docker volume rm  v2
docker volume rm  v3
docker volume create --name v1
docker volume create --name v2
docker 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 --permanent
firewall-cmd --zone=public --add-port=3302/tcp --permanent
firewall-cmd --reload

docker 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 pxc


docker 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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值