• 基于docker+Keepalived+Haproxy高可用前后的分离技术


    基于docker+Keepalived+Haproxy高可用前后端分离技术

    架构图

    image-20231008112141771

    服务名docker-ip地址docker-keepalived-vip-ip
    haproxy-01docker-ip自动分配 未指定ip192.168.31.252
    haproxy-02docker-ip自动分配 未指定ip192.168.31.253

    安装haproxy

    宿主机ip 192.168.31.254
    宿主机keepalived虚拟网络未定义

    1. 下载docker镜像
      docker pull haproxy:2.1
      
      • 1

      image-20231008133511141

    2. 配置haproxy 配置文件 文件名haproxy.cfg
    global
    	#工作目录
    	chroot /usr/local/etc/haproxy
    	#日志文件,使用rsyslog服务中local5日志设备(/var/log/local5),等级info
    	log 127.0.0.1 local5 info
    	#守护进程运行
    	daemon
     
    defaults
            log 127.0.0.1 local0 err #[err warning info debug]
            mode http                #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
            retries 2                #两次连接失败就认为是服务器不可用,也可以通过后面设置
            option redispatch        #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
            option abortonclose      #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
            option dontlognull       #日志中不记录负载均衡的心跳检测记录
            maxconn 4096             #默认的最大连接数
            timeout connect 5000ms   #连接超时
            timeout client 30000ms   #客户端超时
            timeout server 30000ms   #服务器超时
            #timeout check 2000      #=心跳检测超时
     
    ######## 监控界面配置 #################	
    listen  admin_stats
    	#监控界面的访问的IP和端口
    	bind  0.0.0.0:8888
    	#访问协议
        mode        http
    	#URI相对地址
        stats uri   /dbs
    	#统计报告格式
        stats realm     Global\ statistics
    	#登陆帐户信息
        stats auth  admin:admin
    
    ########frontend配置##############
    #mycat负载均衡
    listen  proxy-mycat
    	#访问的IP和端口
    	bind  0.0.0.0:9000  
            #网络协议
    	mode  tcp
    	#负载均衡算法(轮询算法)
    	#轮询算法:roundrobin
    	#权重算法:static-rr
    	#最少连接算法:leastconn
    	#请求源IP算法:source 
            balance  roundrobin
    	# 这里是容器中的IP地址,由于配置的是轮询roundrobin,weight 权重其实没有生效
            server haproxy01 192.168.31.252:4001 check weight 1 maxconn 2000 
            server haproxy02 192.168.31.253:4002 check weight 1 maxconn 2000 
    	# 使用keepalive检测死链
            option tcpka
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    创建Haproxy容器

    haproxy01

    docker run -d -p 4001:8888 -p 9000:8066  \
    -v /haproxy/haproxy01:/usr/local/etc/haproxy  \
    --name haproxy01 --privileged  haproxy:2.1
    
    • 1
    • 2
    • 3

    haproxy02

    docker run -d -p 4002:8888 -p 9001:8066 \
    -v /haproxy/haproxy02:/usr/local/etc/haproxy \
    --name haproxy02 --privileged  haproxy:2.1
    
    • 1
    • 2
    • 3
    参数配置详解
    -p 4001:8888        将Haproxy提供的监控界面服务端口8888映射到宿主机的4001端口
    
    -p 4002:3306        将Haproxy提供的数据库负载均衡的服务端口3306映射到宿主机的4002端口
    
    -v /home/soft/haproxy:/usr/local/etc/haproxy       将宿主机的/home/soft/haproxy目录映射到容器的/usr/local/etc/haproxy目录。将来在宿主机的/home/soft/haproxy中放入配置文件,在相映射的容器目录中就可以使用了。
    
    --name h1            给容器起名,为了保证Haproxy的高可用,将来也会启动多个Haproxy容器实例
    
    --privileged          配置权限
    
    --net=net1           使用的网段,数据库实例使用的都是net1网段,需和数据库实例使用的网段保持一致
    
    --ip 172.18.0.7     手动分配的ip地址,如不设置,docker虚拟机也会给其分配一个ip地址 
    
    haproxy:2.1               docker run使用的镜像名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    image-20231008142452384

    在haproxy容器中启动haproxy实例

    由于容器是使用-d做后台运行的,因此之后还需要进入后台运行的容器,把haproxy中间件启动起来。

    进入后台运行的容器:

    docker exec -it haproxy01 /bin/bash
    
    • 1

    启用配置文件(启用完配置文件才算是真的启动了haproxy服务)
    (haproxy01 、haproxy02 都需要执行)

    haproxy -f /usr/local/etc/haproxy/haproxy.cfg
    
    • 1

    image-20231008143136453

    查看haproxy监控界面

    http://对应ip:4001/dbs
    用户名:admin
    密码:admin
    对应上面的配置

    image-20231008143421736

    keepalived搭建

    (haproxy01 、haproxy02 都需要执行)

    1、进入docker-haproxy服务
    docker exec -it haproxy01 /bin/bash
    
    • 1
    2、更新update,安装keepalived
    apt-get update
    apt-get install keepalived
    
    更换源这里就不操作了
    
    • 1
    • 2
    • 3
    • 4
    3、安装vim 安装ifconfig命令 安装ping
    apt-get install net-tools  vim   iputils-ping
    
    • 1
    4、新建并写入一个keepalived的配置文件(注意把注释删掉)
    vim /etc/keepalived/keepalived.conf
    
    vrrp_instance  VI_1 {
        #定义节点属性
        state  MASTER
    	  #定义虚拟网卡
        interface  eth0
    	  #定义组vriid
        virtual_router_id  100
    	  #定义权重
        priority  100
    	  #定义心跳检测时间1秒
        advert_int  1
    	  #定义组用户密码
        authentication {
            auth_type  PASS
            auth_pass  123456
        }
    	  #定义docker内ip地址,必须要在和haproxy同一个网段
        virtual_ipaddress {
            172.17.0.66
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    keepalived配置文件详细说明
    vrrp_instance  VI_1 {
        state  MASTER   #Keepalive的身份(MASTER为主服务,BACKUP为备用服务,抢占到ip的为主服务器,没有抢占到的自动降级为备用服务器)
        interface  eth0  #docker中虚拟ip使用到的docker内部网卡
        virtual_router_id  51  #虚拟路由标识,MASTER和BACKUP的虚拟路由标识必须一致。 标识可以是0~255之间任意值。
        priority  100   #硬件设备条件不同时采用的权重,MASTER权重要高于BACKUP,数字越大优先级越高。
        advert_int  1  #keepalived节点之间的心跳检测间隔,单位为秒,主备之间必须一致。
        authentication {   
            auth_type  PASS
            auth_pass  123456
        }  #心跳检测需要登录到keepalived节点内,登录使用的账号密码。主备必须用相同的密码才能正常通信。
        virtual_ipaddress {
            172.18.0.201
        }  #虚拟ip,该虚拟ip将被写入到上面的docker网卡ens33中,如数据库集群的网段是172.18.0.xxx,这里就定义个大一点的该网段的ip地址。由于是docker内部的虚拟ip,在docker内部能访问,出了docker是不能访问的。
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    image-20231008150323665
    启动keepalived
    service keepalived start
    执行 /bin/systemctl start keepalived.service 即可
    
    • 1
    • 2

    image-20231008150247369

    尝试宿主机能否ping通keepalived占有的虚拟ip,能ping通就说明这个虚拟ip已经配置成功了:

    image-20231008150639375

    如若ping不通需检查配置是否正确,以及网络模式是否是桥接。

    一开始我使用的网络模式是nat,无法ping通,改为桥接后重启linux可以ping通

    三、在宿主机内安装Keepalived

    Haproxy容器内的keepalive已经正常运行了,其抢占的虚拟ip也可以正常ping通了。

    之后需要把该虚拟ip和宿主机的ip做映射,以使外部网络可以访问到该虚拟ip,需要在宿主机上也安装keepalived。

    宿主机的linux是centos,所以安装命令有所不同:

    yum install -y keepalived  
    apt-get   install -y keepalived
    
    • 1
    • 2

    编写Keepalived配置文件

    位置/etc/keepalived文件夹
    宿主机配置信息

    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,一定要和宿主机网卡在同一个网段,我的宿主机网卡ip是192.168.1.85,所以指定虚拟ip是给的90
           	192.168.136.140
        }
    }
    
    #接受监听数据来源的端口,网页入口使用
    virtual_server 192.168.136.140 8888 {
        delay_loop 3
        lb_algo rr 
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        #把接受到的数据转发给docker服务的网段及端口,由于是发给docker服务,所以和docker服务数据要一致
        real_server 172.18.0.15 8888 {
            weight 1
        }
    }
     
        #接受数据库数据端口,宿主机数据库端口是3306,所以这里也要和宿主机数据接受端口一致
    virtual_server 192.168.136.140 8066 {
        delay_loop 3
        lb_algo rr 
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        #同理转发数据库给服务的端口和ip要求和docker服务中的数据一致
        real_server 172.18.0.15 8066 {
            weight 1
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    image-20231008154345698

    配置文件详解
    注意:
    
    1. 如上配置中的virtual_server 192.168.31.252,这是我当前的宿主机的网段ip地址,需将配置中所有192.168.132.252改成自己使用的宿主机网段
    
    2. ipaddress查看自己连接宿主机的ip地址,查看ip地址对应的网卡名。把interface eth1一项修改成自己正确的宿主机网卡名。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    3、启动keepalived
    service keepalived start
    
    
    执行 /bin/systemctl start keepalived.service 即可  如果报错
    
    • 1
    • 2
    • 3
    • 4

    启动成功后,尝试ping宿主机供请求访问的ip ping 192.168.31.99

    image-20231008154658429

    image-20231008154626406

    测试Haproxy监控服务

    通过宿主机keepalived绑定的ip访问haproxy监控服务

    image-20231008154800808

    注意,这次访问haproxy监控服务的ip192.168.31.99是宿主机keepalived所占有的虚拟ip,

    keepalived通过这个虚拟ip192.168.31.99 转发请求到docker的虚拟ip 172.17.0.66。

    haproxy01容器中的keepalived所在主服务器haproxy最后进行负载均衡请求分发。

    这次访问的已经不是原本的未使用keepalived时的宿主机192.168.132.252的ip了
    以上都是为了实现高可用功能,没有配置前后端分离。

    至此完成高可用

    Haproxy配置动静分离页面

    修改主配置文件如下
    global
            chroot /usr/local/etc/haproxy
            log 127.0.0.1   local0 info                     ##定义日志级别;
            log 127.0.0.1   local1 notice
            maxconn 4096            ##设定每个haproxy进程所接受的最大并发连接数
            uid 99                  ##指定运行服务的用户和组
            gid 99
            daemon                  ##指定运行模式为daemon,以守护进程的方式工作在后台
    defaults
            log     global                          ##采取global中的日志配置
            mode    http                            ##默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
            option  httplog                         ##采用http日志格式记录日志
            option  dontlognull                     ##不记录健康检查的日志记录
            option httpclose                        ##关闭保持连接
            retries 3                               ##检查节点最多失败次数
            maxconn 2000                            ##最大连接数,定义不得大于global中的值
            contimeout      5000    ##连接超时时间,毫秒,在此期间,如若客户端与服务端无法成功建立连接,则断掉
            clitimeout      50000   ##设置连接客户端发送数据时的成功连接最长等待时间,单位为毫秒,如若在这期间无法请求成功,则断掉
            srvtimeout      50000   ##设置服务器端回应客户端数据发送的最长等待时间,如果在这期间还无法发送成功,则断掉
    
    ##################无分离页面需求的配置##############
    #listen webcluster 0.0.0.0:80                   ##指定haproxy服务监听地址和端口
    #       option  httpchk GET /index.html         ##指定http请求方法和默认文件
    #       balance roundrobin                      ##指定轮询调度算法
    #       server  inst1 192.168.100.155:80 check inter 2000 fall 3                ##定义web节点,检测心跳频率,单位为毫秒,定义检查节点最多失败次数
    #       server  inst2 192.168.100.156:80 check inter 2000 fall 3
    
    ##################有分离页面需求的配置##############
    frontend http                           ##定义名称为http
            bind *:80                       ##指定监听地址和端口
            acl linuxfan1 hdr_end(host) -i 192.168.31.253                ##指定类型为访问路径的域名,-i不区分大小写
            acl linuxfan2 hdr_end(host) -i www.ceshi.con
    
            acl linuxfan3 path_end -i .jsp .do .css .js                     ##指定请求文件格式为.jsp
            #acl linuxfan3 hdr_reg -i \.(css|png|jpg|jpeg|gif|ico|swf|xml|txt|pdf|do|jsp|js)$       ##调用正则表达式
            acl linuxfan4 path_end -i .html .css .png .jpg .jpeg .xml       ##指定请求文件格式为.html
    
            acl linuxfan5 path_beg -i /WebRoot                              ##指定访问URL中的路径,如http://www.linuxfan.cn/WebRoot/index.jsp
    
            use_backend dongtai if linuxfan1 linuxfan3
            use_backend dongtai if linuxfan2 linuxfan3
            use_backend dongtai if linuxfan1 linuxfan5 linuxfan3
            use_backend dongtai if linuxfan2 linuxfan5 linuxfan3
    
            default_backend jingtai                                 ##默认的请求使用backend dongtai
    
    backend jingtai         ##定义backend :jingtai
            mode http                       ##定义模式
            balance roundrobin              ##定义调度算法为轮询
            server jingtai01 192.168.31.253:80 check inter 2000 fall 3             ##定义节点
    
    
    backend dongtai
            mode http
            balance roundrobin
            server dongtai01 192.168.31.254:8080 check inter 2000 fall 3
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    部署nginx

    创建目录

    mkdir -p /usr/local/docker/nginx
    vim docker-compose.yml
    
    • 1
    • 2
    version: "3.0"
    services:
      nginx:
        image: nginx:1.21.6
        restart: always
        #network_mode: "host"
        ports:
          - 80:80
          - 443:443
        volumes:
          - "./nginx/html:/usr/share/nginx/html"
          - "./nginx/conf.d:/etc/nginx/conf.d"
          - "./nginx/ssl:/etc/nginx/ssl"
          - "./nginx/logs:/var/log/nginx"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    启动
    image-20231008171725061

    部署tomcat

    创建目录,为了放置 Tomcat 的配置文件等

    mkdir  bin  conf  docker-compose.yml  logs  webapps
    
    • 1

    先随便启动一个 tomcat 容器(用第一种方法,docker run),主要是为了获取 tomcat 容器内部的配置文件

    #启动一个容器
     docker run -d --name tomcat tomcat
    
    # 查看 容器 获取容器ID
     docker ps -a
    
    • 1
    • 2
    • 3
    • 4
    • 5

    其中将,容器内 tomcat 文件夹下的 conf bin logs webapps 里面的内容都拷贝到上面宿主机上创建的对应文件夹内。容器的文件拷贝到宿主机的命令如下:

    # 注意!是在宿主机上执行这条命令。
    docker cp 容器名:/usr/local/tomcat/webapps/* /usr/local/tomcat/webapps
    其它文件夹内的内容也要这样拷贝到宿主机对应的文件夹内。
    
    • 1
    • 2
    • 3

    创建这个文件,docker-compose.yml

    version: '3'
    services:
      tomcat:
        user: root
        restart: always
        container_name: tomcat
        image: tomcat
        privileged: true
        environment:
          - TZ="Asia/Shanghai"
        ports:
          - 1002:8080
        volumes:
          - /usr/local/tomcat/webapps/:/usr/local/tomcat/webapps/
          - /usr/local/tomcat/conf:/usr/local/tomcat/conf
          - /usr/local/tomcat/logs:/usr/local/tomcat/logs
          - /usr/local/tomcat/bin:/usr/local/tomcat/bin
          - /etc/localtime:/etc/localtime
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

  • 相关阅读:
    PC电脑 VMware安装的linux CentOs7如何扩容磁盘?
    vite+vue3使用UEditorPlus ,后端PHP
    猿创征文 |『牛客|每日一题』循环链表
    【办公类-04-03】华为助手导出照片视频分类(根据图片、视频的文件名日期分类导出)
    axios从入门到源码分析之axios的理解和使用(一)
    SpringBoot整合JWT实现登陆验证
    【Linux守护进程】二、守护进程详解
    奇瑞新能源旗下新车——无界Pro上市,雷霆机甲炫酷登场
    Android 11.0 展讯平台关于ota升级开机logo的相关功能实现
    acwing算法提高之图论--最小生成树的典型应用
  • 原文地址:https://blog.csdn.net/tianmingqing0806/article/details/133707899