解决OS虚拟机内采用LVS-DR模式请求超时问题

背景####

公司大促期间,由于扩容了大量云主机,采用LVS DR模式的Zabbix-Proxy端请求巨增,导致监控数据采集的队列长时间堆积,已经在前端界面无法展示。所以这个时候负责监控的同事从我这里申请了20多台虚拟机用于抗监控流量。

Zabbix-Proxy的集群框架是Keepalived + lvs,原本以为只需要给安装Keepavlived的两台虚拟机分配一个Vip就好了(让虚拟机支持高可用的vrrp协议),结果过了一阵监控的同事告诉我vip的端口访问超时,我便开始觉得自己想得太简单。

看下问题现场:

# nc -vz 10.1.26.252 10051
nc: connect to 10.1.26.252 port 10051 (tcp) failed: Connection timed out

客户端返回内容很简单,连接超时。

$ ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.1.26.252:zabbix-trapper sh
  -> 10.1.26.136:zabbix-trapper   Route   100    0          0
  -> 10.1.26.137:zabbix-trapper   Route   100    0          0
  -> 10.1.26.138:zabbix-trapper   Route   100    0          0
  -> 10.1.26.139:zabbix-trapper   Route   100    0          0
  -> 10.1.26.140:zabbix-trapper   Route   100    0          0
  -> 10.1.26.141:zabbix-trapper   Route   100    0          0
  -> 10.1.26.142:zabbix-trapper   Route   100    0          0
  -> 10.1.26.143:zabbix-trapper   Route   100    0          0

$ ipvsadm -lnc
IPVS connection entries
pro expire state       source             virtual            destination
TCP 01:57  SYN_RECV    10.0.19.92:37358   10.1.26.252:10051  10.1.26.139:10051
TCP 01:57  SYN_REVV    10.0.19.92:37359   10.1.26.252:10051  10.1.26.139:10051

LVS端看到问题很明显,客户端请求过来的连接状态全部卡在SYN_RECV,说明请求已经到达LVS,但是在丢给后端Real Server的时候处理异常。

那么问题点出在哪儿呢?

  • 虚拟机iptables

最开始怀疑是虚拟机上iptables规则影响DR模式的报文转发,因为DR模式下的LVS在接收到请求后,会将报头拆解,将dst mac改成后端RealServer的MAC地址,然后重新封装好报文通过广播vip地址丢到后端的RealServer处理。


LVS-DR模式原理

于是我清空所有虚拟机的iptales,并关闭selinux。但问题仍然存在,说明问题不在虚拟机上。

  • LVS配置

根据LVS DR模式的特性,后端的RealServer上的lo网卡需要绑定vip地址,否则当接受到转发过来dst ip为vip的报文时,默认也会丢弃,造成客户端访问超时的问题。

通过和监控的同事沟通,确定排除这块问题,我又想到会不会需要把vip同时也绑定到RealServer上。我再用allowed_address_pairs参数更新了后端虚拟机的Port。客户端请求依然超时,说明问题并不是这里。

  • Security Group

由于排除了虚拟机问题,我这边将解决问题的重点移至安全组策略。我们知道Neutron通过iptables规则来实现虚拟机进出流量的限制。

于是我将安全组策略全部打开,如下图:

安全组策略

客户端还是超时!!!这个时候我已经感觉无计可施。

转折

过了一会,我觉得应该做最后一搏,于是我将宿主机上iptables全部清空,客户端居然通了!

$ nc -vz 10.1.26.252 10051
Connection to 10.1.26.252 10051 port [tcp/*] succeeded!

排查

看来问题点在宿主机上的Iptables,找到这个方向后,我便开始根据VIP对iptables进行反向排查。

Chain neutron-openvswi-o38833ad6-c

$ iptables-save | grep 10.1.26.252
-A neutron-openvswi-s38833ad6-c -s 10.1.26.252/32 -m mac --mac-source FA:16:3E:C4:20:C7 -m comment --comment "Allow traffic from defined IP/MAC pairs." -j RETURN

$ iptables-save | grep neutron-openvswi-o38833ad6-c
-A neutron-openvswi-o38833ad6-c -j neutron-openvswi-s38833ad6-c
-A neutron-openvswi-s38833ad6-c -s 10.1.26.252/32 -m mac --mac-source neutron-openvswi-o38833ad6-c -m comment --comment "Allow traffic from defined IP/MAC pairs." -j RETURN
-A neutron-openvswi-s38833ad6-c -s 10.1.26.144/32 -m mac --mac-source FA:16:3E:C4:20:C7 -m comment --comment "Allow traffic from defined IP/MAC pairs." -j RETURN
-A neutron-openvswi-s38833ad6-c -m comment --comment "Drop traffic without an IP/MAC allow rule." -j DROP

上面这一条意思很明确,就是绑定虚拟机IP和MAC地址,只允许MAC地址为FA:16:3E:C4:20:C7,IP地址为10.1.26.25210.1.26.144通过,其余DROP掉。neutron-openvswi-s38833ad6-c这条Chain是从neutron-openvswi-o38833ad6-c跳转下来的。

Chain neutron-openvswi-o38833ad6-c

$ iptables-save | grep neutron-openvswi-o38833ad6-c
:neutron-openvswi-o38833ad6-c - [0:0]
-A neutron-openvswi-INPUT -m physdev --physdev-in tap38833ad6-c6 --physdev-is-bridged -m comment --comment "Direct incoming traffic from VM to the security group chain." -j neutron-openvswi-o38833ad6-c
-A neutron-openvswi-o38833ad6-c -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-openvswi-o38833ad6-c -j neutron-openvswi-s38833ad6-c
-A neutron-openvswi-o38833ad6-c -p udp -m udp --sport 68 --dport 67 -m comment --comment "Allow DHCP client traffic." -j RETURN
-A neutron-openvswi-o38833ad6-c -p udp -m udp --sport 67 -m udp --dport 68 -m comment --comment "Prevent DHCP Spoofing by VM." -j DROP
-A neutron-openvswi-o38833ad6-c -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-openvswi-o38833ad6-c -p icmp -j RETURN
-A neutron-openvswi-o38833ad6-c -p tcp -m tcp -m multiport --dports 1:65535 -j RETURN
-A neutron-openvswi-o38833ad6-c -j RETURN
-A neutron-openvswi-o38833ad6-c -p udp -m udp -m multiport --dports 1:65535 -j RETURN
-A neutron-openvswi-o38833ad6-c -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-openvswi-o38833ad6-c -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-openvswi-sg-fallback
-A neutron-openvswi-sg-chain -m physdev --physdev-in tap38833ad6-c6 --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-o38833ad6-c

neutron-openvswi-o38833ad6-c这条Chain是用于规则虚拟机出口流量,可以看到它是从两条Chian上跳转下来的neutron-openvswi-INPUTneutron-openvswi-sg-chain
neutron-openvswi-o38833ad6-c主要定义虚拟机engress的安全规则。这里可以看到之前创建的规则已经下发到ipables上应用成功。将没匹配的到规则丢给neutron-openvswi-sg-fallback,fallback里面就一条规则,丢弃进来的所有报文。

Chain neutron-openvswi-i38833ad6-c

$ iptables-save | grep neutron-openvswi-i38833ad6-c
:neutron-openvswi-i38833ad6-c - [0:0]
-A neutron-openvswi-i38833ad6-c -m state --state RELATED,ESTABLISHED -m comment --comment "Direct packets associated with a known session to the RETURN chain." -j RETURN
-A neutron-openvswi-i38833ad6-c -s 10.1.26.120/32 -p udp -m udp --sport 67 -m udp --dport 68 -j RETURN
-A neutron-openvswi-i38833ad6-c -p icmp -j RETURN
-A neutron-openvswi-i38833ad6-c -j RETURN
-A neutron-openvswi-i38833ad6-c -p tcp -m tcp -m multiport --dports 1:65535 -j RETURN
-A neutron-openvswi-i38833ad6-c -p udp -m udp -m multiport --dports 1:65535 -j RETURN
-A neutron-openvswi-i38833ad6-c -m state --state INVALID -m comment --comment "Drop packets that appear related to an existing connection (e.g. TCP ACK/FIN) but do not have an entry in conntrack." -j DROP
-A neutron-openvswi-i38833ad6-c -m comment --comment "Send unmatched traffic to the fallback chain." -j neutron-openvswi-sg-fallback
-A neutron-openvswi-sg-chain -m physdev --physdev-out tap38833ad6-c6 --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-i38833ad6-c

neutron-openvswi-i38833ad6-c这条Chain是用于规则虚拟机入口流量,这里看住它只从neutron-openvswi-sg-chain上面跳转下来,同时将没匹配的到规则丢给neutron-openvswi-sg-fallback

Chain neutron-openvswi-sg-chain

$ iptables-save | grep neutron-openvswi-sg-chain
:neutron-openvswi-sg-chain - [0:0]
-A neutron-openvswi-FORWARD -m physdev --physdev-out tap38833ad6-c6 --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-openvswi-sg-chain
-A neutron-openvswi-FORWARD -m physdev --physdev-in tap38833ad6-c6 --physdev-is-bridged -m comment --comment "Direct traffic from the VM interface to the security group chain." -j neutron-openvswi-sg-chain

-A neutron-openvswi-sg-chain -m physdev --physdev-out tap38833ad6-c6 --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-i38833ad6-c
-A neutron-openvswi-sg-chain -m physdev --physdev-in tap38833ad6-c6 --physdev-is-bridged -m comment --comment "Jump to the VM specific chain." -j neutron-openvswi-o38833ad6-c
-A neutron-openvswi-sg-chain -j ACCEPT

这里可以看到neutron-openvswi-sg-chain处理虚拟机入口和出口流量,同时由neutron-openvswi-FORWARD跳转而来。
physdev模块是iptables用于过滤linuxbridge上的网络包,

参数说明
-m physdev
--physdev-in 发出虚拟机的数据包,作用于INPUT, FORWARD and PREROUTING
--physdev-out 接受虚拟机的数据包、作用于FORWARD, OUTPUT and POSTROUTING

Chain neutron-openvswi-FORWARD

$ iptables-save | grep neutron-openvswi-FORWARD
:neutron-openvswi-FORWARD - [0:0]
-A FORWARD -j neutron-openvswi-FORWARD
-A neutron-openvswi-FORWARD -j neutron-openvswi-scope

根据上下文可以确定,neutron-openvswi-FORWARD是由filter表的FORWARD跳转过来。

Chain FORWARD

$ iptables-save | grep FORWARD
-A FORWARD -j neutron-filter-top
-A FORWARD -j neutron-openvswi-FORWARD

这里看到报文在转发之前还进入了neutron-filter-top链,继续往下。

$ iptables-save | grep neutron-filter-top
:neutron-filter-top - [0:0]
-A neutron-filter-top -j neutron-openvswi-local

$ iptables-save | grep neutron-openvswi-local
:neutron-openvswi-local - [0:0]

看到这里我想大部分同学应该明白了,LVS DR模式的虚拟机在转发报文时,默认的FORWARD链里面并没有针对处理报文转发的规则。于是我在neutron-openvswi-local加了一条ACCEPT的语句,终于客户端就能正常请求VirtualServer了。

思考

由于LVS的DR模式的特殊性,VirtualServer在收到客户端请求时,并不响应请求,只修改报头重新转发给RealServer。从宏观来看过程并不是VS去请求RS。当请求走到VS所在宿主机上面时,自然会分到FORWARD链上,而这时Netron处理虚拟机iptables时,只做了对虚拟机访问的限制,而当虚拟机需要转发自己数据包时就没有处理规则。从而导致客户端在连接时出现超时的现象。

由于Neutron有基于Haproxy的负载均衡服务,并不鼓励在虚拟机上直接搭建负载均衡器,所以我想在处理这类的问题应该都转到FAAS上面了。总之通过这次排点,对Neutron这块又有了新的认识。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容