Docker

Docker中使用keepalived+haproxy负载均衡方

2018-12-12  本文已影响125人  QIQIHAL

为什么要用keepalived+haproxy实现docker下的高可用负载均衡?在不同环境下有哪些方式可以实现高可用负载均衡?

首先第一点,实现负载均衡并不是只有haproxy一个中间件,网上还有很多方案是用keepalived+LVS等等,所以对于docker下的高可用负载均衡不一定只有keepalived+haproxy。只是本次我是基于之前搭建的pxc集群进行继续搭建的,所以用的是haproxy。

为什么这里强调的是docker、keepalived?

首先我们运行环境是docker,keepalived的作用是抢占虚拟ip,docker环境下,镜像内的网段外网是无法访问的,所以我们需要一个外网在宿主机上映射到docker内的ip上,keepalived一方面可以映射ip到docker服务内,二可以在docker服务内强占虚拟ip。所以在docker搭建负载均衡的多种方案中都常见会出现keepalived。

为什么要抢占虚拟ip?为什么要用keepalived呢?

负载均衡中间件(haproxy,lvs)等等在实际中不可能只是单节点存在(单节点不需要keepalived),都要有冗余设计,即集群设计,和数据库集群不一样的是,docker中实现负载均衡中间件的集群是通过抢占一个ip地址实现的,有主备和主主方式,虽然方式不一样,但都有一个心跳检测的共同点,在主节点抢占虚拟ip时,主从节点上会有心跳检测线,如果发现主节点心跳检测连不上,则从节点会主动抢占ip实现数据不中断的冗余机制;

总结描述:由于是在docker环境下,我们要搭建负载均衡集群需要通过keepalived抢占虚拟ip实现,而负载均衡功能需要haproxy中间件实现,所以本次我搭建的是一个在docker环境下高可用的负载均衡方案是:keepalived+haproxy。

1 使用docker下载rabbitmq镜像,目前版本号为3.7.8-management,如果需要其他版本请登录https://hub.docker.com/进行搜索,rabbitmq有带web管理页面版本,与不带web管理页面版本,区别是带web管理页面的rabbitmq版本号有"-management"后缀

[root@localhost ~]#  docker pull rabbitmq:3.7.8-management

2 下载完毕后分别创建/home/docker/rabbitmq、rabbitmq1、rabbitmq2、rabbitmq3这四个文件夹

[root@localhost ~]# cd /home

[root@localhost home]# cd /docker

[root@localhost docker]# mkdir rabbitmq

[root@localhost home]# cd rabbitmq

[root@localhost rabbitmq]# mkdir rabbitmq1 rabbitmq2 rabbitmq3

3 创建创建一个rabbitmq使用的网络,docker创建网络具体百度,比较复杂,这里不一一介绍,这里只保证rabbitmq集群能够成功被访问,不在深究

[root@localhost rabbitmq]# docker network create --subnet=172.100.100.0/16 rabbitmqnet

3.1 查看创建的网络

[root@localhost rabbitmq]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
9ccff013f2c0        bridge              bridge              local
73f358c702fd        host                host                local
bd3d802d6666        none                null                local
827e59f2a657        rabbitmqnet         bridge              local

4 使用docker下载haproxy镜像,目前版本号为3.7.8,如果需要其他版本请登录https://hub.docker.com/进行搜索

[root@localhost ~]#  docker pull haproxy

5 下载完毕后分别创建/home/docker/haproxy文件夹、haproxy.cfg配置文件

[root@localhost ~]# cd /home

[root@localhost home]# cd /docker

[root@localhost docker]# mkdir haproxy

[root@localhost docker]# cd /haproxy

[root@localhost docker]# mkdir haproxy

[root@localhost docker]# cd /haproxy

[root@localhost haproxy]# touch haproxy.cfg

6 vi编辑自定义haproxy.cfg配置文件,复制下列代码

#全局配置: 
#global: 全局配置段 
#代理配置: 
#default: 默认配置—–>所有在backend、frontend、linsten中相同内容可以在此定义; 
#frontend:前段配置—–>定义前端套接字,接受客户端请求; 
#backend: 后端配置—–>定义后端分配规则,与后端服务器交互; 
#listen: 绑定配置—–>直接将指定的客户端与后端特定服务器绑定到一起
global
       maxconn 10000                   #默认最大连接数
       log 127.0.0.1 local0 err        #日志文件,使用rsyslog服务中local0日志设备(/var/log/local0),等级info[err warning info debug]
       chroot /usr/local/sbin          #chroot运行的路径
       #user        haproxy            #所属用户
       #group       haproxy            #所属组
       daemon                          #以后台守护进程方式运行haproxy
       pidfile /var/run/haproxy.pid    #当前haproxy进程的pid存放路径,启动进程的用户必须有权限访问此文件
       #tune.ssl.default-dh-param 2048 #SSL密钥使用的是2048bit加密,不设置会有警告
defaults
       log 127.0.0.1 local1
       mode http                       #默认的模式mode { tcp|http|health },所处理的类别,tcp是4层,http是7层,health只会返回OK
       maxconn 10000                   #每个进程可用的最大连接数
       option dontlognull              #日志中不记录负载均衡的心跳检测记录
       option redispatch               #serverId对应的服务器挂掉后,强制定向到其他健康的服务器,当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了, 但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
      #stats refresh 30                #统计页面刷新间隔
       retries 3                       #3次连接失败就认为服务不可用,也可以通过后面设置
      #default_backend my_webserver    #定义一个名为my_app前端部分。此处将对应的请求转发给后端     
      #option http-server-close        #每次请求完毕后主动关闭http通道
      #option forwardfor except 127.0.0.0/8  #如果后端服务器需要获得客户端的真实ip,需要配置的参数,可以从http header 中获取客户端的IP 
       balance roundrobin              #默认的负载均衡的方式,轮询方式
      #balance source                  #默认的负载均衡的方式,类似nginx的ip_hash
      #balance leastconn               #默认的负载均衡的方式,最小连接
      #timeout http-request    10s     #http请求超时时间
      #timeout queue           1m      #一个请求在队列里的超时时间
       timeout connect 5000            #连接超时
       timeout client 50000            #客户端超时
       timeout server 50000            #服务器超时
       timeout http-keep-alive 10s     #设置http-keep-alive的超时时间
       timeout check 2000              #心跳检测超时
#frontend  main *:80                   #监听地址为80
      #server static 127.0.0.1:80 check #静态文件部署在本机(也可以部署在其他机器或者squid缓存服务器)
      #acl url_static path_beg -i /static /images /javascript /stylesheets
      #acl url_static path_end -i .jpg .gif .png .css .js
      #use_backend static if url_static
#backend static                        #使用了静态动态分离(如果url_path匹配 .jpg .gif .png .css .js静态文件则访问此后端)     
#backend my_webserver                  #定义一个名为my_webserver后端部分。PS:此处my_webserver只是一个自定义名字而已,但是需要与frontend里面配置项default_backend 值相一致
####################################################################
listen http_front
       bind 0.0.0.0:5669               #监听端口  
       stats refresh 30s               #统计页面自动刷新时间  
       stats uri /haproxy?stats        #统计页面url  
       stats realm Haproxy Manager     #统计页面密码框上提示文本  
       stats auth admin:admin          #统计页面用户名和密码设置  
       #stats hide-version             #隐藏统计页面上HAProxy的版本信息
#####################RabbitMQ的管理界###############################
listen rabbitmq_admin 
       bind 0.0.0.0:5671
       server rabbitmq3 172.100.100.4:15674
       server rabbitmq2 172.100.100.3:15673
       server rabbitmq1 172.100.100.2:15672
#####################RabbitMQ集群####################################
listen rabbitmq_cluster 
       bind 0.0.0.0:5670
       option tcplog
       mode tcp
       timeout client  3h
       timeout server  3h
       option          clitcpka
       balance roundrobin              #负载均衡算法(banlance roundrobin 轮询,balance source 保存session值,支持static-rr,leastconn,first,uri等参数)
       #balance url_param userid
       #balance url_param session_id check_post 64
       #balance hdr(User-Agent)
       #balance hdr(host)
       #balance hdr(Host) use_domain_only
       #balance rdp-cookie
       #balance leastconn
       #balance source //ip
       server   rabbitmq3 172.100.100.4:5674 check inter 5s rise 2 fall 3   #check inter 2000 是检测心跳频率,rise 2是2次正确认为服务器可用,fall 3是3次失败认为服务器不可用
       server   rabbitmq2 172.100.100.3:5673 check inter 5s rise 2 fall 3
       server   rabbitmq1 172.100.100.2:5672 check inter 5s rise 2 fall 3

7 启动haproxy容器

docker run -d --name rabbitmq-haproxy --ip=172.100.100.1 -p 5669-5671:5669-5671 --net=rabbitmqnet -v /home/docker/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg --restart=always haproxy:latest

8 启动三个rabbitmq容器

docker run -d --restart=always --name rabbitmq1 --ip=172.100.100.2 --net=rabbitmqnet  -p 5672:5672 -p 15672:15672 -v /home/docker/rabbitmq/rabbitmq1:/var/lib/rabbitmq --log-opt max-size=10m --log-opt max-file=3 -e RABBITMQ_NODENAME=rabbitmq1 -e RABBITMQ_ERLANG_COOKIE='RABBITMQ_ERLANG_COOKIE' -h rabbitmq1 rabbitmq:3.7.8-management

docker run -d --restart=always --name rabbitmq2 --ip=172.100.100.3 --net=rabbitmqnet  -p 5673:5672 -p 15673:15672 -v /home/docker/rabbitmq/rabbitmq2:/var/lib/rabbitmq --log-opt max-size=10m --log-opt max-file=3 -e RABBITMQ_NODENAME=rabbitmq2 -e RABBITMQ_ERLANG_COOKIE='RABBITMQ_ERLANG_COOKIE' -h rabbitmq2 rabbitmq:3.7.8-management

docker run -d --restart=always --name rabbitmq3 --ip=172.100.100.4 --net=rabbitmqnet  -p 5674:5672 -p 15674:15672 -v /home/docker/rabbitmq/rabbitmq3:/var/lib/rabbitmq --log-opt max-size=10m --log-opt max-file=3 -e RABBITMQ_NODENAME=rabbitmq3 -e RABBITMQ_ERLANG_COOKIE='RABBITMQ_ERLANG_COOKIE' -h rabbitmq3 rabbitmq:3.7.8-management

8 将第二个rabbitmq容器与第三个abbitmq容器加入到第一个abbitmq容易中

docker exec rabbitmq2 bash -c "rabbitmqctl stop_app && rabbitmqctl reset && rabbitmqctl join_cluster rabbitmq1@rabbitmq1 && rabbitmqctl start_app"

docker exec rabbitmq3 bash -c "rabbitmqctl stop_app && rabbitmqctl reset && rabbitmqctl join_cluster rabbitmq1@rabbitmq1 && rabbitmqctl start_app"

8.1 如果在执行加入集群命令时,不是以下结果

Stopping rabbit application on node rabbitmq2@rabbitmq2 ...
Resetting node rabbitmq2@rabbitmq2 ...
Clustering node rabbitmq2@rabbitmq2 with rabbitmq1@rabbitmq1
Starting node rabbitmq2@rabbitmq2 ...
 completed with 3 plugins.

8.2 例如是第二个rabbitmq没有成功加入集群,则执行

[root@localhost ~]# docker stop rabbitmq2
[root@localhost ~]# cd/home/docker/rabbitmq/rabbitmq2
[root@localhost ~]# ls -a
[root@localhost ~]# .  ..  config  .erlang.cookie  mnesia  schema
[root@localhost ~]# rm -rf *
[root@localhost ~]# rm .erlang.cookie
[root@localhost ~]# docker start rabbitmq2

打开浏览器输入地址:http://宿主机IP:5671

image.png
上一篇下一篇

猜你喜欢

热点阅读