在阿里云 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 地址对外提供服务。
最终要达到的目标为:
- Client 通过 VIP 访问服务能够将请求根据配置的规则进行分发( LB )
- 当 MATSER 的 LB 节点故障时,自动切换到 BACKUP 的 LB 节点上,保证服务正常访问; MASTER 恢复后,再次作为主 LB 负载节点
- 当某个 RS 节点故障时,自动剔除该节点;恢复后,再次加入集群
配置 Keepalived
- 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 } } ######################################################## ##### 开发端口 ################################ # 开发端口 1.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 - 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 ... 