为了账号安全,请及时绑定邮箱和手机立即绑定

Openstack Neutron(网络)查错及解决

标签:
云计算

webp

OpenStack_Project_Neutron_vertical-2-300x250.png

这篇文章翻译自这里

其中结合了自己的一些观点和总结,内容是如何排查openstack网络问题及解决方法。笔者是openstack新手,翻译和注解过程中如有错误,欢迎指正。

话不多说,进入正题:

常见问题分类

您可能遇到的问题可以分为以下几类:

  • 配置错误 - 遇到问题可能是因为你在neutron配置文件中进行了错误的配置。使用错误的配置工具也可能导致问题。配置错误的底层网络会影响neutron的功能,因为每个数据包最终都会通过物理层。举个例子,产生错误的原因可能是外部网络不可访问,或由于防火墙规则阻止了你的虚拟机流量通往外部。所以如果底层网络不可用,neutron也将无法正常工作。

  • 代码中的错误 - 你可能会在代码中发现错误。幸运的是,你大概率不会是第一个遇到这个bug的人,如果有人已经上报了bug,你可以在 这里 找到答案。如果找不到这个bug,那么你可能是第一个遇到它的人,你应该报告这个bug,这样开发人员就可以开始修复它了。

问题一: 无法用private IP ping通或ssh远程登录虚拟机

这是一个常见的问题,特别是对于openstack新手来说。为了调试这个问题,我们首先应当理解虚拟机是如何获得一个IP的。

虚拟机如何获得IP?

为了回答这个问题,我们需要介绍 DHCP 代理。如果你熟悉网络,会知道 DHCP 是分发不同网络参数(包括IP地址)的协议。

DHCP 代理通过 RPCneutron-server 进行通信,它使用 namespaces (命名空间)确保网络隔离,因此每个网络都有自己的DHCP命名空间。在这个命名空间里有一个名为 dnsmasq 的进程,它实际上服务于DHCP参数,包括IP地址。DHCP代理使用一个 lease file (租约文件)来配置这个dnsmasq。

让我们更详细地看看IP分配过程:


webp

vm_get_ip.png

在这个过程结束时,新的IP被提供给虚拟机。

让我们更详细地跟踪数据流。了解我们的数据流是很重要的,这将使我们知道去哪里查看问题并期待更快地找到问题。

数据流在 neutron - openvswitchlinux bridge 中有两个默认实现。我们从 openvswitch 开始:

webp

openvswitch_flow.png


稍微解释一下上图:

firewall bridge(防火墙)是一个 linux bridge,这是应用 security groups(安全组)的地方,使用 iptables 来实现。我们不能将iptables应用到连接到 openvswitch 端口的接口,所以我们需要在中间有防火墙。

集成网桥(integration bridge,br-int)负责用与网络相关联的 VLAN ID 标记或取消标记那些来往于虚拟机的流量。每个网络都有一个VLAN ID,运用于主机内部以隔离流量(这也是为什么它被称为本地VLAN ID)。

隧道桥(tunnel bridge,br-tun)是负责连同的通道。它将分配给网络的VLAN ID转换成 segmentation id (分段ID)。举个例子,如果你正在使用 GRE tuneel ,则 GRE tunnel ID 将是分配给网络的分段ID。

现在我们来看看linux bridge的数据流:


webp

linux_bridge_flow.png

在linux bridge实现中,每个网络都有一个linux bridge。现在我们有net1并且虚拟机连接到net1上,同时可看到插入net1网桥的接口是eth0.100,这意味着vlan 100被分配给net1网络。

Debug步骤

首先检查虚拟机是否启动,这听起来很简单,但不能略过这一步:

$ nova list

输出应当类似下图:


webp

nova_list.png

在上面的输出中,我们可以看到实例正在运行。如果它没有运行,我们可以在日志中查看出错的线索。查看日志总是一个明智的步骤,因为许多问题都反映在日志里。

$ grep -E -R -i "trace|error" /var/log/nova/ var/log/neutron/

笔者注:log中可能会提示代码错误,需要我们手动改动配置文件或python文件,一般都能在网上查到方法。由于我们使用openstack存在版本差异,可能在某个版本出现的bug在下个版本修复了,但依旧存在于这个版本,于是我们可以参考 github 上不同版本对比修改。

需要明确的是,错误可能是由任何因素造成的。它甚至可能与你的OpenStack部署无关,而与你的硬件有关。举个例子,也许是因为你已经没有足够的空间或内存去启动和运行虚拟机,你可以通过以下方式验证:

$ df -Ph && free -m

错误的另一个常见原因是默认的安全组规则。default security group默认情况下不允许ICMP(ping命令使用的协议),所以我们需要配置它。

笔者注:可以在openstack horizon界面中添加ICMP和ssh(TCP)规则,也可以通过命令行。命令行方式给默认安全组添加规则的方法如下:

$ nova secgroup-add-rule default icmp -l -l 0.0.0.0/0

$ nova secgroup-add-rule default tcp 22 22 0.0.0.0/0

其中,第一条命令使虚拟机能被ping通,第二条使虚拟机可以ssh远程登录。

如前所述,物理底层网络也可能导致问题,在排查问题前,应当确保openstack各个节点间能ping通。

笔者注:在引入环境变量后,可以使用如下命令查看各个节点的情况:

$ openstack compute service list

如果发现某个节点的状态是down,应当及时检查硬件设备:电源是否接通,网线是否接通。

端口绑定

如果虚拟机没有启动,请检查是否在虚拟机端口或路由器、DHCP端口上遇到了端口绑定故障。

对于虚拟机端口,将会被记录为端口绑定失败,因此很容易发现。

对于DHCP或路由器来说,并不是那么容易,因为端口是异步创建的,这意味着你不会马上看到它。以路由器为例。当你创建路由器并添加新的接口时,即使在背后创建的端口进入绑定失败状态,操作也会成功。那是因为这是异步发生的。

笔者注:针对原文下面的指令,首先我们可以从openstack horizon界面中获得端口的ID,或者通过命令行获得。我们可以通过命令行看到所有的端口ID:

$ openstack port list

查看端口绑定情况:

$ neutron port-show <port_id> -F "binding:vif_type" -F "binding:host_id"

webp

binding_failure.png


有两种情况容易导致这个错误发生:

1.当你在路由器中添加新的子网或新的接口端口时,OVS代理已经挂掉。 这可以通过以下方式轻松验证:

$ neutron agent-list

你可以在openvswitch agent那行查看状态,如果正常,在alive栏会看到笑脸。

笔者注:笔者在安装openstack的时候参照的是官方文档,并没有用到 openvswitch 。但上述指令不失为一种检测网络代理是否正常的方法。笔者上次遇到错误就是发现 Linux bridge agent 出错,然后在log中找到了问题。

另一种OVS代理挂掉的症状是tap设备下没有VLAN标记。你可以通过以下方式验证:

$ ovs-vsctl show | grep tap -A 3

这种情况下唯一的解决方法就是重新创建虚拟机。

2.代理或服务器配置文件中的配置错误。这通常是因为在配置文件中使用了一些非默认值。

虚拟机是否接受到IP?

既然我们知道了虚拟机得到IP的过程,我们可以检查虚拟机是否接受到IP。可以在虚拟机命令行中使用如下指令:

$ ip a

如果没有IP,检查DHCP代理是否正常运行:

$ neutron agent-list

接下来,可以检查 dnsmasq 是否在你指定的网络节点正常运行。

$ ps -ef | grep dnsmasq | grep <network_id>

还可以检查 lease file(租约文件)是否存在并且虚拟机的mac地址在host 文件中。

$ cat /var/lib/neutron/dhcp/<network_id>/host

如果以上都排查了发现没有IP并且其他一切都看起来很正常,那么可以检查DHCP代理的log文件:

$ less /var/log/neutron/dhcp-agent.log

此时,还需要确保没有跨节点连接问题,所以请尝试在主机和虚拟机之间进行ping操作。不要忘记给主机设定正确的静态IP。

要记住的是,如果底层网络有问题,它会影响neutron的运行。 例如,如果物理交换机中不允许使用某些vlan ID,它将反映在neutron中,并且可能存在连接问题。

如果还没有找到问题,那么是时候拿出终极武器了—— tcpdump。tcpdump将允许你跟踪数据包的完整过程,并查看它们在每个步骤中的变化情况。有很多很棒的在线教程解释了如何使用它,对于最基本的使用,试试运行:

$ tcpdump -i <name_of_the_device>

问题二: 虚拟机无法访问外部网络

为了解决这个问题,我们需要了解L3 agent(L3代理)的工作原理。其主要职责是允许L3连接和路由,也提供NAT,并使用命名空间进行网络隔离。通常它将被安装在网络节点上,也是提供访问外部网络的代理。

笔者注:在官网的安装文档上并没有网络节点,而是把网络服务分装在控制节点和计算节点上,这里所说的网络节点应当就是我们平时配置的控制节点。

让我们看看虚拟机尝试访问外部网络的过程:


webp

l3_external_flow.png

和解析虚拟机如何获得IP类似,下图是linux bridge数据流:


webp

l3_external_linux_bridge_flow.png

Debug步骤

首先,确保在环境中配置了正确的安全组规则,需要明确地允许ssh和ping。(这在上文中已经讲过,如下指令可以查看环境中的所有安全组都具有哪些规则,也可以在horizon界面中查看)

$ neutron security-group-rule-list

检查是否可以ping通 private IP。如果不能,就不必指望浮动IP起作用。请检查虚拟机是否可以到达路由器,因为如果不能到达路由器,必然不能到达外部网络。

笔者注:官网教程 创建一个虚拟机  中写了如何创建 provider networkself-service network。在self-service netwrok中,创建的网络有一个内部IP和一个外部IP。创建self-service network时,需要有一个provider network,并创建一个路由,把self-service network的子网作为路由的一个接口,再把路由连接到provider网络上。这时运行以下命令,可以看到provider网络的两个网关:

$ neutron router-port-list router

webp

fix_ip.png


如上图,其中 172.16.1.1 是self-service network的内部网关,是无法从外部ping通的,203.0.113.102 是外部网关,可以从外部ping通。如上所说,在创建self-service network时,会通过建立一个路由把该网络和一个provider network连接以保证self-service network可以访问外部网络。

在self-service network中创建虚拟机,需要给虚拟机分配一个浮动IP,如果我们想ping通虚拟机,应当使用这个浮动IP。

上文的ping通private IP笔者略有疑惑,可能指的是从虚拟机内部ping 类似 172.16.1.1 的内部网关,也可能是从外部ping虚拟机绑定的浮动IP。

接下来,从路由器命名空间尝试使用浮动IP来ping 虚拟机:

$ sudo ip netns exec qrouter-xxx-xxx-xxx ping <vm_floating_ip>

笔者注:上面命令的命名空间可以用如下指令获得:

$ ip netns

用如下指令可以得到所有虚拟机的IP:

$ openstack server list

这可能是个愚蠢的检查,因为浮动IP总是处于路由器命名空间内,但至少它会告诉我们情况有多糟糕。

你还应该检查网桥配置问题。 用下面的命令检查它:

$ ovs-vsctl show

别忘了检查L3 agent的log文件:

$ sudo grep -E -i "error|trace" /var/log/neutron/l3-agent.log

用以下命令看虚拟机是否得到了IP:

$ ip a

从虚拟机里ping网关看是否能到达:

$ route -n

$ ping <default_gateway_ip>

问题三: 虚拟机无法访问元数据服务器

元数据服务器是为虚拟机提供元数据的服务。数据可以是ssh密钥,ip地址,主机名。

元数据代理负责将来自虚拟机的请求代理到元数据服务器或 nova。 有两种方法来配置它:

  • 路由网络 - 当你有一个连接到路由器的网络

  • 非路由网络 - 当你有没有连接到路由器的网络,所以它是隔离的。

我们来看看路由网络的工作流:


webp

routed_networks_metadata.png

注意:metdata代理由L3代理生成,并监听请求。当来自虚拟机的请求到达元数据代理时,它将一些信息添加到虚拟机和路由器id的头部IP中,并将其转发给元数据代理。

现在让我们更仔细地看看其他配置 - 隔离网络:


webp

isolated_network_metadata.png

注意:为了隔离网络能工作,必须在dhcp配置文件中进行配置:

enable_isolated_metadata = True

笔者注:在以下文件中配置:

/etc/neutron/dhcp_agent.ini

我们还使用DHCP的 option 121,在向DHCP请求IP地址时向虚拟机注入路由。 所以元数据代理是到达元数据服务器的下一个跃点。

Debug步骤

首先查看metadata agent是否正常运行:

$ neutron agent-list

在metadata agent 那行应当看到alive下面的微笑。

接着,检查metadata proxy是否正常。请记住,它是由L3代理在路由器(或dhcp)命名空间中产生的,所以您应该检查它是否在命名空间的进程表中:

$ sudo ip netns exec qrouter-xxx-xxx-xxx ps -ef | grep metadata-proxy

问题会反映在metadata的log文件中,所以前去检查:

$ sudo grep -E -i "error|trace" /var/log/neutron/metadata-agent.log /var/log/neutron/neutron-ns-metadata-proxy-xxx-xxx-xxx.log

检查是否可以通过路由/DHCP到达元数据服务器:

$ sudo ip netns exec qrouter-xxx-xxx-xxx ping <metadata-server_IP>

检查创建虚拟机的镜像是否支持 option 121。如果不支持,那么虚拟机可能无法得到路由并且到达元数据服务器。

如果所有都尝试了还没有发现问题,试着使用 tcpdump 来解决问题。

问题四: VIF plugging timeout

为了理解为什么会遇到timeout问题,我们需要介绍L2代理。

L2代理在计算主机上运行,其主要职责是配置节点上的本地交换机并连接新设备,它通过RPC与neutron服务器通信,还负责提供使用iptables和ip集合的安全组规则。

让我们更详细地看看VIF如何工作:


webp

vif_plugging.png

当Nova发送allocate_network请求时,它将超时设置为5分钟。如果Nova在5分钟内没有得到Neutron的回复,你会得到VIF plugging timeout。

debug步骤

检查日志。L2代理,neutron和nova日志可以帮助查找问题,在计算节点上输入:

$ sudo grep -E -i "error|trace" /var/log/nova/nova-compute.log /var/log/neutron/openvswitch-agent.log

在控制节点上:

$ sudo grep -E -i "error|trace" /var/log/neutron/server.log

如果系统加载缓慢,或者你正在执行压力测试,则可能需要调整/etc/nova/nova.conf文件中的服务器配置:

  • 尝试增加 vif_plugging_timeout 以提供更多的时间来插入接口

  • 尝试增加 rpc_thread_pool_sizerpc_conn_pool_size 以使处理速度更快

一些好用的工具

让我们回顾一下在对neutron进行debug过程中用到的工具。

ip a

ip addr(ip a只是一个快捷方式)对于检查你的机器/命名空间中的设备非常有用。它允许你获取设备名称、查看设备是否启动、获取IP地址、MTU以及其他一些网络参数。

route -n

它会显示路由表。通过路由表,你可以知道你的数据包在流出时将采用哪个路径。

iptables -L

查看节点上存在哪些防火墙规则。如果你的数据包突然消失或没有到达最终目的地,防火墙的某些规则可能是原因。

arp

查看主机上的arp表。利用它可以查看你的节点能不能找到其他节点的地址。

tcpdump

在这篇文章中多次提到过。这是一个很棒的数据包追踪工具,容易安装,也容易使用。我将在另一篇文章中介绍它,因为有很多方法可以使用,最好花时间专门学习。对于最基本的使用,只需运行:

$ tcpdump -i <device_name>

ip netns

查看namespace。为了列出你所在节点可用的namespaces,可以使用:

$ ip netns list

你可以使用 ip netns exec 查看更多。例如,要在命名空间中显示路由表,请使用:

$ ip netns exec qrouter-xxx-xxx-xxx route -n

OpenVSwich

如果你在部署中使用openvswitch,则有几个用于调试和故障排除的工具:

ovs-vsctl show —— 显示机器上网桥的配置

ovs-ofctl show —— 显示数据路径

ovs-ofctl dump-flows —— 转储安装在机器上的所有流

ovs-ofctl dump-flows br-tun —— 转储br-tun上的所有流

ovs-ofctl dump-flows br-tun table = 21 —— 在特定表中转储br-tun上的所有流

LinuxBridge

对于linux网桥,请使用以下命令:

brctl show  —— 显示机器上网桥的配置

brctl show <bridge name>  —— 显示特定网桥的配置

补充

再介绍一些你可能想要熟悉的几个重要的网络设备。

我们从TAP设备开始。TAP设备是一个虚拟网络接口,用于连接由虚拟机管理程序(KVM,Xen等)实现的虚拟机实例。流量到达TAP设备,由虚拟机实例接收。要记住TAP设备通常是流量的起点,可以从TAP设备开始跟踪流量。

要查看TAP设备,只需运行:

$ ip a | grep -i tab

更多关于TAP设备的信息,可以在 这里  找到。

TAP设备使用Linux bridge进行桥接。通常Linux桥名以qbr开头,这是qunaum bridge的简写(qunaum是neutron以前的名字)。你可以使用brctl列出系统上的linux bridge。

$ brctl show

你会在输出中看到TAP接口和qvb接口。

qvb(Quantum veth bridge)和另一end - qvo(Quantum veth openvswitch)构成一个虚拟以太网对(Virtual Ethernet Pair)。它用来连接Linux桥和OVS桥。可以把它们想象成一条管道,任何在一个设备上进入的东西都应该从这个设备上离开。

如果你列出集成桥上的端口,你将看到其中一个端口是qvo,它将你连接到Linude Bridge。

路由器和DHCP设备直连到br-int。在列出DHCP命名空间中的接口或列出集成网桥上的端口时,可以看到TAP设备条目。

$ ip netns exec qdhcp-<network_id> ip address

$ ovs-vsctl list-ports br-int

笔者总结

在了解了neutron的基础概念,通过一些图表知道了数据流的走向后,对于我们debug最有用的还是查看log。Openstack的log都处于 /var/log 目录下,我们通过查看、解决log里的问题,并重启相应网络服务,基本可以解决问题。

笔者翻译这篇博客的过程中,对Openstack的neutron模块有了更深的了解,也利用博客里梳理的思路解决了实验室Openstack环境遇到的问题,以后会多多学习这类博客,看到好的博客会争取翻译过来。



作者:Murray66
链接:https://www.jianshu.com/p/cf6168803d2e


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消