本文记录虚拟机无法上网的几种可能的解决办法,虽然OpenStack的版本是基于Pike 发行版,环境的搭建基于DevStack,但对其它版本应该都可以适用。
假设你的基础网络配置没有问题,而且物理机可以成功访问外网,用DevStack可以成功搭建好一个OpenStack集群,如果不做任何修改,你的虚拟网络是无法与外界连通的。
虚拟机需要与外界连通,需要考虑的因素包含下面几点:
- Floating IP的创建
- Security Group的配置
- IP table规则是否正确
- 域名服务器配置是否正确
我们一个一个来看,首先对创建的虚拟机关联一个Floating IP,虚拟网络与物理网络默认是隔离的,外界与虚拟机互访需要借助Floating IP,Floating IP并不是一个物理存在的IP,它实现本质上是通过IP table来完成的SNAT和DNAT规则。
分配Floating IP的前提是虚拟网络的DHCP服务器以及router是正常工作的,讨论DHCP与router的原理是另一个网络的主题了,这里不再扩展。
接下来需要做security group的修改,环境搭建好之后,只有一个默认的security group,默认的security group是禁止外界ssh以及ping虚拟机的,所以你可以选择创建一个自己的security group定义合适的rule,或者直接修改default security group,将虚拟机关联到合适的security group。我们选择后者,修改后的security group如下图所示:
第一条规则,允许来自任何IP对虚拟机发起ping命令,第二条规则则定义了允许任何外界的IP通过SSH连接到虚拟机。可以直接在界面上操作,也可以通过命令行操作,通过命令行操作,命令如下:
openstack security group rule create 4db9cb30-7dde-4026-b99b-1bd41c491b85 –ingress –protocol icmp –description “for ping”
openstack security group rule create 4db9cb30-7dde-4026-b99b-1bd41c491b85 –ingress –protocol tcp –dst-port 22
上面的4db9cb30-7dde-4026-b99b-1bd41c491b85是security group的ID,修改规则之后,我们试试ping 虚拟机的floating IP,并SSH到虚拟机:
如果顺利的话,我们可以连上虚拟机了,试试虚拟机内访问外网,发现虚拟机如果无法访问外网,可以从下面两个角度再考虑,宿主机上的IP table是否设置正确,域名服务器是否设置正确,不妨在物理机上执行下面的规则:
iptables -t nat -I POSTROUTING -o eno1 -j MASQUERADE
这条规则的意思是通过地址伪装,自动读取宿主机上的物理网卡eno1的IP,然后做SNAT出去,接下来可以检查域名服务器是否设置正确,如果采用的网络是devstack默认设置的,域名设置看起来像下面这样(假设你用的是默认创建好的网络,而不是你自定义的网络):
$ cat /etc/resolv.conf
search openstacklocal
nameserver 10.0.0.2
可以考虑使用Google提供的免费域名服务器: 8.8.8.8和8.8.4.4。更新域名服务器为8.8.8.8再测试网络的连通性:
实际的环境可能千差万别,排查上面这些可能的原因后,做网络的故障分析时,熟练应用tcpdump,或者借助一些第三方工具例如wireshark可以帮助你分析定位问题。