hncys 发表于 2018-12-30 10:03:26

keepalived实现网关服务器双机热备问题

  网关服务器的主要作用有二:1、路由 2、nat。考虑到网关是公司的核心服务,决定使用keepalived实现网关的双机热备。
  使用keepalived实现只监控主机的存活非常简单,而且在本次需求中并不需要监控服务。然后看似双机做成了,但是问题来了。
  网关上跑的全是iptables脚本,而且主要是状态跟踪和snat,最突出的一个问题是,keepalived发出的vrrp广播的源地址有时被转换成了外网地址,而且这个还不决定什么时候转换成外网地址。
  配置文件如下:
  # cat /etc/keepalived/keepalived.conf
  ! Configuration File for keepalived
  global_defs {
  notification_email {
  xxxxxxxxxx@xxxx.cn
  }
  notification_email_from gw@xxx.cn
  smtp_server xxxxxxxx
  smtp_connect_timeout 30
  router_id gw_ha_175
  }
  #vrrp_sync_group VG1 {
  #group {
  #VI_1
  #   }
  #}
  vrrp_script check_run {
  script "/data/sbin/checkgw.sh"
  weight -5
  interval 5
  }
  vrrp_instance VI_1 {
  state BACKUP
  #nopreempt
  interface eth0
  virtual_router_id 150
  priority 150
  advert_int 1
  track_script {
  check_run
  }
  track_interface {
  eth0
  }
  authentication {
  auth_type PASS
  auth_pass 12345678
  }
  notify_master "/data/sbin/master.sh"
  notify_backup "/data/sbin/backup.sh"
  #notify_fault "/data/sbin/backup.sh"
  #smtp_alert
  mcast_src_ip eth0 192.168.8.175
  virtual_ipaddress {
  192.168.8.254/24 dev eth0
  192.168.9.254/24 dev eth0
  192.168.7.254/24 dev eth0
  192.168.6.254/24 dev eth0
  192.168.5.254/24 dev eth0
  192.168.4.254/24 dev eth0
  192.168.2.254/24 dev eth0
  192.168.1.254/24 dev eth0
  192.168.10.254/24 dev eth0
  192.168.100.254/24 dev eth0
  192.168.16.254/24 dev eth0
  192.168.33.254/24 dev eth0
  192.168.38.254/24 dev eth0
  192.168.39.254/24 dev eth0
  }
  }
  另外一台机器配置文件除了mcast_src_ip eth0 192.168.8.175和上面的不一样外,其余都一样。
  我使用tcpdump抓到的包应该是这样,
  # tcpdump vrrp
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
  09:34:28.681948 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
  09:34:29.682389 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
  但实际情况确是,
  # tcpdump vrrp
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
  09:34:28.681948 IP 1.1.1.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
  09:34:29.682389 IP 1.1.1.1 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
  在进行了各种研究,发现是状态跟踪导致的,
  # grep src=192.168.8.175 /proc/net/ip_conntrack
  unknown112 599 src=192.168.8.175 dst=224.0.0.18 packets=11662 bytes=1072904 src=1.1.1.1 dst=224.0.0.18 packets=0 bytes=0 mark=0 secmark=0 use=2
  iptables会对每一个连接进行连接跟踪,除非这个连接断开或者/proc/net/ip_conntrack表中的记录超时才回重新跟踪。而vrrp广播是不停的发,所以连接不会断开,表中记录也不会超时,一直会匹配这个错误的记录。(至于这条记录是如何产生的,应该刚开始运行的时候iptables的nat表中还没添加相应的vrrp规则)
  对于这种情况,尝试删除这个表中条目,失败!!!停止keepalived,等待表中条目超时,不可能!(停止后vip就会消失,就会断网)
  在研究后决定对vrrp广播包就行取消状态跟踪,在filter表中添加UNTRACKED状态,
  iptables -I FORWARD -m state --state ESTABLISHED,RELATED,UNTRACKED -j ACCEPT
  iptables -I INPUT -m state --state ESTABLISHED,RELATED,UNTRACKED -j ACCEPT
  在raw中,添加如下:
  iptables -t raw -A OUTPUT -s 192.168.8.175 -d 224.0.0.0/8 -j NOTRACK
  抓到的变为包如下:
  # tcpdump vrrp
  tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
  listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
  09:34:28.681948 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
  09:34:29.682389 IP 192.168.8.175 > 224.0.0.18: VRRPv2, Advertisement, vrid 150, prio 150, authtype simple, intvl 1s, length 72
  等待表中条目超时后,在nat中添加对应vrrp的规则即可!
  参考连接http://linuxnet527.blog.163.com/blog/static/172982867201151395821550/
  http://wangcong.org/articles/learning-iptables.cn.html



页: [1]
查看完整版本: keepalived实现网关服务器双机热备问题