Ricky 最近有一个需求:因为根据降低成本的需要,需要缩减虚拟机,所以目前打算在一台虚拟机上跑两个应用;但是在程序代码中做了 IP 地址限制,所以需要在一台虚拟机上配置两个内网 IP 地址。
以下描述以 CentOS Linux 7.6 为例:
[root@XXX ~]# cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) [root@XXX ~]#
如果此时我们有两个内网 IP 地址,但是只有一张路由表,那么会发生什么呢?
[root@XXX ~]# ip add | grep 172 inet 172.16.173.158/24 brd 172.16.173.255 scope global noprefixroute dynamic eth0 inet 172.16.174.31/24 brd 172.16.174.255 scope global noprefixroute dynamic eth1 [root@XXX ~]# [root@XXX ~]# ip route default via 172.16.173.1 dev eth0 proto dhcp metric 100 169.254.169.254 via 172.16.173.254 dev eth0 proto dhcp metric 100 172.16.173.0/24 dev eth0 proto kernel scope link src 172.16.173.158 metric 100 172.16.174.0/24 dev eth1 proto kernel scope link src 172.16.174.31 metric 101 [root@XXX ~]#
通过上方的输出可以看到,目前一台 CentOS Linux 虚拟机上有两个内网 IP 地址分别是:172.16.173.158/24 和 172.16.174.31/24 ,和一条去往 172.16.173.1 的默认路由。
假设现在有一台服务器 A ,想去访问 172.16.174.31 上的应用( A 发起一个目的 IP 为 172.16.174.31 的 TCP 连接)。
那么 172.16.174.31 在往回发送数据包时,数据包会通过默认路由从 eth0 网卡发送给 172.16.173.1( eth0 网卡上配置的 IP 地址是 172.16.173.158 ),这也就意味着在回包的时候不是 172.16.174.31 回的,而是 172.16.173.158 回的(即 IP 数据包的源 IP 地址是 172.16.173.158 )。
对于服务器 A 来说,A 是要跟 172.16.174.31 建立 TCP 连接,结果却收到来自 172.16.173.158 的回复,那么这个 TCP 连接自然是建立不起来的。如何解决这个问题呢?针对不同的网卡使用不同的路由表进行路由(即根据源 IP 地址进行路由)即可:
[root@XXX ~]# echo 1 > /proc/sys/net/ipv4/ip_forward # 开启 IP 路由转发功能 [root@XXX ~]# ip rule add from 172.16.173.158 table 10 # 针对不同的网卡(或 IP 地址)配置多个路由表 [root@XXX ~]# ip rule add from 172.16.174.31 table 20 [root@XXX ~]# ip route add default via 172.16.173.1 table 10 # 在不同的路由表中配置默认路由 [root@XXX ~]# ip route add default via 172.16.174.1 table 20 [root@XXX ~]# ip route flush cache # 刷新
虚拟机重启后上述配置就失效了。如果希望重启后还能生效,请将上述命令添加到 /etc/rc.local 。
路由表现在需要这么查看:
[root@XXX ~]# ip route list table 10 default via 172.16.173.1 dev eth0 [root@XXX ~]# ip route list table 20 default via 172.16.174.1 dev eth1 [root@XXX ~]#
发表评论?