让特定虚拟机流量的外网出口不走 neutron vrouter 默认的 external gateway 而是用另一个地址作为出口网关。例如,属于同一个 neutron 子网的虚拟机,需要指定不同的路由访问公网。这可能是因为这些虚拟机按照用途进行了区分,例如办公用机需要用户进行认证之后才可以上网,而开发节点为了方便可以直接访问公网。

对系统改动最少的解决办法是在 neutron vrouter 所在的 network namespace 新建一个路由表,配置相应的路由规则,例如设置新的默认网关。然后利用 iproute2 的 ip rule 为特定虚拟机指定路由表。

  • 虚拟机IP 192.168.10.135
  • 外部网络地址 10.20.128.0/18
  • 欲设置该虚拟机的出口网关为 10.20.128.254
  • 但不改变其他虚拟机的路由规则,原默认网关为 10.20.191.254
    网络连接

192.168.10.1 是 nova 虚拟机 192.168.10.135 的默认网关。这个地址在 neutron vrouter 上。vrouter 将 192.168.10.135 为源地址的包,经 NAT 之后,按照路由表转发规则发往下一跳地址 10.20.128.254 ,这时已经离开了 OpenStack 平台。

在虚拟机里查看。默认网关 192.168.10.1。

[root@host-192-168-10-135 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.10.1    0.0.0.0         UG    0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
169.254.169.254 192.168.10.1    255.255.255.255 UGH   0      0        0 eth0
192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0

在网络节点运行。

# ip netns

找到 qrouter。设置环境变量

# qrouter="qrouter-b051f50b-5148-4081-ba13-4ce8aac703fd"

查看路由

# ip netns exec ${qrouter} ip route
default via 10.20.191.254 dev qg-b73193e9-40 
10.20.128.0/18 dev qg-b73193e9-40  proto kernel  scope link  src 10.20.162.55 
192.168.10.0/24 dev qr-f1fd249b-4a  proto kernel  scope link  src 192.168.10.1

显示默认网关为 10.20.191.254。外部网络接口是 qg-b73193e9-40。

# ip netns exec ${qrouter} ip route list table 3

显示为空

设置默认网关

# ip netns exec ${qrouter} ip route add default via 10.20.128.254 table 3

添加外部网络路由

# ip netns exec ${qrouter} ip route add 10.20.128.0/18 dev qg-b73193e9-40 table 3

设置从特定虚拟机来的流量查找 table 3

# ip netns exec ${qrouter} ip rule add from 192.168.10.135/32 table 3

刷新路由缓存

# ip netns exec ${qrouter} ip route flush cache

查看新的路由表

# ip netns exec ${qrouter} ip route list table 3
default via 10.20.128.254 dev qg-b73193e9-40 
10.20.128.0/18 dev qg-b73193e9-40  scope link 

main 表没有变化

# ip netns exec ${qrouter} ip route list table main
default via 10.20.191.254 dev qg-b73193e9-40 
10.20.128.0/18 dev qg-b73193e9-40  proto kernel  scope link  src 10.20.162.55 
192.168.10.0/24 dev qr-f1fd249b-4a  proto kernel  scope link  src 192.168.10.1

查看 rule

# ip netns exec ${qrouter} ip rule show
0:  from all lookup local 
32765:  from 192.168.10.135 lookup 3 
32766:  from all lookup main 
32767:  from all lookup default 

在虚拟机里操作。

[root@host-192-168-10-135 ~]# ping baidu.com
PING baidu.com (123.125.114.144) 56(84) bytes of data.
64 bytes from 123.125.114.144: icmp_seq=1 ttl=45 time=4.91 ms
64 bytes from 123.125.114.144: icmp_seq=2 ttl=45 time=4.61 ms

[root@host-192-168-10-135 ~]# traceroute -d 123.125.114.144
traceroute to 123.125.114.144 (123.125.114.144), 30 hops max, 60 byte packets
 1  gateway (192.168.10.1)  0.824 ms  0.791 ms  0.799 ms
 2  10.20.128.254 (10.20.128.254)  2.525 ms  2.516 ms  3.005 ms
 ......

在网络节点抓包。虚拟机没有 floating ip 的情况。看到 vrouter 网络接口地址。

# ip netns exec ${qrouter} tcpdump -nni qg-b73193e9-40 host 123.125.114.144
IP 10.20.162.55 > 123.125.114.144: ICMP echo request,id 5986, seq 53,length 64
IP 123.125.114.144 > 10.20.162.55: ICMP echo reply,id 5986,seq 53,length 64

在网络节点抓包。虚拟机绑定了 floating ip 的情况。看到虚拟机 floating ip 地址。

# ip netns exec ${qrouter} tcpdump -nni qg-b73193e9-40 host 123.125.114.144
IP 10.20.162.49 > 123.125.114.144: ICMP echo request,id 6009,seq 5,length 64
IP 123.125.114.144 > 10.20.162.49: ICMP echo reply,id 6009,seq 5,length 64
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐