☰
先电平台运维实践:网络与存储故障排查全记录
2026/10/17 1:37:16 网站建设 项目流程

接着前两篇的进度写。先电平台搭好以后,真正开始往上面跑业务的时候,坑基本都集中在网络和存储里,这篇操作笔记3就把这段时间的实践过程完整记录一下。平台本身相当于在底层那套云管理组件外面套了一层教学管理外壳,所以你在页面上点的很多操作,最后都要落到各个服务组件的API上。想看得更透、查错更准,我还是建议整一套命令行操作方式。这篇笔记默认你已经完成了平台部署、能正常登录管理页面,如果环境还没搭好,建议先回头看第一篇。下面要讲的内容有三个重点:网络规划与连通性、实例从创建到连接的完整链路、块存储的挂载与扩容,最后附一份我整理的排查清单。前后花了大概一周时间反复测,踩了不少坑,下面都是实测记录。

1. 动手之前:先摸清平台的骨架

1.1 其实你操作的是两个入口

先电平台的管理页面看起来很完整,但你看到的网络、镜像、实例这些菜单,本质都是对底层管理组件的封装。封装有个坏处:错误信息被截断了。比如说,在浏览器里创建一个网络报错,页面只会提示“创建失败”,具体原因一点不给;而在命令行里,服务端会直接告诉你哪一步出了问题,比如“物理网络不存在”“DHCP agent不可用”之类的关键词。

所以操作的第一步,不是急着点菜单,而是先把命令行入口准备好。一般是先source一下认证脚本,然后验证一下认证信息是否正常:

source /etc/keystone/admin-openrc.sh openstack endpoint list openstack token issue

这里解释一下每条命令的意图:source是加载管理员账号的环境变量,后续openstack命令才能知道去哪个服务端认证;endpoint list是列出各个服务的访问地址,确认地址是否可通;token issue是实际向认证服务申请一个临时令牌,如果这条能成功,说明身份认证链路基本没问题。

我第一次操作时就遇到过这种情况:环境变量里的认证服务地址填的是主机名,但实验环境没有内部DNS解析,结果命令行全部超时。解决办法很简单,查看一下当前环境变量里的URL是不是IP:

env | grep OS_AUTH

如果发现地址不对,直接修改admin-openrc.sh里的OS_AUTH_URL,把它改成管理节点的IP。这个文件通常放在/etc/keystone目录下,改完重新source一次就好。

1.2 服务进程正常,不代表链路正常

平台刚装完的时候,管理页面通常显示所有服务都是正常的,但“进程在跑”和“链路能通”是两件不同的事。我刚开始也天真地以为全部正常,直到创建第一个实例卡在调度阶段,才意识到要主动去验证服务状态。

建议在动手之前跑这两条命令:

openstack compute service list openstack network agent list

第一条看计算服务,第二条看网络插件代理。输出里每一行的第三列是这个服务节点的运行状态,只有显示为UP才是可用状态。如果看到down或者XXX,后面创建实例大概率会出现各种“莫名奇妙”的问题,比如实例一直停留在创建中、虚拟机起来了但没有网络。

平台的教学场景里,经常有同学在实验环境里反复重置节点,到时候某个代理服务没跟着起来是很常见的。所以这里强调一遍:改任何配置前、做任何实验前,先把这两条列表截图或保留输出,后面排错会省很多时间。

2. 网络:实例上不了网,一半的锅都在这里

2.1 先搞清楚你建的是哪种网络

网络配置是整个平台里最容易让人懵圈的部分。实例创建出来拿不到IP、跨节点通信不通、外部访问不了虚拟机,这些问题十有八九都能追溯到网络类型没选对。

常见的网络类型有三种:flat、vlan、vxlan。我用自己的话给你翻译一下:

  • flat网络:相当于一个二层大广播域,打个比方就是把一堆电脑插在同一个交换机上,谁都能直接通信。它的优点是无封装,性能损耗低;缺点是不隔离,适合做连接外部的链路,对外网络一般用它。
  • vlan网络:在二层用802.1Q做了隔离,好比同一栋楼里分出多个房间,每个房间用了不同的门牌号。它需要交换机配置配合,适合有真实网络设备的机房。
  • vxlan网络:用隧道封装实现隔离,相当于把不同楼层的房间通过一条虚拟走廊连起来。它不受物理交换机VLAN数量限制,适合多租户环境,但需要注意MTU,否则大包会被分片。

实验环境里通常至少要有两个网络:外部网络和内部网络。我自己的做法是,外部网络用flat类型,对应管理节点上物理网卡所在的那个物理网络,内部网络用vlan或vxlan,专门让实例之间的流量走这里。

创建外部网络的命令一般长这样:

openstack network create --share \ --provider:physical_network physnet1 \ --provider:network_type flat ext-net

这里有两个参数特别容易踩坑。第一个是--share,表示这个网络可以被所有项目共用;如果不加,你可能在另一个项目里根本看不到这个网络。第二个是--provider:physical_network physnet1,它必须与底层配置文件里设置的物理网络名称完全一致。比如配置里写的是physnet2,你这里写成physnet1,创建不会报错,但后面实例上网就会变得时好时坏,日志里会有“Unknown physical network”的报错。

2.2 子网、网关和地址池到底怎么填

网络创建完,下一步是创建子网。这里涉及三个核心概念:网段、网关、地址池。

openstack subnet create --network ext-net \ --subnet-range 192.168.20.0/24 \ --gateway 192.168.20.1 \ --allocation-pool start=192.168.20.20,end=192.168.20.250 \ --dns-nameserver 223.5.5.5 ext-subnet

这段命令含了几个关键决策点:

  • --subnet-range是子网整体范围,决定了你能用多少个IP;
  • --gateway是网关地址,负责把出去的流量交给路由器;
  • --allocation-pool指定DHCP从哪个范围分配IP,这个范围要刻意跳过网关和静态主机地址。

我最初建地址池的时候,贪省事写成了start=192.168.20.1,结果192.168.20.1被动态分配给了某台实例,网关没人用了,网络一片混乱。后来改成start=192.168.20.20才恢复正常。其实网关和地址池不重叠,这是网络规划的基本纪律。

DNS服务器可以按实验环境选,如果一个网络既承担外网访问又承担内网解析,建议填一个你能确定的公共DNS地址,比如223.5.5.5,至少保证实例里面有域名解析能力。

2.3 内部网络、路由器和接口

有了外部网络还不够,实例一般要放在内部网络里,通过网络路由器连接到外部网络。创建流程并不复杂:

openstack router create router-test openstack router set router-test --external-gateway ext-net openstack network create inner-net openstack subnet create --network inner-net \ --subnet-range 10.0.2.0/24 \ --gateway 10.0.2.1 inner-subnet openstack router add subnet router-test inner-subnet

为什么实例的网关是10.0.2.1而不是外部网络的192.168.20.1?因为底层有一台虚拟路由器在做地址转换,实例访问外网时,数据包会先到路由器,再由路由器把源地址换成外部网络的IP送出去。这个转换过程可以简单理解成小区门卫帮你转交快递:寄件人写的自己的名字,门卫会把发件人统一改成小区地址。

验证路由器是否正常工作,可以用这个命令看底层命名空间:

openstack router show router-test ip netns list

如果路由器创建成功,ip netns list里会看到和路由器关联的命名空间。如果你看不到,说明路由代理没有正常工作,网络功能基本不可用。

3. 实例创建:从镜像到云主机的完整链路

3.1 上传镜像:qcow2好还是raw好

网络结构理清了,接下来才轮到创建实例。实例的第一步是镜像。先电环境里默认给的镜像格式一般是qcow2,这个选择不是没有原因的。

qcow2格式的镜像是稀疏文件,就是说它只占用实际数据大小的磁盘空间。比如一个镜像文件名义上是10GB,但里面装完系统可能只有1.8GB,放到本地磁盘就只占1.8GB。raw格式是完整裸数据,创建多大就占多大,虽然读取性能稍好一点,但在实验环境里会快速耗尽存储。

上传镜像的命令:

openstack image create --public \ --disk-format qcow2 \ --container-format bare \ --file /opt/images/centos7.qcow2 \ CentOS-7-Test

--container-format bare表示镜像没有封装格式,是最常见的上传方式。上传完成后一定要看状态:

openstack image list

只有显示active才是可用,如果显示saving或者error,多半是存储节点空间不够或镜像文件损坏,需要重新上传。

3.2 Flavor、安全组和创建实例的关键参数

镜像准备好后,需要选择实例规格。先电平台的管理页面里一般已经预置了几种Flavor,但命令行方式创建更可控。我习惯先自己建一个:

openstack flavor create --ram 4096 --disk 40 --vcpus 2 m2.medium

这个是2核4G内存40G磁盘的规格,适合跑普通的业务镜像。选规格不是越大越好,要看你实验环境的物理资源。如果节点只有32G内存,你却一次性创建十台8G内存的实例,调度器会把节点资源耗尽,后面的实例一直处于创建中,这是很多新手搞不清的“资源超分”问题。

安全组也是新手最容易忽略的部分。平台默认的安全组会拒绝外部访问实例,如果不放行ICMP和SSH,实例就算有IP也ping不通、ssh不上:

openstack security group rule create --proto icmp default openstack security group rule create --proto tcp --dst-port 22 default

这两条命令是给默认安全组放行ping和22端口。注意,这里只放行了从外面进来的访问,如果你的业务还要用80、443等端口,记得一并加进去。

正式创建实例的命令:

openstack server create --flavor m2.medium \ --image CentOS-7-Test \ --network inner-net \ --security-group default \ --wait test-vm

加上--wait之后,命令会一直等待实例状态变为ACTIVE才返回。如果出现ERROR,多半是镜像格式不对、计算资源不足或网络创建有问题。创建完成后立刻用openstack server list查看状态。

3.3 实例ssh不通,先别乱重启

实例状态显示ACTIVE,并不代表你就能ssh上去。这个判断过程我建议按顺序排查,不要上来就重启实例。

第一步,先ping一下实例的浮动IP或内部网关,确认二层和三层联通性。ping不通的情况下,要区分是外网访问不到还是实例内部网络问题。

第二步,查看实例的控制台输出日志:

openstack console log show test-vm

如果日志里能看到网卡启动了但没有获取到IP,基本可以肯定是DHCP环节出了问题,重点检查DHCP代理和子网地址池。

第三步,确认你有没有给实例绑定浮动IP。内部网络的IP是无法直接从外部访问的,你需要先创建一个浮动IP并绑定到实例:

openstack floating ip create ext-net openstack server add floating ip test-vm <浮动IP>

浮动IP本质上就是在路由器上做一个端口转发,把外部IP映射到内部实例IP。如果你发现外网可以ping通外部网关地址,但怎么都联系不上实例,多半就是这一步漏了。

4. 存储:卷操作是慢功夫

4.1 卷创建和后端选择

实例有临时磁盘,但临时磁盘的生命周期跟实例绑定,实例删除数据就没了。想要持久化,就得用块存储卷。先电环境的默认后端一般是LVM,也就是在存储节点上创建一块逻辑卷提供给实例使用。你也可以在平台上看到其他后端选项,比如NFS,适合共享文件场景,但性能通常不如本地LVM。

创建卷的命令:

openstack volume type list openstack volume create --size 10 --type 普通卷>openstack server add volume test-vm>lsblk fdisk /dev/vdb

fdisk里依次执行n创建分区、w保存。然后格式化并挂载:

mkfs.xfs /dev/vdb1 mkdir -p /mnt/data mount /dev/vdb1 /mnt/data

关于是否分区,我的经验是不要偷懒直接整盘格式化。分区之后,后续扩容和快照处理都更灵活,而且文件系统大小和分区表对齐也更清晰。

这里有个新手特别容易翻车的点:写/etc/fstab永久挂载时抄错UUID。实例重启时会因为找不到挂载设备,直接卡在启动流程或者进入紧急模式。正确做法是先用blkid拿到分区的UUID,再把挂载表写好:

blkid /dev/vdb1
UUID=xxxx-xxxx-xxxx /mnt/data xfs defaults 0 0

写完之后,建议先执行mount -a测试一遍,确认无误再重启。

4.3 扩容与快照

卷扩容是块存储的高频操作。比如原来10GB的卷不够用了,想扩到20GB:

openstack volume set --size 20>growpart /dev/vdb 1 xfs_growfs /mnt/data

如果是ext4文件系统,用resize2fs /dev/vdb1。注意,有些环境不允许在线扩容,强行扩会报错。稳妥的做法是先把卷从实例上卸载,扩容完成后再重新挂载,或者干脆先打个快照再操作。

快照也是存储里必练的技能。卷快照命令:

openstack volume snapshot create --volume>openstack server image create --name test-vm-bak --wait test-vm

这里有一条个人经验:对运行中的实例直接做快照,得到的镜像可能不是完全一致的,内存里的数据并没有被完整保存。所以重要业务要打快照时,我习惯先停掉实例或者至少把服务停一会儿再做,虽然麻烦,但恢复时真正能用的概率高很多。如果条件不允许停机,也要保证业务数据已经落盘,不要只依赖实例快照。

5. 排障实录:我记下来的问题,你大概率也会碰上

5.1 问题速查表

这一个星期里,我把实际遇到的问题整理成一张表。遇到故障时,先对照一下现象,能省掉很多盲目尝试的时间。

现象可能原因验证手段解决办法
管理页面打不开或空白Web服务或认证服务异常systemctl status httpd;检查认证服务日志重启对应服务,查看认证服务日志定位
实例一直处于创建中计算资源不足、调度失败、磁盘空间不够openstack compute service list;查看计算节点日志清理节点磁盘,调整Flavor规格,修复计算服务状态
实例卡在spawning镜像数据未完全复制到计算节点查看计算服务日志等待镜像转换完成,或重新上传镜像
实例创建成功但ping不通安全组未放行ICMP、浮动IP未绑定、网络类型不匹配openstack security group rule list;openstack floating ip list放行ICMP端口,绑定浮动IP,检查网络类型
能ping通但ssh不上安全组未放行22端口,镜像内sshd未启动查看控制台日志放行TCP 22端口,或重置root密码
外部网络不通路由器接口未配置、物理网络名不匹配openstack router show;查看网络日志重新配置路由器接口,修改物理网络名
DHCP获取不到地址DHCP代理未运行、地址池耗尽openstack network agent list;查看DHCP日志启动代理,扩展地址池
卷创建一直处于creatingcinder卷服务异常、后端空间不足openstack volume service list;查看存储日志重启卷服务,释放后端磁盘空间
卷扩容不生效文件系统未扩展lsblk;df -h在实例内执行扩容命令
服务状态显示down节点宕机、服务未启动openstack compute service list登录对应节点,重启对应服务

5.2 按顺序排错,不要一上来就重启

排查问题最好遵循一个固定套路:先看服务状态,再看日志,最后才碰配置和重启。

第一步,查看关键服务状态:

systemctl status httpd mariadbrabbitmq-server memcached

按实际情况替换服务名,比如在存储节点上要看存储卷服务的状态,在网络节点上看网络代理服务状态。

第二步,按照组件查日志。平台各服务的日志路径一般是固定位置,我列一下常用的:

组件日志路径
认证服务/var/log/keystone/keystone.log
计算服务/var/log/nova/nova-compute.log
网络服务/var/log/neutron/network-agent.log
存储服务/var/log/cinder/cinder-volume.log
镜像服务/var/log/glance/api.log

用tail -100查看最新的错误信息:

tail -100 /var/log/nova/nova-compute.log

日志里通常直接写着失败的完整堆栈和触发条件。我见过很多人一遇到问题就先重启实例,重启后日志被覆盖,现场被破坏,问题也没解决,反而变成“重启了好多次但还是报错”的玄学状态。先看日志再动手,是运维最基本的原则。

第三步,想一下改动过什么。配置变更、清理文件、添加资源,这些操作都会有痕迹。回滚之前的改动,往往比重新安装配置快得多。

5.3 巡检脚本化,十分钟搞定日常检查

平台用久了,我建议把日常巡检脚本化。不需要复杂的监控,两三条命令就够了:

openstack token issue openstack compute service list openstack network agent list openstack volume service list

把这几条命令写进脚本里,每次实验前跑一遍,输出文件保留日期后缀。只要看到所有列表里的服务状态都是UP,基本可以放心往下走。如果某列为down或XXX,再按前面5.2的顺序定位。

我自己的习惯是把巡检输出重定向到一个文件里:

openstack compute service list > /tmp/inspect-$(date +%Y%m%d).txt

这样出问题的时候,能直接对比“昨天正常时”和“现在异常时”的输出差异,快速锁定是哪台节点在什么时间点出了状况。

我在这次连续几天的操作里,最大的体会是先电平台的上手门槛不算高,但如果你只依赖图形界面的提示,很多问题会变成“玄学”。反而后来所有操作我都保留命令行记录,等再次遇到问题时,不用回忆就能直接翻记录定位。最后再分享一个小技巧:给所有网络、路由器、卷这些资源的名字加上日期前缀,比如netext-0716、vol-data-0718。测试环境里这类资源特别多,如果全部叫test,过几天你根本分不清谁是谁,到时候排查问题就会多花好几倍时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询