docker安装(PXC)mysql集群

安装PXC

PXC 模式,没有主从之分,每个数据库都可以进行读写,数据可以保持强一致性,执行时间较慢,由于一般是强一致性,所以一般用于存储重要的信息,例如金融。

  1. 安装pxc镜像
    进入docker官网找到pxc镜像传送门复制安装pxc进行的指令docker pull percona/percona-xtradb-cluster
  2. 执行该指令,等待linux安装完毕。安装完毕后使用docker images检查是否已经安装
[root@localhost ~]# docker images
REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
docker.io/percona/percona-xtradb-cluster   latest              70b3670450ef        3 months ago        408 MB
  1. 由于系统自带的PXC名字过长,我们可以将他的名字进行修改,方便使用
[root@localhost ~]# docker tag docker.io/percona/percona-xtradb-cluster pxc
[root@localhost ~]# docker rmi docker.io/percona/percona-xtradb-cluster
Untagged: docker.io/percona/percona-xtradb-cluster:latest
Untagged: docker.io/percona/percona-xtradb-cluster@sha256:78460483e99c093d2910d3667d928ed8c2165165554482058875bccafa4ccf0b
[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
pxc                 latest              70b3670450ef        3 months ago        408 MB
  1. 每个PXC节点内部包含一个mysql实例,如果需要创建包含5个数据库节点的数据库集群,那么要创建5个pxc节点。出于安全考虑,需要给PXC集群实例创建一个Docker内部网络。
    1. 创建一个网段docker network create
[root@localhost ~]# docker network create --subnet=172.18.0.0/24 net1
0b8e9701ac4e79239e4a92013ee80a089ff8e9681e881d20a7b1a4ccd8e9ddf9
  1. 查看指定网段信息docker network inspect 网段名称
[root@localhost ~]# docker network inspect net1
[
    {
        "Name": "net1",
        "Id": "0b8e9701ac4e79239e4a92013ee80a089ff8e9681e881d20a7b1a4ccd8e9ddf9",
        "Created": "2019-06-10T09:34:11.010208053+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/24"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
  1. 移除指定网段docker network rm 网段名称
  2. 创建docker卷docker volume create --name
    创建一个docker卷名字为v1,通过查看其详细信息,发现该卷在宿主机的映射地址为/var/lib/docker/volumes/v1/_data
[root@localhost ~]# docker volume create v1
v1
[root@localhost ~]# docker inspect v1
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/v1/_data",
        "Name": "v1",
        "Options": {},
        "Scope": "local"
    }
]
  1. 创建PXC容器


    image.png

    -d :代表创建的容器在后台运行
    -p : 端口映射 宿主机端口:容器端口
    -v :路径映射
    -e MYSQL_ROOT_PASSWORD=root 指定mysql的root账号密码为root
    -e CLUSTER_NAME=PXC 执行名称为PXC
    -e XTRABACKUP_PASSWORD=root 指定mysql数据同步时用的密码为root
    --privileged 给最高的权限
    --name=node1 节点名称node1
    --net=net1 使用的内部网段
    --ip 172.18.0.2 分发的ip地址
    pxc 镜像名称pxc

[root@localhost ~]# docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=root  -v v1:/var/lib/mysql  --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
96e7588f1e9f2f657217f7ede6c53b1c5e7c044b57b5ef3787df2e7c5e69b974
[root@localhost ~]# docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=root  -v v2:/var/lib/mysql -e CLUSTER_JOIN=node1  --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc
206452fddb60a03f44bd175c075b527781fbe7cc2d3eb805969ef1b48894fa76
[root@localhost ~]# docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=root  -v v3:/var/lib/mysql -e CLUSTER_JOIN=node1  --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc
0fc05938f19fd16c69999ce79e67983609308417a500407ae693900667f668dc
[root@localhost ~]# docker run -d -p 3309:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=root  -v v4:/var/lib/mysql -e CLUSTER_JOIN=node1  --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc
74e8fb3022e5077669dc05d519aa331e9c678b2943fdd61e331d93ab39548424
[root@localhost ~]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=root  -v v5:/var/lib/mysql -e CLUSTER_JOIN=node1  --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc
bc48ae76e854ef3ddd6ef0a6d412f00a6e3a826edecc8c56a572322e1b821b10

执行docker ps进行查看

[root@localhost ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                                   NAMES
14a0ba3c314e        pxc                 "/entrypoint.sh "   6 seconds ago        Up 5 seconds        4567-4568/tcp, 0.0.0.0:3309->3306/tcp   node4
bc48ae76e854        pxc                 "/entrypoint.sh "   About a minute ago   Up About a minute   4567-4568/tcp, 0.0.0.0:3310->3306/tcp   node5
0fc05938f19f        pxc                 "/entrypoint.sh "   2 minutes ago        Up 2 minutes        4567-4568/tcp, 0.0.0.0:3308->3306/tcp   node3
206452fddb60        pxc                 "/entrypoint.sh "   4 minutes ago        Up 4 minutes        4567-4568/tcp, 0.0.0.0:3307->3306/tcp   node2
96e7588f1e9f        pxc                 "/entrypoint.sh "   13 minutes ago       Up 12 minutes       0.0.0.0:3306->3306/tcp, 4567-4568/tcp   node1

通过navcat进行连接,连接的ip即为宿主机的ip


image.png

数据负载均衡机制

image.png

负载均衡中间件对比


image.png

安装Haproxy

  1. 拉取镜像
docker pull haproxy
  1. 创建配置文件
[root@localhost ~]# mkdir /home/soft -p
[root@localhost ~]# touch /home/soft/haproxy.cfg

配置文件具体内容可参考戳我

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  5000
    #服务器超时(毫秒)
    timeout server  5000
    
#监控界面
listen  admin_stats
    #监控界面访问ip和端口
    bind    0.0.0.0:8888
    #访问协议
    mode        http
    #URI相对地址
    stats   uri     /dbs
    #统计报告格式
    stats   realm   Gloal\ statistics
    #登录账户信息 用于登录监控网站使用
    stats   auth    root:root
    
#数据库负载均衡
listen  proxy-mysql
    #访问的IP和端口
    bind    0.0.0.0:3306
    #网络协议
    mode    tcp
    #负载均衡算法(轮询算法)
    #轮询算法:roundrobin
    #权重算法:static-rr
    #最少连接算法:leastconn
    #请求源IP算法:source
    balance roundrobin
    
    #日志格式
    option  tcplog
    #在MySQL中创建一个没有权限的haproxy用户,密码为空。
    option mysql-check user haproxy
    server MySQL_1 172.18.0.2:3306 check weight 1 maxconn 2000
    server MySQL_2 172.18.0.3:3306 check weight 1 maxconn 2000
    server MySQL_3 172.18.0.4:3306 check weight 1 maxconn 2000
    server MySQL_4 172.18.0.5:3306 check weight 1 maxconn 2000
    server MySQL_5 172.18.0.6:3306 check weight 1 maxconn 2000
    #使用keepalive检测死链
    option tcpka
image.png
  1. 创建Haproxy容器
[root@localhost ~]# docker run -it -d -p 4001:8888 -p 4002:3306 -v /home/haproxy:/usr/local/etc/haproxy --name haproxy --privileged --net=net1 haproxy
  1. 进入haproxy后台docker exec,加载配置文件
[root@localhost haproxy]# docker exec -it  h1 bash 
root@4e53fd48e900:/# haproxy -f /usr/local/etc/haproxy/haproxy.cfg
  1. 在node1节点上创建一个没有密码没有权限的用户用于做心跳检测
create user 'haproxy'@'%' IDENTIFIED BY '';
  1. 确认防火墙关闭或者端口4001是暴露的状态的前提下客户端访问ip:4001/dbs
    用户名和密码为在haproxy.cfg配置文件设置好的,查看配置文件即可。
    image.png
  2. 后台关闭任意一个数据库节点进行测试
[root@localhost ~]# docker stop node1
node1
image.png
  1. haproxy连接navcat客户端
    像连接mysql客户端一样,
    ip为宿主机ip,端口为刚刚启动的时候映射的4002,密码为数据库的密码。


    image.png

    haproxy本身并不会存储数据,他只会将发过来的请求进行转发。值得注意的是单节点的haproxy是不具备高可用性的,所以必须要有冗余的设计。具体如下:

haproxy高可用

  1. Keepalived双机热备


    image.png

    设置一个虚拟ip,两个keepalive同时进行抢占该虚拟ip,抢到的为主服务器,没有抢到的为从服务器,从服务器定期向主服务器发送心跳,如果检测到主服务器宕机,从服务便可以获得虚拟ip成为主服务器。

  2. 总体架构设计


    image.png

    前面已经介绍过keepalived双机热备,不在赘述,最外面的那个keepalived作为跳板机使用。

  3. 安装
  4. 在haproxy中安装keepalived
sudo apt-get update
sudo apt-get install keepalived
  1. 更改keepalived配置文件
    路径:/etc/keepalived/keepalived.conf
    内容:
vrrp_instance VI_1{
    state MASTER
    interface   eth0
    virtual_router_id   51
    priority    100
    advert_int  1
    authentication{
        auth_type   PASS
        auth_pass   123456
    }
    virtual_ipaddress{
        172.18.0.201
    }
}

[配置文件说明]

  • state MASTER 表明keepalived身份(MASTER为主服务器,BACKUP为从服务器),主服务器抢占虚拟IP,备用服务器不会抢占IP
  • interface eth0 网卡设备,用于保存虚拟IP地址,该网卡是docker的网卡,只有在宿主机可见。所以需要将该虚拟IP映射到其他可见的IP上
  • virtual_router_id 51 虚拟路由标识,MASTER和BACKUP的虚拟路由标识必须保持一致,标识可以是0~255
  • priority 100 权重,MASTER的权重要高于BACKUP数字越大优先级越高。
  • advert_int 1 心跳检测的时间间隔,主备之间必须一致。单位(秒)
  • authentication{
    auth_type PASS
    auth_pass 123456
    }
    心跳检测使用的账号和密码
  • virtual_ipaddress{
    172.18.0.201
    }
    虚拟IP地址,可以设置多个虚拟IP地址,每行一个。
  1. 启动keepalived程序,在宿主机ping定义好的虚拟ip

推荐阅读更多精彩内容