前言 本文主要讲述LVS-DR原理介绍和配置实践,HA高可用方案基于Keepalived。
LVS-DR原理介绍和配置实践
更新历史 2020年04月20日 - 增加Keepalived双活实践 2019年09月03日 - 拆分LVS-Keepalived中LVS-DR 2019年08月23日 - 更新LVS/NAT、LVS/DR、LVS/TUN三种模式的原理和配置实践 2018年12月03日 - 精简和更新配置步骤 2018年07月31日 - 初稿
阅读原文 - https://wsgzao.github.io/post/lvs-nat/
扩展阅读
LVS - http://www.linuxvirtualserver.org/zh/index.html Keepalived - http://www.keepalived.org/
ReadMe 参考文章 Virtual Server via Direct Routing - http://www.linuxvirtualserver.org/VS-DRouting.html LVS和Keepalived官方中文手册PDF - https://pan.baidu.com/s/1s0P6nUt8WF6o_N3wdE3uKg
相关术语
以下术语涉及LVS三种工作模式的原理
LB (Load Balancer 负载均衡)
HA (High Available 高可用)
Failover (失败切换)
Cluster (集群)
LVS (Linux Virtual Server Linux 虚拟服务器)
DS (Director Server),指的是前端负载均衡器节点
RS (Real Server),后端真实的工作服务器
VIP (Virtual IP),虚拟的IP地址,向外部直接面向用户请求,作为用户请求的目标的 IP 地址
DIP (Director IP),主要用于和内部主机通讯的 IP 地址
RIP (Real Server IP),后端服务器的 IP 地址
CIP (Client IP),访问客户端的 IP 地址
LVS三种模式的主要区别
VS/NAT
VS/TUN
VS/DR
server
any
tunneling
non-arp device
server network
private
LAN/WAN
LAN
server number
low (10~20)
high
high
server gateway
load balancer
own router
own router
模式与特点
NAT 模式
IPIP 模式
DR 模式
对服务器的要求
服务节点可以使任何操作系统
必须支持 IP 隧道,目前只有 Linux 系统支持
服务器节点支持虚拟网卡设备,能够禁用设备的 ARP 响应
网络要求
拥有私有 IP 地址的局域网络
拥有合法 IP 地址的局域,网或广域网
拥有合法 IP 地址的局域,服务器节点与负载均衡器必须在同一个网段
通常支持节点数量
10 到 20 个,根据负载均衡器的处理能力而定
较高,可以支持 100 个服务节点
较高,可以支持 100 个服务节点
网关
负载均衡器为服务器节点网关
服务器的节点同自己的网关或者路由器连接,不经过负载均衡器
服务节点同自己的网关或者路由器连接,不经过负载均衡器
服务节点安全性
较好,采用内部 IP,服务节点隐蔽
较差,采用公用 IP 地址,节点安全暴露
较差,采用公用 IP 地址,节点安全暴露
IP 要求
仅需要一个合法的 IP 地址作为 VIP 地址
除了 VIPO 地址外,每个服务器界定啊需要拥有合法的 IP 地址,可以直接从路由到客户端
除了 VIP 外,每个服务节点需拥有合法的 IP 地址,可以直接从路由到客户端
特点
地址转换
封装 IP
修改 MAC 地址
配置复杂度
简单
复杂
复杂
LVS基本工作原理
当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间
PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链
IPVS是工作在INPUT链上的,当用户请求到达INPUT时,IPVS会将用户请求和自己已定义好的集群服务进行比对,如果用户请求的就是定义的集群服务,那么此时IPVS会强行修改数据包里的目标IP地址及端口,并将新的数据包发往POSTROUTING链
POSTROUTING链接收数据包后发现目标IP地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器
LVS的组成
LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。
ipvs(ip virtual server):一段代码工作在内核空间,叫ipvs,是真正生效实现调度的代码。
ipvsadm:另外一段是工作在用户空间,叫ipvsadm,负责为ipvs内核框架编写规则,定义谁是集群服务,而谁是后端真实的服务器(Real Server)
LVS和Keepalived 在lvs+keepalived环境里面,lvs主要的工作是提供调度算法,把客户端请求按照需求调度在real服务器,keepalived主要的工作是提供lvs控制器的一个冗余,并且对real服务器做健康检查,发现不健康的real服务器,就把它从lvs集群中剔除,real服务器只负责提供服务。
LVS/DR
重点将请求报文的目标MAC地址设定为挑选出的RS的MAC地址
(1) 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP (2) PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链 (3) IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址 (4) 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。 (5) RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP (6) 响应报文最终送达至客户端
LVS/DR模型的特性
特点1 :保证前端路由将目标地址为VIP报文统统发给Director Server,而不是RS
RS可以使用私有地址;也可以是公网地址,如果使用公网地址,此时可以通过互联网对RIP进行直接访问
RS跟Director Server必须在同一个物理网络中
所有的请求报文经由Director Server,但响应报文必须不能进过Director Server
不支持地址转换,也不支持端口映射
RS可以是大多数常见的操作系统
RS的网关绝不允许指向DIP(因为我们不允许他经过director)
RS上的lo接口配置VIP的IP地址
缺陷:RS和DS必须在同一机房中
特点1的解决方案:
在前端路由器做静态地址路由绑定,将对于VIP的地址仅路由到Director Server
存在问题:用户未必有路由操作权限,因为有可能是运营商提供的,所以这个方法未必实用
arptables:在arp的层次上实现在ARP解析时做防火墙规则,过滤RS响应ARP请求。这是由iptables提供的
修改RS上内核参数(arp_ignore和arp_announce)将RS上的VIP配置在lo接口的别名上,并限制其不能响应对VIP地址解析请求。
DR(Direct Routing 直接路由模式)此模式时LVS 调度器只接收客户发来的请求并将请求转发给后端服务器,后端服务器处理请求后直接把内容直接响应给客户,而不用再次经过LVS调度器。LVS只需要将网络帧的MAC地址修改为某一台后端服务器RS的MAC,该包就会被转发到相应的RS处理,注意此时的源IP和目标IP都没变。RS收到LVS转发来的包时,链路层发现MAC是自己的,到上面的网络层,发现IP也是自己的,于是这个包被合法地接受,RS感知不到前面有LVS的存在。而当RS返回响应时,只要直接向源IP(即用户的IP)返回即可,不再经过LVS。
注意: (1) 确保前端路由器将目标IP为VIP的请求报文发往Director: (a) 在前端网关做静态绑定; (b) 在RS上使用arptables; (c) 在RS上修改内核参数以限制arp通告及应答级别; arp_announce arp_ignore (2) RS的RIP可以使用私网地址,也可以是公网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director; (3) RS跟Director要在同一个物理网络; (4) 请求报文要经由Director,但响应不能经由Director,而是由RS直接发往Client; (5) 此模式不支持端口映射;
缺点:唯一的缺陷在于它要求LVS 调度器及所有应用服务器在同一个网段中,因此不能实现集群的跨网段应用。
优点:可见在处理过程中LVS Route只处理请求的直接路由转发,所有响应结果由各个应用服务器自行处理,并对用户进行回复,网络流量将集中在LVS调度器之上。
配置LVS-DR DS 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 apt-get install keepalived ipvsadm yum install keepalived ipvsadm vim /etc/sysconfig/iptables -A INPUT -p vrrp -j ACCEPT -A INPUT -p igmp -j ACCEPT -A INPUT -d 224.0.0.18 -j ACCEPT service iptables reload echo "1" > /proc/sys/net/ipv4/ip_forwardvi /etc/sysctl.conf net.ipv4.ip_forward = 1 sysctl -p vim /etc/keepalived/keepalived.conf vrrp_sync_group GOP { group { VI_PRI_CONNECT VI_PRI_AUTH } } vrrp_instance VI_PRI_CONNECT { state BACKUP interface bond0 virtual_router_id 128 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.65.32.28/23 dev bond0 } } virtual_server 10.65.32.28 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.13 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 80 } } real_server 10.65.32.14 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 80 } } } virtual_server 10.65.32.28 443 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.13 443 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 443 } } real_server 10.65.32.14 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 443 } } } vrrp_instance VI_PRI_AUTH { state BACKUP interface bond0 virtual_router_id 129 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.65.32.29/23 dev bond0 } } virtual_server 10.65.32.29 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.22 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 80 } } real_server 110.65.32.23 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 80 } } } virtual_server 10.65.32.29 443 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.65.32.22 443 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 443 } } real_server 110.65.32.23 443 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 connect_port 443 } } } systemctl start keepalived systemctl enable keepalived watch ipvsadm -L -n --stats
RS
Edit “/etc/sysconfig/network-scripts/ifcfg-lo” to patch bug in Centos 7 (if using Centos 7). Add TYPE=Loopback to the file.
Add loopback for each Virtual IP on each worker. E.g. first virtual IP create file “/etc/sysconfig/network-scripts/ifcfg-lo:0”.
Start adapters if not yet started
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 echo "TYPE=Loopback" >> /etc/sysconfig/network-scripts/ifcfg-locat > /etc/sysconfig/network-scripts/ifcfg-lo:0 << EOF DEVICE=lo:0 IPADDR=10.65.32.28 NETMASK=255.255.255.255 ONBOOT=yes EOF ifup lo:0 cat > /root/real_start.sh << EOF #!/bin/bash echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce EOF chmod 755 /root/real_start.shcat > /usr/lib/systemd/system/real.service << EOF [Unit] Description=autostart lvs real After=network.target remote-fs.target nss-lookup.target [Service] Type=forking ExecStart=/root/real_start.sh [Install] WantedBy=multi-user.target EOF systemctl enable real.service vim /root/lvs_real.sh VIP=10.65.32.28 case "$1 " in start) echo "Start REAL Server" /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce ;; stop) /sbin/ifconfig lo:0 down echo "Stop REAL Server" echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac exit 0
配置LVS/DR和LVS/TUN混合模式 DS 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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 [packet-forwarding-method] -g, --gatewaying Use gatewaying (direct routing). This is the default. -i, --ipip Use ipip encapsulation (tunneling). -m, --masquerading Use masquerading (network access translation, or NAT). Note: Regardless of the packet-forwarding mechanism specified, real servers for addresses for which there are interfaces on the local node will be use the local forwarding method, then packets for the servers will be passed to upper layer on the local node. This cannot be specified by ipvsadm, rather it set by the kernel as real servers are added or modified. /sbin/ifconfig tunl0 10.10.36.11 broadcast 10.10.36.11 netmask 255.255.255.255 up /sbin/route add -host 10.10.36.11 dev tunl0 /sbin/ipvsadm -At 10.10.36.11:80 -s rr /sbin/ipvsadm -at 10.10.36.11:80 -r 10.10.36.4:80 -g -w 1 /sbin/ipvsadm -at 10.10.36.11:80 -r 10.10.36.7:80 -i -w 1 vrrp_sync_group GOP { group { VI_PRI_AUTH } } vrrp_instance VI_PRI_AUTH { state BACKUP interface em1 virtual_router_id 11 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.10.36.11/23 dev em1 } } virtual_server 10.10.36.11 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 10.10.36.4 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } virtual_server 10.10.36.11 80 { delay_loop 6 lb_algo rr lb_kind TUN protocol TCP real_server 10.10.36.7 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } [root@d126027 wangao] rs2 rs1 rs2 rs1 rs2 [root@d126009 keepalived] IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes -> RemoteAddress:Port TCP 10.10.36.11:80 100 700 0 36700 0 -> 10.10.36.4:80 50 350 0 18350 0 -> 10.10.36.7:80 50 350 0 18350 0 [root@d126009 wangao] IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.10.36.11:80 rr -> 10.10.36.4:80 Route 100 0 0 -> 10.10.36.7:80 Tunnel 100 0 0
RS
DR和TUN的模式基本不用做改动
基于Keepalived的双活实践 Keepalived官方的文档并没有给出实践案例,我对上面的代码改进之后的效果如下
实现双活,支持不中断LVS人工干预任意节点运行位置
实现status状态无变化时无告警邮件
主要差异体现在keepalived.conf和相关的脚本,所有节点均为Backup,配置是一模一样的,不再解释细节了,如果不明白可以参考之前的Keepalived专题或者官方文档
keepalived.conf
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 vrrp_sync_group VI_GROUP_xxx { group { VI_PRI_xxx VI_PUB_xxx } notify /etc/keepalived/notify.sh } vrrp_sync_group VI_GROUP_xxx { group { VI_PRI_xxx VI_PUB_xxx } notify /etc/keepalived/notify.sh } vrrp_script maint-xxx { script "/bin/bash -c '[[ -e /etc/keepalived/xxx ]]' && exit 1 || exit 0" interval 2 fall 2 rise 2 } vrrp_script maint-xxx { script "/bin/bash -c '[[ -e /etc/keepalived/xxx ]]' && exit 1 || exit 0" interval 2 fall 2 rise 2 } vrrp_script maint-xxx { script "/bin/bash -c '[[ -e /etc/keepalived/xxx ]]' && exit 1 || exit 0" interval 2 fall 2 rise 2 } vrrp_script maint-xxx { script "/bin/bash -c '[[ -e /etc/keepalived/xxx ]]' && exit 1 || exit 0" interval 2 fall 2 rise 2 } vrrp_instance VI_PRI_xxx { state BACKUP interface bond0 virtual_router_id 138 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { xxx/23 dev bond0 } track_script { maint-xxx } } virtual_server xxx 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server xxx 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server xxx 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } vrrp_instance VI_PRI_xxx { state BACKUP interface bond0 virtual_router_id 139 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { xxx/23 dev bond0 } track_script { maint-xxx } } virtual_server xxx 443 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server xxx 443 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server xxx 443 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } vrrp_instance VI_PUB_xxx { state BACKUP interface bond1 virtual_router_id 101 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { xxx/26 dev bond1 } track_script { maint-xxx } } virtual_server xxx 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server xxx 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server xxx 80 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } } vrrp_instance VI_PUB_xxx { state BACKUP interface bond1 virtual_router_id 102 priority 100 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { xxx/26 dev bond1 } track_script { maint-xxx } } virtual_server xxx 443 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server xxx 443 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } real_server xxx 443 { weight 100 TCP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 } } }
notify.sh
Keepalived tasks some action depending on the VRRP state.
1 2 3 4 5 6 7 vrrp_sync_group VI_GROUP_xxx { group { VI_PRI_xxx VI_PUB_xxx } notify /etc/keepalived/notify.sh }
The script is called after any state change with the following parameters:
$1 = “GROUP” or “INSTANCE” $2 = name of group or instance $3 = target state of transition (“MASTER”, “BACKUP”, “FAULT”)
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 #!/bin/bash TYPE=$1 NAME=$2 STATE=$3 FILE="/etc/keepalived/${NAME} " if [ ! -f "${FILE} " ]; then touch "${FILE} " fi ORI_STATE=`cat ${FILE} ` if [ ${STATE} == ${ORI_STATE} ];then exit 0 else case $STATE in "MASTER" ) /bin/python /etc/keepalived/sendmail.py ${STATE} ${TYPE} ${NAME} echo "${STATE} " > "${FILE} " exit 0 ;; "BACKUP" ) /bin/python /etc/keepalived/sendmail.py ${STATE} ${TYPE} ${NAME} echo "${STATE} " > "${FILE} " exit 0 ;; "FAULT" ) /bin/python /etc/keepalived/sendmail.py ${STATE} ${TYPE} ${NAME} echo "${STATE} " > "${FILE} " exit 0 ;; *) echo "unknown state" exit 1 ;; esac fi
sendmail.py
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 import sysimport socketimport smtplibEMAIL_CONFIG = { 'EMAIL_HOST' : 'xxx' , 'EMAIL_HOST_USER' : 'xxx' , 'EMAIL_RECEIVER' : 'xxx' } def _get_private_ip (): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try : sock.connect(('10.255.255.255' , 1 )) return sock.getsockname()[0 ] except : return '127.0.0.1' finally : sock.close() def send_email (): ip = _get_private_ip() hostname = socket.gethostname() message = 'Subject: Keepalived Failover Alert %s \n\nHOSTNAME %s on LANIP %s %s %s status has changed to %s' % ( sys.argv[1 ], hostname, ip, sys.argv[2 ], sys.argv[3 ], sys.argv[1 ]) server = smtplib.SMTP(EMAIL_CONFIG["EMAIL_HOST" ]) server.sendmail(EMAIL_CONFIG['EMAIL_HOST_USER' ], EMAIL_CONFIG['EMAIL_RECEIVER' ], message) server.quit() send_email()
LVS和Keepalived系列 LVS和Keepalived的原理介绍和配置实践 LVS原理介绍和配置实践 Keepalived原理介绍和配置实践 LVS-NAT原理介绍和配置实践 LVS-DR原理介绍和配置实践 LVS-TUN原理介绍和配置实践