概述
目前阿里云ECS部分机型可以配置多张网卡(一张原生网卡+若干张弹性网卡),用来实现业务上对于系统内多网卡的需求,详细可以参考【新功能】弹性公网IP绑定弹性网卡新功能及最佳实践。在使用过程中,可能会遇到多个弹性公网IP绑定到一个ECS上的原生网卡、弹性网卡上后无法通信的问题,这个时候需要检查系统内的路由配置和策略(policy rules)。
从route路由表说起
默认情况下,linux系统中都会有一张路由表,使用route或ip route就可以进行查看,如
default via 172.16.127.253 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.16.112.0/20 dev eth0 proto kernel scope link src 172.16.115.242
以上起到关键作用的是第一行路由,它声明了一条默认路由,从eth0网卡中出去,目标是网关172.16.127.253。在只有一张网卡的实例中,这样的配置是没有问题的,但如果有多张网卡的情况下,入流量会从不同的网卡中进入实例,但出流量都会从eth0网卡中出去(譬如从外部ping 绑定在弹性网卡上的弹性公网IP,ICMP request包会从实例的弹性网卡中进入实例,而实例回复的ICMP reply包会从eth0中流出),导致出入路径不一致,会造成一系列的问题,如单网卡流量瓶颈、负载不均衡等问题。
真实的路由表
在linux系统中,实际上是有255张路由表的,默认使用的是254这张路由表,使用route命令展示的即是这张表中的路由条目。除此之外的路由表我们可以对它进行适当的配置,以实现自定义或高级需求。
我们可以使用ip route list table [table index]来查看系统内的路由表条目,如
[root@xiaoling-hz-test ~]# ip route list table 254
default via 172.16.127.253 dev eth0
169.254.0.0/16 dev eth0 scope link metric 1002
172.16.112.0/20 dev eth0 proto kernel scope link src 172.16.115.242
以上条目可以看到系统内默认的254号路由表内的条目,另外,还可以将index置为0来查看系统内所有的路由条目,这在需要循环遍历系统内自定义路由表时非常有用。
PS. table==253这张路由表被系统默认为是default表,建议使用1-252号路由表来添加自定义的路由条目。被linux预先定义的路由表详情可以查看系统内/etc/iproute2/rt_tables,以下是一个示例,可以看到253 - 255已经被系统定义:
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
策略路由
为什么会需要多张路由表呢?这不得不提到策略路由,目前我们需要实现的功能是同进同出,保证从eth0口进来的包从eth0口出去,eth1进从eth1出,但弹性公网IP需要有一条默认路由来让ECS可以正常访问公网,但却又不能直接在默认路由表里添加两个目标网段是0.0.0.0,分别从eth0、eth1中出去的路由,这个时候策略路由就派上用场了,我们需要根据源地址进行策略选择。
简单来说就是配置两张路由表,路由表中分别有从eth0、eth1中出去的默认路由,在系统需要发包时,根据包的源IP进行选择,eth0的源IP就从包含eth0的路由表出去,eth1的源IP就从eth1的路由表走,从而实现同进同出。
linux系统内关于策略的索引是一个无符号的32位整型数值,所以理论上策略索引的数值可以达到4294967295之多,当然通常我们只需要使用个位数的索引条目即可。
具体的一个配置
以上说的都是理论,可能会有一些虚,下面我们来实际进行一个配置。我们特意选取阿里云官方尚未支持自动配置的镜像Ubuntu 16.04 64位来进行配置,以下是这个场景中相关参数:
ECS实例网关地址:172.16.127.253
==原生网卡信息==
名称:eth0
IP地址:172.16.116.38
绑定的弹性公网IP:47.99.42.x
==弹性网卡信息==
名称:eth1
IP地址:172.16.116.39
绑定的弹性公网IP:116.62.163.x
如何获得ECS实例完整的网卡信息
阿里云ECS控制台对于实例的网卡信息展示的不是很完全,建议通过API方法 DescribeNetworkInterfaces 来获取,若没有API调试环境,可以使用阿里云的API Explorer来调试,非常方便,以下是一个示例 URL ,点击后可以直接进入在线调试页面。
检查系统的默认配置
依次查看网卡、默认路由,可以看到系统内的配置残缺不全:
root@iZbp14bxrlofsqs3d5dw43Z:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:16:3e:0c:72:5d brd ff:ff:ff:ff:ff:ff
inet 172.16.116.38/20 brd 172.16.127.255 scope global eth0
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:16:3e:10:aa:7e brd ff:ff:ff:ff:ff:ff
root@iZbp14bxrlofsqs3d5dw43Z:~# ip route list table 254
default via 172.16.127.253 dev eth0
172.16.112.0/20 dev eth0 proto kernel scope link src 172.16.116.38
首先编辑/etc/network/interfaces文件,在最后加上关于eth1的定义,新添加的两行分别告诉系统在启动时自动拉起eth1、eth1的参数配置使用DHCP协议,详细的配置说明可以参考man interfaces:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet dhcp
保存后执行systemctl restart networking重启网络服务,可以看到eth1网卡已经配置上IP地址了:
root@iZbp14bxrlofsqs3d5dw43Z:~# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:16:3e:0c:72:5d brd ff:ff:ff:ff:ff:ff
inet 172.16.116.38/20 brd 172.16.127.255 scope global eth0
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:16:3e:10:aa:7e brd ff:ff:ff:ff:ff:ff
inet 172.16.116.39/20 brd 172.16.127.255 scope global eth1
valid_lft forever preferred_lft forever
接下去就需要配置策略路由了,针对这个场景,我们定义了以下信息:
==原生网卡==
使用路由表100,策略路由优先级索引为200
添加路由的命令(网关地址根据实际情况而定):ip route add default via 172.16.127.253 dev eth0 tab 100
添加策略的命令(源IP根据实际情况而定):ip rule add from 172.16.116.38 tab 100 priority 200
==弹性网卡==
使用路由表101,策略路由优先级索引为300
添加路由的命令(网关地址根据实际情况而定):ip route add default via 172.16.127.253 dev eth1 tab 101
添加策略的命令(源IP根据实际情况而定):ip rule add from 172.16.116.39 tab 101 priority 300
执行以上命令后,系统内策略路由就已经配好了,通过相关命令查看的结果如下(已经略去无关信息):
root@iZbp14bxrlofsqs3d5dw43Z:~# ip route list table 0
default via 172.16.127.253 dev eth0 table 100
default via 172.16.127.253 dev eth1 table 101
default via 172.16.127.253 dev eth0
172.16.112.0/20 dev eth0 proto kernel scope link src 172.16.116.38
172.16.112.0/20 dev eth1 proto kernel scope link src 172.16.116.39
root@iZbp14bxrlofsqs3d5dw43Z:~# ip rule list
0: from all lookup local
200: from 172.16.116.38 lookup 100
300: from 172.16.116.39 lookup 101
32766: from all lookup main
32767: from all lookup default
可以看到系统中增加了table==100、101的两张路由表,增加了200、300两个优先级的策略,分别指定eth0、eth1出入的规则,这样就可以做到一张网卡同进同出了。
阿里云原生的做法
查看阿里云官方关于配置 ECS 实例的弹性网卡的说明,以下几种镜像是可以直接支持不需要手工配置:
CentOS 7.3 64 位
CentOS 6.8 64 位
Windows Server 2016
数据中心版 64 位
Windows Server 2012 R2
数据中心版 64 位
实际上CentOS系统内部也是采用了类似的策略来实现的,使用ip route和ip rule命令可以查看到响应的策略,只是路由表索引和策略路由的优先级序号有些许不同,各位可以实际验证一下。
参考文献
了解更多请微博关注阿里云客户满意中心
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
相关标签: