设为首页 收藏本站
查看: 1727|回复: 0

[经验分享] KVM部署LVS集群故障案例一则

[复制链接]

尚未签到

发表于 2017-6-24 07:51:14 | 显示全部楼层 |阅读模式
  
一、故障现象

  KVM部署LVS(Linux Virtual Server)集群后,能够单独以HTTP方式访问RS(Real Server)的实际IP,但无法通过VIP(Virtual IP)访问。
  二、故障分析过程
  
1.简化架构
  
  在原部署环境中,采用的架构是LVS的DR(Direct Return)模式,如下图所示:

  为了便于故障排查,我们简化为

  也就是在2台宿主机上,各保留一个虚拟机,角色分别是LVS的Director(调度器)和RS。
  该架构中的服务器(及虚拟机)的IP和MAC地址如下:
  角色
  IP
  MAC
  网络结构
  宿主机1
  x.y.z.70
  a0:d3:c1:f4:66:ac
  宿主机1的eth0和Director1的eth0(在宿主机1中对应为vnet0)桥接到br0
  Director1
  x.y.z.200
  02:00:73:b6:53:c8
  宿主机2
  x.y.z.73
  a0:d3:c1:f9:f3:fc
  宿主机2的eth0和RS2的eth0(在宿主机2中对应为vnet0)桥接到br0
  RS2
  x.y.z.226
  02:00:73:b6:53:e2
  VIP
  x.y.z.208
  02:00:73:b6:53:c8
  Client IP
  192.243.119.145

2.确认Director1是否能够正确识别到RS2提供的服务
  在Director1上,使用如下的命令检查
  [iyunv@Director1 ~]# ipvsadm -ln --sort
  IP Virtual Server version 1.2.1 (size=4096)
  Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
  TCP  x.y.z.208:80 rr
  ❶-> x.y.z.226:80           Route   2      0         0        
  由以上的输出❶可以看出,Director1能够正确识别到RS2提供的服务。

3.确认Director1是否能够正确重写MAC地址
  在Director1上执行以下的命令:
  [iyunv@Director1 ~]# tcpdump -vvv -nnn -e -i eth0 host 192.243.119.145
  ❶11:39:19.372804 84:78:ac:27:6c:41 > 02:00:73:b6:53:c8,ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 48, id 47264, offset 0, flags[DF], proto TCP (6), length 60)
  192.243.119.145.51643 > x.y.z.208.80:Flags [S], cksum 0x000e (correct), seq 3639534333,win 14600, options [mss 1460,sackOK,TS val 780753501ecr 0,nop,wscale 7], length 0
  ❷11:39:19.372815 02:00:73:b6:53:c8 > 02:00:73:b6:53:e2,ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 48, id 47264, offset 0, flags[DF], proto TCP (6), length 60)
  192.243.119.145.51643 > x.y.z.208.80:Flags [S], cksum 0x000e (correct), seq 3639534333,win 14600, options [mss 1460,sackOK,TS val 780753501ecr 0,nop,wscale 7], length 0
  ❸11:39:20.372079 84:78:ac:27:6c:41 > 02:00:73:b6:53:c8,ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 48, id 47265, offset 0, flags[DF], proto TCP (6), length 60)
  192.243.119.145.51643 > x.y.z.208.80:Flags [S], cksum 0xfc25 (correct), seq 3639534333,win 14600, options [mss 1460,sackOK,TS val 780754501ecr 0,nop,wscale 7], length 0
  ❹11:39:20.372091 02:00:73:b6:53:c8> 02:00:73:b6:53:e2, ethertype IPv4 (0x0800), length 74: (tos 0x0,ttl 48, id 47265, offset 0, flags [DF], proto TCP (6), length 60)
  192.243.119.145.51643 > x.y.z.208.80:Flags [S], cksum 0xfc25 (correct), seq 3639534333,win 14600, options [mss 1460,sackOK,TS val 780754501ecr 0,nop,wscale 7], length 0
  ---以下略去客户端第3、4、5次重传数据
  从❷所示的以太网帧中,我们能够看到❶所示的以太网帧目的MAC地址被Director1重写成了RS2的MAC地址,同时源MAC地址被Director1重写成了Director1本身的MAC地址。
  从❸和❹所示的以太网帧中,我们能够看到Client(192.243.119.145)在1s后(❸中的TSval 780754501比❶中的TSval 780753501大1000ms,TCPSequence相同)(注:TS val表示发送方的时间戳,单位是ms)进行了SYN包重传,说明Client和RS2没有正常建立TCP连接。此时,Director1仍然正确重写了MAC地址。
4.确认宿主机1是否能够正确转发虚拟机Director1重写后的帧
  在宿主机上执行以下命令:
  [iyunv@HOST1 ~]# tcpdump -vvv -nnn -e -i br0 host 192.243.119.145
  ❶11:39:19.430993 84:78:ac:27:6c:41 > 02:00:73:b6:53:c8,ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 48, id 47264, offset 0, flags[DF], proto TCP (6), length 60)
  192.243.119.145.51643 > x.y.z.208.80:Flags [S], cksum 0x000e (correct), seq 3639534333,win 14600, options [mss 1460,sackOK,TS val 780753501ecr 0,nop,wscale 7], length 0
  ❷11:39:20.430238 84:78:ac:27:6c:41 > 02:00:73:b6:53:c8,ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 48, id 47265, offset 0, flags[DF], proto TCP (6), length 60)
  192.243.119.145.51643 > x.y.z.208.80:Flags [S], cksum 0xfc25 (correct), seq 3639534333,win 14600, options [mss 1460,sackOK,TS val 780754501ecr 0,nop,wscale 7], length 0
  ---以下略去客户端第3、4、5次重传数据
  从❶和❷所示的以太网帧中,我们能够看到宿主机1未转发虚拟机Director1重写后的以太网帧(其中❷是❶的Client重传,我们没有观察到❶和❷的MAC地址被重写的情况)。
  很明显,问题出在宿主机1上,它没有转发Director1重写后的以太网帧。
  我们来看看为什么会发生这个问题。
5.检查宿主机1上虚拟机Director1的网络配置
  在宿主机1上执行以下命令:
  [iyunv@HOST1 ~]# virsh dumpxml r2-10105
  <interfacetype='bridge'>
  <mac address='02:00:73:b6:53:c8'/>
  <source bridge='br0'/>
  <target dev='vnet0'/>
  <modeltype='virtio'/>
  ❶<filterref filter='clean-traffic'>
  ❷<parameter name='IP' value='x.y.z.200'/>
  </filterref>
  <aliasname='net0'/>
  <address type='pci'domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
  </interface>
  从❶和❷中,我们看到Director1被引用了一个名为'clean-traffic'的过滤策略,同时给变量IP赋值为Director1的IP地址x.y.z.200。
  在宿主机1上执行以下命令:
  [iyunv@HOST1 ~]# virsh nwfilter-dumpxml clean-traffic
  <filter name='clean-traffic' chain='root'>
  <uuid>8c2059f9-d00f-4d1d-b96e-69e7d2b41c0f</uuid>
  <filterreffilter='no-mac-spoofing'/>
  ❸<filterreffilter='no-ip-spoofing'/>
  <rule action='accept'direction='out' priority='-650'>
  <macprotocolid='ipv4'/>
  </rule>
  <filterreffilter='allow-incoming-ipv4'/>
  <filterreffilter='no-arp-spoofing'/>
  <rule action='accept'direction='inout' priority='-500'>
  <macprotocolid='arp'/>
  </rule>
  <filterreffilter='no-other-l2-traffic'/>
  <filterreffilter='qemu-announce-self'/>
  </filter>
  [iyunv@HOST1 ~]# virsh nwfilter-dumpxml no-ip-spoofing
  <filter name='no-ip-spoofing' chain='ipv4-ip' priority='-710'>
  <uuid>bf7be725-1486-410f-8a8b-42c82b952261</uuid>
  <rule action='return'direction='out' priority='100'>
  <ip srcipaddr='0.0.0.0'protocol='udp'/>
  </rule>
  <rule action='return'direction='out' priority='500'>
  ❹<ipsrcipaddr='$IP'/>
  </rule>
  ❺<rule action='drop' direction='out' priority='1000'/>
  </filter>
  从❸、❹、❺中,我们看到在宿主机1中把Director1的发出的数据包的源地址限定为x.y.z.200,任何从Director1发出的数据包,如果源IP为其他,则被过滤掉(drop)。
  注意:
  在LVS的DR模式部署中,Director会重写来自客户端的以太网帧的源MAC地址和目的MAC地址,但会保留源IP地址和目的IP地址,因此Director发出的数据包得源IP地址并不是在这个虚拟机上配置的IP地址,也就是进行了IP的伪装(spoofing)。恰好被宿主机1上对它限制给过滤了。
  三、故障解决方法
  
  根据以上的分析,我们知道,为了能够在KVM集群中配置DR模式的LVS集群,我们必须禁用’no-ip-spoofing’的过滤策略。
  方法是:
  1)执行:
  virsh edit r2-10105
  2)删除以下内容:
  <filterref filter='clean-traffic'>
  <parameter name='IP'value='x.y.z.200'/>
  </filterref>
  3)重启虚拟机。
  4)我们采用以下的步骤抓包验证。
  [iyunv@HOST1 ~]#  tcpdump -i br0 -s 0 host 192.243.119.145 -vvv-nnn -s 0 -e
  tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size65535 bytes
  ❶16:39:37.842828 84:78:ac:27:6c:41 > 02:00:73:b6:53:c8,ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 48, id 59437, offset 0, flags[DF], proto TCP (6), length 60)
  192.243.119.145.48377 > x.y.z.208.80:Flags [S], cksum 0x8721 (correct), seq 2886813932, win 14600, options [mss1460,sackOK,TS val 885170369 ecr 0,nop,wscale 7], length 0
  ❷16:39:37.842990 02:00:73:b6:53:c8 > 02:00:73:b6:53:e2,ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 48, id 59437, offset 0, flags[DF], proto TCP (6), length 60)
  192.243.119.145.48377 > x.y.z.208.80:Flags [S], cksum 0x8721 (correct), seq 2886813932, win 14600, options [mss1460,sackOK,TS val 885170369 ecr 0,nop,wscale 7], length 0
  ---以下略去其他正常数据通信
  从❶和❷所示的以太网帧中,我们能够看到宿主机1转发了虚拟机Director1重写后的以太网帧。因此,这个问题得以完美解决。
  四、再探原理
  
  通过这个故障案例,我们对KVM的网络过滤策略有了更深的理解。那么,这些过滤策略到底是如何在系统里面生效的呢?
  通过在宿主机上配置iptables、ebtables,宿主机能够对虚拟机进行网络限制。其中,iptables实现对四层TCP、UDP端口的网络流量过滤;ebtables对二层MAC地址、三层IP地址进行过滤。如下是在宿主机1上对虚拟机进行MAC地址限定、源IP限定的规则:
  [iyunv@HOST1 ~]# ebtables -t nat --list
  Bridge table: nat
  Bridge chain: PREROUTING, entries: 1, policy: ACCEPT
  -i vnet0 -j libvirt-I-vnet0 #宿主机vnet0入流量走libvirt-I-vnet0策略
  Bridge chain: OUTPUT, entries: 0, policy: ACCEPT
  Bridge chain: POSTROUTING, entries: 1, policy: ACCEPT
  -o vnet0 -j libvirt-O-vnet0 #宿主机vnet0出流量走libvirt-O-vnet0策略
  Bridge chain: libvirt-I-vnet0, entries: 9, policy: ACCEPT
  -j I-vnet0-mac
  -p IPv4 -j I-vnet0-ipv4-ip
  -p IPv4 -j ACCEPT
  -p ARP -j I-vnet0-arp-mac
  -p ARP -j I-vnet0-arp-ip
  -p ARP -j ACCEPT
  -p 0x8035 -j I-vnet0-rarp
  -p 0x835 -j ACCEPT
  -j DROP
  Bridge chain: libvirt-O-vnet0, entries: 4, policy: ACCEPT
  -p IPv4 -j O-vnet0-ipv4
  -p ARP -j ACCEPT
  -p 0x8035 -j O-vnet0-rarp
  -j DROP
  Bridge chain: I-vnet0-mac, entries: 1, policy: ACCEPT
  -s 2:0:73:b6:53:c8 -j RETURN #限定源MAC地址
  -j DROP
  Bridge chain: I-vnet0-ipv4-ip, entries: 3, policy: ACCEPT
  -p IPv4 --ip-src 0.0.0.0 --ip-proto udp -j RETURN
  -p IPv4 --ip-src x.y.z.200 -j RETURN #限定源IP地址
  -j DROP
  Bridge chain: O-vnet0-ipv4, entries: 1, policy: ACCEPT
  -j ACCEPT
  五、总结
  
  在KVM环境中部署LVS集群时,要特别注意宿主机上iptables、ebtables对虚拟机的影响。因为此时,虚拟机并不是使用用户态的的应用程序进行代理,而是使用了网络地址转换(NAT模式)、MAC地址重写(DR模式)等“非常规”方法。
  通过这个案例,我们同时可以知道,在遇到未知可能涉及到网络方便的问题时,使用网络分析技术可以提供有效的信息来帮助我们定位和排除问题。
  阅读原文

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-387461-1-1.html 上篇帖子: KVM 基本硬件容量扩容 下篇帖子: 虚拟化之KVM的安装篇
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表