V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Recommended Services
Amazon Web Services
LeanCloud
New Relic
ClearDB
leensunny
V2EX  ›  云计算

阿里云问题请教:使用 LVS 与 Keepalived 实现集群的均衡和高可用

  •  
  •   leensunny · 314 天前 · 1557 次点击
    这是一个创建于 314 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在阿里云 ECS 服务器环境下,使用 LVS 与 Keepalived 实现集群的均衡和高可用。

    当前问题:DS 未向 RS 转发,标记路由未起作用,RS 直接向客户端发送响应。

    生产环境

    软件环境:CentOS7.9 、Keepalived1.3.5 、ipvsadm1.27

    DS1(MASTER):10.7.8.176

    DS1(BACKUP):10.7.8.177

    RS1:10.7.8.178

    RS1:10.7.8.179

    VIP:10.7.8.175

                                  |
                 +----------------+-----------------+
                 |                                  |
       10.7.8.176|----     VIP:10.7.8.175       ----|10.7.8.177
         +-------+--------+                +--------+-------+
         | 	    DS1       |                |       DS2      |
         | LVS+Keepalived |                | LVS+Keepalived |
         +-------+--------+                +--------+-------+
                 |			                |
                 +----------------+-----------------+
                                  |
      +------------+              |               +------------+
      |     RS1    |10.7.8.178    |     10.7.8.179|     RS2    |
      | App Server +--------------+---------------+ App Server |
      +------------+                              +------------+
    

    集群的架构图如上图所示。DS1 、DS2 为两个 LB 节点,RS1 、RS2 为两个真实的服务节点,通过一个虚拟的 IP 地址对外提供服务。

    最终要达到的目标为:

    1. Client 通过 VIP 访问服务能够将请求根据配置的规则进行分发( LB )
    2. 当 MATSER 的 LB 节点故障时,自动切换到 BACKUP 的 LB 节点上,保证服务正常访问; MASTER 恢复后,再次作为主 LB 负载节点
    3. 当某个 RS 节点故障时,自动剔除该节点;恢复后,再次加入集群

    配置 Keepalived

    1. DS1(MASTER) 节点
    [root@localhost ~]# vi /etc/keepalived/keepalived.conf
    
    !Configuration File for keepalived
    global_defs {
      # 路由 id ,主备节点不能相同
      router_id ipvs-master
      # 指定状态脚本运行用户
      script_user root
    }
    vrrp_instance ipvs {
        # Keepalived 的角色,MASTER 表示主节点,BACKUP 表示备份节点
        state MASTER
        # 指定监测的网卡,可以使用 ifconfig 或 ip a 进行查看
        interface eth0
        # 虚拟路由的 id ,主备节点需要设置为相同
        virtual_router_id 51
        # 优先级,主节点的优先级需要设置比备份节点高
        priority 200
        # 设置主备之间的检查时间,单位为秒
        advert_int 5
        # 定义验证类型和密码
        authentication {
            auth_type PASS
            auth_pass acadmin
        }
        # 单播源地址(本机地址)
        unicast_src_ip 10.7.8.176
        # 单播目标地址(互备节点地址)
        unicast_peer {
          10.7.8.177
        }
        # 虚拟 IP 地址,可以设置多个
        virtual_ipaddress {
            10.7.8.175
        }
        # keepalived 状态改变时执行用户自定义脚本 : 必须放置到 /usr/libexec/keepalived/ 目录下
        notify_master "/usr/libexec/keepalived/keepalived-notify.sh master"
        notify_backup "/usr/libexec/keepalived/keepalived-notify.sh backup"
        notify_stop "/usr/libexec/keepalived/keepalived-notify.sh stop"
        notify_fault "/usr/libexec/keepalived/keepalived-notify.sh fault"
    }
    ##### 侦听端口 ################################
    
    # 侦听端口 10.7.8.175:3200 -> ams:3200,3201
    # EAS 服务器连接参数 : 10.7.8.138:00:3200,10.7.8.137:00:3201
    virtual_server 10.7.8.175 3200 {
        lb_algo rr
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        real_server 10.7.8.178 3200 {
            weight 1
        }
        real_server 10.7.8.179 3200 {
            weight 1
        }
        real_server 10.7.8.178 3201 {
            weight 1
        }
        real_server 10.7.8.179 3201 {
            weight 1
        }
    }
    ########################################################
    
    
    ##### 开发端口 ################################
    
    # 开发端口 10.7.8.175:3300 -> ams:3300,3301
    # 将 '32' 替换为 '33' : 不存在 '3232' 端口时, 可通过替换取得开发端口
    # EAS 服务器连接参数 : 10.7.8.138:00:3200,10.7.8.137:00:3201
    virtual_server 10.7.8.175 3300 {
        lb_algo rr
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        real_server 10.7.8.178 3300 {
            weight 1
        }
        real_server 10.7.8.179 3300 {
            weight 1
        }
        real_server 10.7.8.178 3301 {
            weight 1
        }
        real_server 10.7.8.179 3301 {
            weight 1
        }
    }
    ########################################################
    
    
    ##### 消息服务器端口 ################################
    
    # 消息服务器端口
    virtual_server 10.7.8.175 3601 {
        lb_algo rr
        lb_kind NAT
        persistence_timeout 50
        protocol TCP
        real_server 10.7.8.178 3601 {
            weight 1
        }
        real_server 10.7.8.179 3601 {
            weight 1
        }
    }
    
    
    sudo ipvsadm -ln
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
      -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    TCP  10.7.8.175:3200 rr persistent 50
      -> 10.7.8.178:3200              Masq    1      0          0         
      -> 10.7.8.178:3201              Masq    1      0          0         
      -> 10.7.8.179:3200              Masq    1      0          0         
      -> 10.7.8.179:3201              Masq    1      0          0         
    TCP  10.7.8.175:3300 rr persistent 50
      -> 10.7.8.178:3300              Masq    1      0          0         
      -> 10.7.8.178:3301              Masq    1      0          0         
      -> 10.7.8.179:3300              Masq    1      0          0         
      -> 10.7.8.179:3301              Masq    1      0          0         
    TCP  10.7.8.175:3601 rr persistent 50
      -> 10.7.8.178:3601              Masq    1      0          0         
      -> 10.7.8.179:3601              Masq    1      0          0 
    
    1. DS2(BACKUP) 节点 略
    [root@localhost ~]# systemctl restart keepalived
    

    配置 RS

    RS 配置标记路由

    自定义路由表

    sudo ip route ls table ipstable
    default via 10.7.8.175 dev eth0 
    10.7.8.137 via 10.7.8.253 dev eth0 
    10.7.8.138 via 10.7.8.253 dev eth0 
    10.7.8.142 via 10.7.8.253 dev eth0 
    
    ip rule ls 
    0:	from all lookup local 
    32765:	from all fwmark 0x1 lookup ipstable 
    32766:	from all lookup main 
    32767:	from all lookup default
    

    标记路由

    sudo iptables-save
    # Generated by iptables-save v1.4.21 on Thu Dec 21 20:32:29 2023
    *nat
    :PREROUTING ACCEPT [66:7058]
    :INPUT ACCEPT [59:4088]
    :OUTPUT ACCEPT [1267:87936]
    :POSTROUTING ACCEPT [1258:87396]
    -A PREROUTING -p tcp -m tcp --dport 3300 -j DNAT --to-destination 10.7.8.138:3300
    -A PREROUTING -p tcp -m tcp --dport 3301 -j DNAT --to-destination 10.7.8.137:3300
    -A PREROUTING -p tcp -m tcp --dport 3601 -j DNAT --to-destination 10.7.8.142:3601
    -A POSTROUTING -p tcp -m tcp --dport 3300 -j MASQUERADE
    -A POSTROUTING -p tcp -m tcp --dport 3301 -j MASQUERADE
    -A POSTROUTING -p tcp -m tcp --dport 3601 -j MASQUERADE
    COMMIT
    # Completed on Thu Dec 21 20:32:29 2023
    # Generated by iptables-save v1.4.21 on Thu Dec 21 20:32:29 2023
    *mangle
    :PREROUTING ACCEPT [478579:48246787]
    :INPUT ACCEPT [478573:48243867]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [482629:53327933]
    :POSTROUTING ACCEPT [482629:53327933]
    -A PREROUTING -p tcp -m tcp --sport 3200 -j MARK --set-xmark 0x1/0xffffffff
    -A PREROUTING -p tcp -m tcp --sport 3300 -j MARK --set-xmark 0x1/0xffffffff
    -A PREROUTING -p tcp -m tcp --sport 3201 -j MARK --set-xmark 0x1/0xffffffff
    -A PREROUTING -p tcp -m tcp --sport 3301 -j MARK --set-xmark 0x1/0xffffffff
    -A PREROUTING -p tcp -m tcp --sport 3601 -j MARK --set-xmark 0x1/0xffffffff
    -A OUTPUT -p tcp -m tcp --sport 3200 -j MARK --set-xmark 0x1/0xffffffff
    -A OUTPUT -p tcp -m tcp --sport 3300 -j MARK --set-xmark 0x1/0xffffffff
    -A OUTPUT -p tcp -m tcp --sport 3201 -j MARK --set-xmark 0x1/0xffffffff
    -A OUTPUT -p tcp -m tcp --sport 3301 -j MARK --set-xmark 0x1/0xffffffff
    -A OUTPUT -p tcp -m tcp --sport 3601 -j MARK --set-xmark 0x1/0xffffffff
    COMMIT
    ...
    

    各位大佬,有没有了解阿里云 ECS 网卡对自建 LVS 有特殊配置要求的地方?

    非常感谢!

    defunct9
        1
    defunct9  
       314 天前 via iPhone   ❤️ 1
    开 ssh ,让我上去看看
    leensunny
        2
    leensunny  
    OP
       314 天前
    @defunct9 ssh 老哥 😂
    hbhh479q
        3
    hbhh479q  
       314 天前
    阿里云好像不支持自己搞 lvs ,需要买它们的服务
    ConnorTomato
        4
    ConnorTomato  
       314 天前
    虽然回答不了问题,但楼主这个流量路径可以直接试下云上 k8s 那一套;
    购买 SLB 负载均衡(相当于 VIP )监听虚拟后端服务器组( k8s Service ),Service 下 endpoint 就是 pod 应用实例(对应楼主的 RS );由容器的健康检查去决定 是否从 Service 上摘掉,不再接收前台流量。这样就实现了服务的负载均衡和可用。
    如果增加后端服务的可用性即自动扩缩 pod 数量,集群安装虚拟节点组件,通过 HPA 采集 CPU 、Memory 、QPS 指标去控制后端实例数量,扩容时优先使用集群内 ECS 资源,不足时启用按量付费的 ECI 实例。
    salmon5
        5
    salmon5  
       314 天前
    建议云上老老实实用 ECS 、LB 、ACK 、RDS 等,别自己折腾这些意义不大的东西(最好懂,锦上添花即可)。
    这些都是 7-8 年前的知识。
    onion83
        6
    onion83  
       314 天前
    阿里云对标服务是 Havip ,不支持自建操作。文档: https://help.aliyun.com/zh/vpc/user-guide/use-highly-available-virtual-ip ,内测的时候就搞过,一般都是做网关的,很少用来做负载均衡。如果只是简单的负载均衡,阿里云的 slb 已经做得很细了,确实没必要自己折腾,成本不低不说,也缺乏有效的监控手段。

    特别是数据库这种有状态场景,更不是 lvs 能力可以及的,老老实实使用官方的 rdb 解决方案吧。
    leensunny
        7
    leensunny  
    OP
       313 天前
    @ConnorTomato 无法采用 k8s ,感谢;
    @onion83 采用 Havip ,程序改造量太大了,感谢!
    Shadowxxx
        8
    Shadowxxx  
       313 天前
    为何不用 SLB ?
    kuituosi
        9
    kuituosi  
       313 天前
    云上肯定没法用 lvs 啊,
    lvs 的数据包是从 ds 到 rs 是数据链路层的,必须要在一个二层网络环境
    ecs 网络是 sdn 是 vxlan 实现,本质是三层网络环境
    在三层网络环境下 ds 根本不可能把数据投递到 rs
    mulu
        10
    mulu  
       313 天前 via Android
    阿里云不支持 VIP
    leensunny
        11
    leensunny  
    OP
       313 天前
    @kuituosi 感谢提醒!
    @mulu 谢谢!
    defunct9
        12
    defunct9  
       313 天前
    阿里云不支持 ipsec 直接打通国外的 vpc ,但是也是可以通的。不用非得购买它哪个企业网
    dorothyREN
        13
    dorothyREN  
       313 天前
    云厂商 都不支持 dr 模式, 因为数据包穿透不了 vpc
    leensunny
        14
    leensunny  
    OP
       312 天前
    @defunct9 @dorothyREN 多谢,已经搞定了;阿里云为了 SLB 有点过分了 😂。
    defunct9
        15
    defunct9  
       312 天前
    @leensunny 搞定了?如何搞定的?
    leensunny
        16
    leensunny  
    OP
       311 天前
    @defunct9 改了集群方案,用阿里云的 SLB 。
    xusp
        17
    xusp  
       307 天前
    其实可以用 lvs 的 dnat 模式。简单很多。
    lfmwO
        18
    lfmwO  
       303 天前
    阿里云支持 高可用虚拟 IP ,只能通过单播实现
    具体在网络里面找找
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1239 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:11 · PVG 07:11 · LAX 16:11 · JFK 19:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.