
1. 从ISO镜像到可用实例整体设计思路拆解在私有云运维的日常里用ISO镜像装虚拟机这件事说简单也简单说坑多也是真多。很多刚接触OpenStack的朋友习惯了在虚拟化平台里点几下就装完系统结果到了OpenStack这边上传ISO、配卷、挂载、引导、装系统、再卸载ISO一套流程走下来中间任何一步没配对虚拟机就卡在BIOS界面或者直接进不了安装程序。我前后在几个不同规模的环境里做过这件事踩过的坑足够写一篇避雷指南所以这篇就把从ISO创建虚拟机的完整链路拆开讲清楚。先明确一下这个操作到底在做什么。OpenStack本身是一个云操作系统它管理的是计算、存储、网络这些资源池。默认情况下它最擅长的是用现成的镜像qcow2、raw这类快速批量创建虚拟机因为这种镜像里已经装好了系统开机即用。但现实场景里你经常需要从ISO开始装系统比如要装一个特定版本的操作系统、要做自定义分区、要装一些镜像里没有的驱动或者干脆就是想模拟一台物理机的完整安装过程。这时候就需要走ISO引导安装这条路。这个内容适合谁看如果你已经能登录OpenStack的Dashboard或者会用命令行知道什么是flavor、什么是volume、什么是network那这篇就是给你准备的实操手册。如果你连项目、用户、配额这些概念都还没搞明白建议先把基础操作过一遍再回来不然中间很多步骤你会不知道为什么这么做。核心思路其实一句话就能概括把ISO当成一张光盘把虚拟机的系统盘当成一块空白硬盘让虚拟机先从光盘启动装系统装完之后再把光盘拔掉从硬盘启动。听起来跟给物理机装系统一模一样对吧OpenStack里也是这个逻辑只不过“光盘”和“硬盘”都是虚拟的需要通过卷Volume和镜像Image来模拟。这里有个关键的设计选择需要提前想清楚系统盘到底用本地盘还是云硬盘Cinder卷这个选择会直接影响你后续的操作路径。用本地盘的话虚拟机实例的根盘是临时的实例删了系统就没了而且没法做快照和迁移用Cinder卷的话系统盘是持久化的可以快照、可以迁移、可以随时挂载到别的实例上排查问题。从ISO安装这个场景我强烈建议用Cinder卷原因后面会详细说因为ISO安装过程中需要多次挂载和卸载用卷操作起来灵活得多。还有一个前置条件容易被忽略你的OpenStack环境得支持从卷引导。有些老版本或者配置不完整的环境Cinder卷只能作为数据盘挂载不能作为启动盘。这个在创建实例的时候就能看出来如果“从卷启动”那个选项是灰的或者创建完直接报错那就是后端存储或者Glance跟Cinder的集成没配好。遇到这种情况要么找管理员确认配置要么就只能退而求其次用本地盘方案。2. 核心细节解析与实操要点2.1 ISO镜像的上传与格式要求第一步是把ISO文件弄进OpenStack。这里有个常见的误解很多人以为ISO要像qcow2镜像那样上传到Glance然后直接拿它创建实例。实际上ISO在Glance里就是一个普通镜像但它的用途是作为“光盘”挂载而不是作为启动盘直接引导。上传的时候有几个参数必须配对否则后面挂载会失败。上传ISO到Glance命令行大概是这样openstack image create ubuntu-22.04-iso \ --file ./ubuntu-22.04.3-live-server-amd64.iso \ --disk-format iso \ --container-format bare \ --public注意--disk-format iso这个参数一定要写对。如果你手滑写成qcow2或者rawGlance虽然能存进去但后面挂载给虚拟机的时候底层驱动会按qcow2去解析这个文件结果就是虚拟机根本认不出这是一张光盘引导直接失败。我见过有人图省事直接写--disk-format raw结果排查了半天才发现是格式标错了。--container-format bare也是必须的ISO文件本身就是裸的不需要额外的容器封装。至于--public还是--private看你的使用范围如果只是自己项目里用private就够了省得污染公共镜像列表。上传完之后用openstack image list确认一下状态是active大小跟你本地文件一致。如果状态一直是queued或者saving那可能是Glance后端存储出问题了得找存储管理员看看。提示ISO文件通常比较大几个GB是常态。上传之前先确认Glance后端的存储空间够不够别传一半空间满了镜像卡在saving状态清理起来很麻烦。2.2 系统盘的创建与参数计算接下来要创建一块空白卷作为虚拟机的系统盘。这块盘的大小怎么定我的经验是ISO里官方推荐的最小磁盘空间再往上加20%到30%的余量。比如Ubuntu Server 22.04官方建议最小25GB那你至少给30GB最好给40GB。因为安装过程中会解压大量文件还要留出swap分区和后续更新的空间给得太紧巴巴的装到一半提示空间不足前功尽弃。创建卷的命令openstack volume create --size 40 --image ubuntu-22.04-iso \ --bootable system-disk-for-vm01这里有个细节--image参数指定ISO镜像--bootable标记这块卷是可引导的。有些版本的OpenStack里--image和--bootable要配合使用意思是“这块卷从指定的镜像引导”。但注意这里指定的镜像其实是ISO所以这块卷在创建的时候会被写入ISO的内容吗不是的它只是把卷标记为“可以从这个镜像引导”实际引导的时候ISO是作为光盘挂载的卷本身还是空的。这个逻辑有点绕但理解这一点很重要因为它决定了你后面挂载和卸载ISO的操作方式。如果你用的是Dashboard操作路径是卷 - 创建卷 - 在“卷来源”里选择“镜像”然后选中你上传的ISO勾选“可引导”。大小填40GB。创建完之后等状态变成available。2.3 实例的创建与引导顺序设置卷创建好之后就可以创建实例了。这里的关键是引导顺序。在OpenStack里创建实例的时候可以指定从哪个设备引导。如果你用命令行大概是这样openstack server create --flavor m1.medium \ --volume system-disk-for-vm01 \ --network private-net \ --key-name mykey \ vm01注意--volume参数它把刚才创建的卷作为启动盘挂给实例。但这时候有个问题卷里是空的ISO虽然标记在卷上但实际引导的时候虚拟机需要先从ISO启动。OpenStack的默认行为是如果卷是从ISO创建的它会自动把ISO作为光盘挂载并且引导顺序会优先从光盘启动。但这个行为在不同版本里表现不一样有的版本需要你手动指定。更稳妥的做法是创建实例的时候先不挂ISO而是创建一个带空卷的实例然后手动把ISO挂载上去再重启实例在启动过程中进入BIOS或者引导菜单选择从光盘启动。但这样操作太繁琐而且很多OpenStack环境不允许你直接访问虚拟机的BIOS界面。所以实际生产里我推荐的做法是创建卷的时候就把ISO关联上创建实例的时候直接用这块卷OpenStack会自动处理引导顺序。如果创建完实例发现直接进了BIOS或者提示“no bootable device”那说明引导顺序不对需要检查一下卷的bootable标记和镜像关联是否正确。2.4 网络与安全组的配置要点网络这块ISO安装过程中通常需要联网下载一些额外的包所以实例得能访问外网。如果你用的是私有网络记得把路由和NAT配好让实例能通过路由器访问外部网络。安全组方面安装过程中可能需要SSH或者HTTP访问但默认的安全组通常只开了SSH。如果你在安装过程中需要从外部访问虚拟机的Web控制台那还得开对应的端口。不过说实话ISO安装阶段最方便的还是通过VNC或者SPICE直接看虚拟机的控制台这样不需要额外开端口直接在Dashboard里就能操作。OpenStack的Dashboard里实例详情页有个“控制台”标签点进去就能看到虚拟机的屏幕跟坐在物理机前面一样。安装系统的时候用这个最省事。注意VNC控制台在安装过程中可能会因为网络延迟或者浏览器兼容性问题卡顿建议用Chrome或者Firefox别用那些小众浏览器。如果控制台一直黑屏先检查实例状态是不是ACTIVE再看VNC代理服务是不是正常。3. 实操过程与核心环节实现3.1 完整操作流程拆解下面我把整个流程按顺序走一遍你可以直接照着做。假设你已经有了OpenStack的访问权限命令行工具也配好了。第一步上传ISO到Glance。openstack image create centos-7-iso \ --file ./CentOS-7-x86_64-Minimal-2009.iso \ --disk-format iso \ --container-format bare \ --private上传完成后确认状态openstack image show centos-7-iso -c status -c size状态应该是activesize跟你本地文件大小一致。第二步创建可引导的空白卷。openstack volume create --size 50 --image centos-7-iso \ --bootable centos7-system-disk等卷状态变成availableopenstack volume show centos7-system-disk -c status第三步创建实例并挂载卷。openstack server create --flavor m1.large \ --volume centos7-system-disk \ --network private-net \ --security-group default \ --key-name mykey \ centos7-vm创建完之后用openstack server list看实例状态应该是ACTIVE。如果状态是ERROR用openstack server show centos7-vm看fault信息通常是卷挂载失败或者flavor资源不足。第四步通过控制台安装系统。在Dashboard里找到这个实例点“控制台”应该能看到CentOS的安装界面。如果看到的是“no bootable device”或者直接进了BIOS说明引导顺序不对。这时候需要检查卷的bootable标记或者手动把ISO挂载为光盘。手动挂载ISO的命令openstack server add volume centos7-vm centos-7-iso --device /dev/sr0然后重启实例openstack server reboot --hard centos7-vm重启的时候盯着控制台应该能看到从光盘引导的提示。如果还是不行可能需要在创建实例的时候指定引导顺序但这个操作在不同OpenStack版本里差异很大有的版本支持--boot-from-volume参数有的版本需要在Nova的配置里改。第五步安装完成后卸载ISO。系统装完之后虚拟机会自动从硬盘重启。这时候ISO还挂载着虽然不影响使用但最好卸载掉免得下次重启又从光盘引导。openstack server remove volume centos7-vm centos-7-iso卸载完之后再重启一次实例确认能从硬盘正常引导。3.2 参数计算与选择依据整个流程里有几个参数需要你根据实际情况算一下。卷的大小前面说了官方最小要求加20%到30%。但如果你要装图形界面或者大量开发工具那得再加。比如CentOS 7 Minimal官方建议最小10GB但你如果要装GNOME桌面至少得20GB起步。我的经验是开发测试环境给40GB生产环境给60GB到100GB具体看你的应用需求。flavor的选择ISO安装过程中对CPU和内存的要求比正常运行时要高因为安装程序本身要解压大量文件。建议至少2核4GB起步如果ISO比较大或者要装图形界面4核8GB更稳妥。安装完之后你可以再调整flavor但注意OpenStack默认不支持在线调整flavor需要关机再改。网络带宽如果你是从外部上传ISO到Glance那上传速度取决于你的网络带宽。一个4GB的ISO在100Mbps的网络上大概要传5到6分钟。如果Glance后端是分布式存储上传过程中可能会有额外的网络开销时间会更长。3.3 实操现场记录与关键截图说明由于这里没法贴图我用文字描述一下关键界面的样子你操作的时候可以对照。Glance镜像列表上传成功后镜像名称旁边会显示“active”大小显示为ISO的实际大小比如“4.2 GB”。如果显示“queued”说明还在上传中如果显示“error”点进去看错误信息通常是存储后端的问题。卷列表创建完卷之后卷的状态是“available”大小显示为你指定的大小比如“50 GB”。如果状态是“creating”等一会儿刷新如果状态是“error”看错误信息可能是Cinder后端存储空间不足。实例控制台安装界面出现后你会看到ISO的引导菜单比如CentOS的“Install CentOS 7”或者Ubuntu的“Try or Install Ubuntu Server”。用键盘方向键选择回车进入安装程序。安装过程中分区那一步建议选“自动分区”除非你有特殊需求。如果选手动分区记得给/boot至少1GB/至少20GBswap根据内存大小定一般内存的1到2倍。安装完成后的重启安装程序会提示你重启重启的时候注意看屏幕如果又出现了“Press any key to boot from CD”千万别按键等它自己跳过从硬盘引导。如果按了键又会进安装程序那就白装了。4. 常见问题与排查技巧实录4.1 引导失败类问题排查问题一创建完实例控制台显示“no bootable device”。这是最常见的问题。原因通常是卷没有正确标记为可引导或者ISO没有正确挂载为光盘。排查步骤检查卷的bootable属性openstack volume show volume-id -c bootable应该是True。检查卷关联的镜像openstack volume show volume-id -c image_id应该是ISO的镜像ID。检查实例挂载的卷openstack server show server-id -c volumes确认系统盘挂载在/dev/vda或者/dev/sda。如果以上都正常尝试手动挂载ISO为光盘openstack server add volume server-id iso-image-id --device /dev/sr0然后硬重启。问题二控制台显示“Booting from Hard Disk”但硬盘是空的。这说明引导顺序错了虚拟机直接从硬盘引导但硬盘里没系统。解决办法是进入BIOS调整引导顺序但OpenStack里通常没法直接进BIOS。替代方案是在创建实例的时候指定引导顺序或者用--boot-from-volume参数强制从卷引导。如果这些都不行那就只能删掉实例重新创建创建的时候确保ISO已经正确关联到卷上。问题三安装过程中提示“Unable to find a medium containing a live file system”。这是Ubuntu ISO常见的问题通常是因为ISO挂载的设备不对。Ubuntu的安装程序会去找包含casper目录的设备如果ISO挂载在/dev/sr0但安装程序没认出来就会报这个错。解决办法是在引导菜单里按e编辑引导参数把cdrom相关的路径改对或者干脆换一个ISO版本试试。我遇到过几次换成Server版而不是Live版就好了。4.2 性能与资源类问题问题四安装过程特别慢进度条半天不动。可能的原因有几个一是Cinder后端存储性能差读写速度跟不上二是网络带宽不够安装程序在下载额外的包三是flavor给的资源太少CPU跑满了解压速度慢。排查的时候先在Dashboard里看实例的CPU和内存使用率如果CPU一直100%那就是资源不够关机改flavor。如果CPU不高但磁盘IO很高那就是存储性能问题找存储管理员确认后端是不是机械盘或者网络存储延迟大。问题五安装完成后实例启动特别慢或者卡在某个服务上。这通常是系统盘的问题。用Cinder卷做系统盘IO性能取决于后端存储。如果后端是机械盘或者低端网络存储系统启动会比本地盘慢很多。我的经验是生产环境尽量用SSD或者高性能分布式存储做Cinder后端不然装完系统用起来也难受。如果实在没法改存储那就只能忍或者在创建实例的时候用本地盘做系统盘但那样就失去了持久化和迁移的能力。4.3 常见问题速查表问题现象可能原因排查命令解决办法控制台显示“no bootable device”卷未标记可引导或ISO未挂载openstack volume show id -c bootable重新创建卷并确保--bootable和--image参数正确直接从硬盘引导但硬盘为空引导顺序错误openstack server show id -c volumes手动挂载ISO为光盘并硬重启安装程序找不到ISO介质ISO挂载设备不对在控制台查看挂载点编辑引导参数或更换ISO版本安装过程极慢存储性能差或资源不足查看实例CPU和磁盘IO改flavor或更换存储后端安装完成后无法从硬盘引导ISO未卸载或引导顺序未恢复openstack server show id -c volumes卸载ISO并重启实例卷创建失败Cinder后端空间不足openstack volume show id -c status清理无用卷或扩容后端存储4.4 独家避坑技巧技巧一先用小ISO测试流程。如果你第一次做这个操作别上来就拿几十GB的ISO试。找一个几百MB的轻量级Linux发行版比如Alpine或者Tiny Core先把整个流程跑通确认引导、挂载、安装、卸载都没问题再换正式ISO。这样能省很多时间因为大ISO上传和安装都慢出错了排查也费劲。技巧二安装过程中别关控制台。有些人习惯开着控制台然后去干别的结果回来发现控制台断开了安装卡在某个交互界面等输入。OpenStack的VNC控制台在长时间无操作后可能会断开虽然虚拟机本身还在跑但你没法看到界面也没法输入。所以安装过程中最好保持控制台窗口活跃或者用openstack console log show看日志确认进度。技巧三装完系统先别急着卸载ISO。系统装完第一次重启后确认能正常登录了再卸载ISO。因为有时候系统装完但引导记录没写对卸载ISO后直接起不来还得重新挂载ISO进救援模式修复。多挂一会儿不碍事确认没问题了再卸。技巧四用卷快照做备份。系统装好之后第一时间给卷做个快照。这样以后装坏了或者要批量部署直接从这个快照创建新卷就行不用每次都从头装。快照命令openstack volume snapshot create --volume volume-id snapshot-name。恢复的时候用openstack volume create --snapshot snapshot-id new-volume-name。技巧五注意时区和键盘布局。安装过程中时区和键盘布局这两个选项很容易被忽略但装完之后再改就麻烦了。特别是键盘布局如果你选错了后面输密码的时候会发现打出来的字符跟预期不一样登录都登不进去。安装的时候花几秒钟确认一下省得后面折腾。5. 批量部署与自动化扩展思路单台从ISO装系统搞定了接下来自然会想能不能批量做。答案是能但需要一些额外的工具和脚本。OpenStack本身提供了Heat编排服务你可以写一个Heat模板把上传ISO、创建卷、创建实例、挂载ISO这一系列操作串起来一键部署多台。但Heat模板写起来比较繁琐而且调试麻烦对于偶尔用一次的场景有点杀鸡用牛刀。更轻量的做法是用命令行脚本。把前面那些命令写成一个bash脚本用循环创建多台实例。但注意ISO安装过程中需要人工交互脚本没法自动完成分区、设置密码这些步骤。所以批量部署的场景通常不是从ISO装而是先手工装好一台做成镜像然后用这个镜像批量创建实例。这才是OpenStack的正确用法。如果你确实需要批量从ISO装那可以考虑用Kickstart或者Preseed做自动化安装。CentOS系用KickstartUbuntu系用Preseed把安装配置写成一个文件放在HTTP服务器上ISO引导的时候指定这个文件的URL安装程序就会自动完成所有步骤不需要人工干预。这样配合脚本就能实现批量部署。但配置Kickstart文件本身也需要不少时间适合有长期批量需求的场景。提示Kickstart和Preseed的配置文件里可以指定分区方案、软件包列表、网络配置、用户密码等。写的时候注意密码要用加密后的哈希值别直接写明文。生成哈希可以用openssl passwd -6命令。6. 个人实操体会与后续扩展这套流程我在不同环境里跑过很多次最大的体会是OpenStack从ISO装虚拟机的难点不在命令本身而在环境配置和引导顺序。命令就那么几条背都背下来了但环境里任何一个环节没配好比如Cinder后端不支持可引导卷、Glance镜像格式不对、Nova引导顺序配置有问题都会让你卡住。所以遇到问题的时候别急着怀疑自己的操作先确认环境是不是支持这个用法。另一个体会是能不用ISO就不用ISO。如果你的需求只是装一个标准系统那直接找一个现成的qcow2镜像上传到Glance创建实例的时候选这个镜像几十秒就能起来比ISO安装快得多也稳得多。ISO安装适合那些确实需要自定义分区、需要特定驱动、或者需要模拟完整安装过程的场景。日常运维里大部分情况用现成镜像就够了。后续如果要把这个流程产品化可以考虑做成一个自服务门户让用户填几个参数ISO选择、卷大小、flavor、网络后台自动完成剩下的步骤。这样不懂OpenStack命令的人也能用。但要注意ISO安装过程中还是需要人工交互所以门户里得集成VNC控制台让用户能直接操作安装界面。这个集成工作量不小但做一次能省很多重复劳动。最后分享一个小技巧如果你经常需要从ISO装系统可以准备一个“万能”ISO里面集成常用的驱动和工具然后把这个ISO做成Glance里的公共镜像所有人共享。这样不用每个人都上传一遍ISO省存储空间也省时间。ISO的定制可以用mkisofs或者genisoimage工具把额外的文件追加进去具体方法这里就不展开了有需要的可以自己查一下。