02月20, 2017

双网卡虚拟机、内核rp_filer和neutron

双网卡虚拟机、内核rp_filer和neutron

背景

通常情况下,我们的虚拟机都仅有一块儿网卡,一般配置10.x.x.x的私网IP;

但有时候,一些业务场景需要第二块网卡,而且一般配置公网IP,我们的“奥创”(基于OpenStack)平台,支持用户为虚拟机热插第二块网卡;

比如这台机器:
alt

这个时候,当从另外一台单网卡的虚拟机(IP为10.x.x.x),ping上面两个IP时,发现那个公网IP不通??

路由

首先怀疑的,就是路由问题,单网卡虚拟机的路由类似这样:

#ip ro sh
default via 10.x.x.1 dev eth0  proto static  metric 100
10.x.x.0/23 dev eth0  proto kernel  scope link  src 10.x.x.10  metric 100

热插第二块网卡后,多了公网IP的流量,默认路由还保持上面,是否合适呢?为此,我们咨询了公司网络组同事,调整后的路由表类似这样:

# ip ro sh
default via 36.x.x.1 dev eth1
10.0.0.0/8 via 10.x.x.1 dev eth0
36.x.x.0/26 dev eth1  proto kernel  scope link  src 36.x.x.10  metric 1 
10.x.x.0/23 dev eth0  proto kernel  scope link  src 10.x.x.120  metric 1

也就是说,我们调整:

  • 私网IP的流量,走eth0
  • 其他流量,走eth1

然而,没卵用,还是不通!

非对称路由

网上一顿搜之后,我们发现,貌似我们遇到了“非对称路由”(asymmetric routing)的问题: alt

简单说就是:ping一块网卡,回程的包,却从另一块网卡出来;
具体到我们的场景,就是:

  1. ping 36.x.x.x
  2. 包到达目的服务器的eth1
  3. 目的服务器回包,查找路由表,匹配到下面路由
  4. 10.0.0.0/8 via 10.x.x.1 dev eth0
  5. 回程包,从eth0发出!!

内核rp_filter

在非对称路由方面,我们又进一步查到了内核关于这方面的一个参数:rp_filter

rp_filter(reverse path filtering),简单说就是:回包时,内核检查,对于包的来源IP来说,从路由决定的网卡发回,是否可达,如果检查不通过,就不发包了;

这个参数,有下面3个值:

  • 0,不检查
  • 1,严格处理
  • 2,宽松处理

我们使用下面的命令,检查了一下这个参数,是关闭的:

# sysctl -a | grep rp_filter

那还有可能是哪方面的原因呢??

neutron

排查了虚拟机内部,就将注意力转移到了外部虚拟化层面;
在neutron层面,我们默认是开启了安全组的,neutron的安全组会使用iptables,在宿主机上添加一系列规则;
查看宿主机的iptables,我们找到的问题所在: alt

出于安全问题,neutron的安全组默认仅允许匹配的MAC/IP,在我们的问题场景中,如上面【非对称路由】小节中分析的第5条,回程包,IP地址是36.x.x.x,但是却从eth0发出,用的是eth0的MAC,所以被Drop了;

关于neutron的这个feature,可以参考: allowed address pairs

解决方案

关于“allowed address pairs”,neutron有相应的API,命令行操作大概如下: alt

iptables规则会做相应更改: alt

本文链接:https://www.opsdev.cn/post/instance-with-two-nics-and-neutron-allow-address-pair.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。