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

2023-12-22 21:07:46 +08:00
 leensunny

在阿里云 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 有特殊配置要求的地方?

非常感谢!

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

特别是数据库这种有状态场景,更不是 lvs 能力可以及的,老老实实使用官方的 rdb 解决方案吧。
leensunny
2023-12-23 09:09:44 +08:00
@ConnorTomato 无法采用 k8s ,感谢;
@onion83 采用 Havip ,程序改造量太大了,感谢!
Shadowxxx
2023-12-23 09:56:05 +08:00
为何不用 SLB ?
kuituosi
2023-12-23 10:10:24 +08:00
云上肯定没法用 lvs 啊,
lvs 的数据包是从 ds 到 rs 是数据链路层的,必须要在一个二层网络环境
ecs 网络是 sdn 是 vxlan 实现,本质是三层网络环境
在三层网络环境下 ds 根本不可能把数据投递到 rs
mulu
2023-12-23 10:51:42 +08:00
阿里云不支持 VIP
leensunny
2023-12-23 10:58:29 +08:00
@kuituosi 感谢提醒!
@mulu 谢谢!
defunct9
2023-12-23 14:25:54 +08:00
阿里云不支持 ipsec 直接打通国外的 vpc ,但是也是可以通的。不用非得购买它哪个企业网
dorothyREN
2023-12-23 15:46:39 +08:00
云厂商 都不支持 dr 模式, 因为数据包穿透不了 vpc
leensunny
2023-12-24 18:19:58 +08:00
@defunct9 @dorothyREN 多谢,已经搞定了;阿里云为了 SLB 有点过分了 😂。
defunct9
2023-12-24 18:30:31 +08:00
@leensunny 搞定了?如何搞定的?
leensunny
2023-12-25 14:55:29 +08:00
@defunct9 改了集群方案,用阿里云的 SLB 。
xusp
362 天前
其实可以用 lvs 的 dnat 模式。简单很多。
lfmwO
358 天前
阿里云支持 高可用虚拟 IP ,只能通过单播实现
具体在网络里面找找

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1002751

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX