C25

OpenStack

点击正文段落选定收藏或划线位置;未选定时使用屏幕内第一段。

课内目录

1 OpenStack 要回答什么

假设你要为门店部署订单 API。程序已经能在开发电脑上接收订单,但生产环境还需要虚拟机、地址、访问规则和保存数据的磁盘。如果每次发布都让管理员手工创建虚拟机、接网线、登记磁盘,交付速度就取决于工单流转,资源归属也很难核对。OpenStack 要回答的问题是:怎样把计算、网络和存储资源变成可授权、可申请、可查询、可回收的基础设施服务。

OpenStack 是由多项服务协作组成的开源云基础设施软件,常用于建设 IaaS 平台。它不是安装在虚拟机里的业务框架,也不是某种虚拟化技术的别名。虚拟化负责让物理服务器运行虚拟机;云控制平台还要决定谁能申请、申请多少、放到哪里,以及相关网络和存储怎样准备。底层可以采用不同的虚拟化、网络和存储实现,平台暴露的资源概念仍可保持相对稳定。

在订单 API 的例子里,开发团队提出需求:创建 2 台应用实例,每台使用 2 个虚拟 CPU、4 GiB 内存,放到指定网络,并允许入口访问应用端口。平台把这些需求转换成资源操作。团队得到实例标识、地址和状态,能够继续部署应用。这里的虚拟 CPU 数量描述实例规格,不代表应用独占了相同数量的物理核心;具体性能还取决于宿主机和资源共享策略。

租户隔离通常围绕项目展开。项目把资源归属、配额和授权范围组织起来,用户或自动化账号在项目内执行被允许的操作。项目不是天然隔绝所有风险的物理围墙:网络连通、存储权限和管理员权限仍须分别配置。对初学者,更实用的理解是“资源有归属,动作要授权,用量有上限”,不要把控制台里的目录结构当成完整的安全模型。

OpenStack 为订单 API 提供的资源与责任边界
OpenStack 为订单 API 提供的资源与责任边界

云平台交付资源,不等于替团队完成业务运行。操作系统更新、应用启动、数据库恢复、容量规划和业务告警都需要明确责任人。有些平台会额外提供托管服务,但不能因为使用 OpenStack 就默认这些能力存在。学习本课时,我们把目标限定为理解基础设施控制面,能够追踪资源申请,并判断平台故障究竟影响创建、访问还是数据持久性。

2 控制面、计算与网络服务边界

控制面负责接收意图、检查权限、记录状态并协调执行。数据面承载实际业务流量与数据读写。用户调用创建实例 API 属于控制面操作,顾客通过网络请求订单 API 属于业务数据路径。这 2 条路径会共享部分基础设施,却有不同的依赖。某个创建接口失效时,已运行实例可能继续提供服务;网络转发中断时,控制台也可能仍然能正常打开。

先认识各服务的职责,暂不展开内部进程。Keystone 提供身份认证、令牌及服务目录等能力;Nova 管理计算实例生命周期;Glance 管理镜像目录和访问;Neutron 管理网络、子网、端口等网络资源;Cinder 管理块存储卷。这些名称代表服务边界,不要求每项服务各占 1 台服务器。部署方式会改变,责任边界仍然值得保留。

Nova 需要决定实例放在哪个计算节点,并让节点准备虚拟机。调度过程中通常会借助 Placement 查询和分配资源。Placement 关注资源供给与分配记录,不替代宿主机上的真实执行,也不负责保证应用健康。可以把调度理解为“根据条件找位置”,把计算节点理解为“在选定位置执行创建”。选到了位置,不表示镜像、网络和磁盘已经全部可用。

Neutron 的网络对象同样需要落地。网络与子网描述连接范围和地址规则,端口代表实例等设备接入网络的位置。平台还可能提供路由器、浮动 IP 等资源。端口对象创建成功,只说明控制面接受并记录了配置;底层网络实现还需要把配置应用到实际转发路径。不同部署可能采用不同后端,因此不能仅凭某个固定进程名称判断所有 OpenStack 网络故障。

身份、计算、网络与存储服务的协作边界
身份、计算、网络与存储服务的协作边界

这些服务经常依赖数据库、消息系统和内部 API。数据库保存资源及任务状态,消息系统传递某些异步工作。RabbitMQ 是常见的消息中间件选择,但并非每次 API 请求都会以相同方式经过它,也不是业务流量必须穿过的转发设备。运维时要问“这项动作依赖哪条调用或消息路径”,不能把所有服务连成没有方向的依赖清单。

订单 API 的请求通常先经过业务入口,再到实例,最后访问数据库。顾客每提交 1 个订单,并不必然触发 Nova 创建操作。把业务请求路径与资源管理路径分别画出,才能解释为什么平台 API 恢复之后,还要继续验证实例网络与业务读写;也能解释为什么平台升级应评估创建和扩容能力,而不只是检查当前页面是否可访问。

3 镜像、卷与安全组的职责

镜像回答“实例从什么软件起点启动”。它通常包含操作系统及预装软件,也可能包含启动配置所需的基础组件。Glance 管理镜像元数据及其访问,镜像数据的实际保存方式取决于部署。镜像不是正在运行的机器,也不会持续自动吸收实例内的新文件。团队应记录镜像标识和版本,避免把可重复发布建立在“管理员记得上次装了什么”之上。

启动实例时,根磁盘可以来自镜像创建的临时存储,也可以使用可启动卷。临时磁盘与实例生命周期紧密相关,删除实例可能导致其中的数据丢失;持久卷则有独立生命周期,但也可能被配置为随实例删除。判断数据能否保留,必须核对实际删除策略。仅看到磁盘出现在实例内,无法判断它属于哪类资源,更不能据此承诺订单数据不会丢失。

卷回答“需要持续保存的块设备在哪里”。Cinder 为实例提供卷的创建、连接等管理能力,后端存储负责承载实际数据。卷呈现给操作系统后,文件系统、数据库写入和一致性仍由上层处理。卷快照可以作为恢复手段的组成部分,却不能在任意时刻自动保证数据库事务一致。备份需要说明一致性方法、保存位置、保留时间,以及怎样通过恢复验证它确实可用。

订单 API 若把正式订单写入数据库,应用实例可以尽量保持可替换。应用日志也不应只留在随实例删除的磁盘里。用于演示的数据库可以连接独立卷,但生产方案还需考虑数据库自身的复制和恢复。增加 1 块卷不会自动形成高可用数据库;卷故障、文件系统损坏和误删除也属于不同故障,需要不同保护措施。

镜像、实例磁盘、持久卷与安全组各自解决的问题
镜像、实例磁盘、持久卷与安全组各自解决的问题

安全组回答“哪些流量可以到达关联端口”。在常见配置下,它通过带状态的规则控制网络访问,具体能力应以平台后端和配置为准。可让入口所在安全组访问应用的 TCP 8080 端口,并只允许运维来源访问管理端口。规则要同时考虑方向、协议、端口和来源范围。直接向所有地址开放全部端口,会使资源申请很方便,却破坏了原本希望建立的访问边界。

安全组不会验证订单接口的登录态,也不等于加密、备份或漏洞修复。访问失败时,还要检查路由、地址、操作系统防火墙和进程监听地址。浮动 IP 用于把外部可达地址映射到相关内部端口,它不代表应用必然可访问;没有浮动 IP 的实例也可能通过负载入口或其他网络连接提供服务。将“镜像决定起点、卷承载数据、安全组约束网络”分别落实,才能避免用错误资源解决问题。

4 动手:追踪一次实例创建的 API 路径

本节的小实验是在已有授权的教学项目里创建 1 台实例,并记录从请求到业务探测的证据。先确认可用镜像、规格、网络、密钥对和最小安全组,再确认配额与清理方式。没有练习环境时,可沿动画整理相同的观察表;不要凭空填写返回值。镜像、网络名称和权限随平台而异,命令中的尖括号是需要替换的占位符。

openstack token issue
openstack quota show
openstack server create --image <镜像标识> --flavor <规格标识> --network <网络标识> --security-group <安全组标识> --key-name <密钥对名称> c25-order-api
openstack server show c25-order-api
openstack port list --server c25-order-api
openstack console log show c25-order-api

认证配置应使用平台提供的安全方式,避免把密码或完整令牌放进课后笔记。令牌查询只是验证当前认证上下文;输出可能包含敏感值。创建操作还需要项目内的相应权限。若收到认证或授权错误,应先核对账号、项目和角色,而不是改动实例规格,或反复提交同样的创建请求。

创建请求进入计算 API 后,会经历参数与权限检查,并协调网络、调度和计算执行等工作。网络准备、存储准备和调度的具体顺序会随启动方式、版本及部署而变化,因此下方动画展示的是职责关系。创建接口返回实例标识,表示已经有可追踪的资源或任务,不表示机器已启动,更不表示订单服务已部署。后续应围绕该标识查询状态,避免把每次刷新都变成新建请求。

从提交请求到业务验证的逻辑路径
从提交请求到业务验证的逻辑路径

观察实例从 BUILD 进入 ACTIVE 或 ERROR,并记录时间。BUILD 通常表示创建相关工作仍在进行;ERROR 表示需要查看故障信息;ACTIVE 表示计算服务记录实例处于运行状态。ACTIVE 无法证明操作系统初始化已经完成。实例可能还在安装软件,也可能没有正确获取地址。控制台日志有助于定位启动问题,但它不是所有配置和故障的完整记录。

随后核对端口地址与安全组,在允许的入口上检查网络连接,最后检查应用健康接口。若健康接口只是固定返回成功,还应增加能够验证关键依赖的检查,例如在专用测试数据范围内完成订单写入和读取。网络能通、进程存活与交易可完成属于不同证据,实验记录应分别写出结果。不要让探测写入真实订单,也不要把敏感业务数据当作排障附件。

请求标识可帮助跨服务关联日志。相关日志可能出现本地请求标识或传播的全局请求标识,实际形式取决于版本与配置;不能假设所有日志都使用完全相同的值。记录时间窗口、项目、实例标识、端口标识及可获得的请求标识,再由平台管理员关联内部日志。练习结束后删除实例,并核查独立卷、端口和浮动 IP 等资源是否按预期释放,避免把“实例列表为空”当成清理完成。

5 配额、调度与故障域取舍

配额解决“这个项目最多可以申请多少”,容量解决“平台实际还有多少可以提供”。项目可能仍有 8 个虚拟 CPU 配额,但符合条件的宿主机没有足够内存;平台也可能很空闲,项目却已达到实例数量上限。这 2 种情况的处理方向不同。提高配额不能制造物理资源,添加宿主机也不会自动提高项目的资源使用上限。

调度还会考虑资源类型和放置约束。总内存够用,不代表任意规格都能放下;可用资源可能分散在多台宿主机,也可能不满足镜像、设备或运维策略要求。初学阶段无需记住具体调度过滤器,应先学会把问题分成“是否获准申请”“是否存在合适位置”“选定位置是否执行成功”。缺少合适宿主机的提示只是结果,还需要结合申请条件与资源记录寻找原因。

用简化模型观察取舍:有 4 台宿主机,每台 64 GiB 内存,其中 16 GiB 留给宿主机及管理开销。每台订单实例需要 8 GiB,因此每台宿主机最多容纳 6 台示例实例,正常情况下共 24 台。如果希望损失任意 1 台宿主机后仍有足够总内存重建原有实例,则运行规模不能超过 18 台。这里不考虑 CPU、磁盘、碎片和超分,数字只用于说明预留容量。

项目上限、物理容量和故障预留共同限制部署规模
项目上限、物理容量和故障预留共同限制部署规模

滑块中的“可承载”只是内存模型的计算结果,不是实际调度承诺。即使运行规模不超过 18 台,故障后的重建仍依赖控制面、镜像、网络和存储可用,并需要合适的放置条件与操作流程。预留能解决“有没有位置”的部分问题,不会自动发现故障、迁移数据或恢复业务。若重建需要 10 分钟,应用也必须能够承受或绕开这段缺口。

故障域描述资源可能一起失效的范围,例如同一宿主机、机架或供电单元。可用区是平台向用户表达放置边界的一种方式,但名称不同不必然证明电力、网络和存储全部独立。把 2 台应用实例放在同一宿主机,宿主机故障时会同时丢失它们;分散放置则降低这种共同失效风险。是否使用反亲和等能力,应结合部署支持和实际隔离效果验证。

订单 API 可以先采用分散的应用副本,并为关键数据库单独设计恢复方案。过强的放置限制会减少候选位置,也可能让扩容更容易失败;过少的限制则可能让冗余副本集中在同一故障域。方案需要写出允许损失什么、保留多少余量、预期多久恢复,而不是只写“实例数量为 2,所以高可用”。成本和可靠性的取舍发生在这些可检验的约束中。

6 常见坑:把控制面可用当业务可用

控制台能够登录,只证明某条身份与页面访问路径可用。它不能证明创建操作能完成,不能证明已运行实例之间能通信,也不能证明订单数据库可以提交事务。甚至“实例详情可以查询”也可能只是读取了控制面记录。业务可用性的判断必须沿顾客实际经过的入口、应用和数据依赖展开,不能停在资源列表上的绿色状态。

反过来,控制面故障也不必然使所有已有业务立即停止。例如调度服务暂时不可用时,已有实例可能仍在宿主机上运行,转发网络也可能继续工作。但此时扩容、替换故障实例或某些维护操作会受影响,业务已经失去部分恢复能力。故障报告应区分当前服务能力与后续修复能力;只说“顾客暂时没报错”容易忽略风险正在累积。

平台操作、实例运行和业务交易需要不同的观察信号
平台操作、实例运行和业务交易需要不同的观察信号

建议建立 3 组观察信号。控制面观察认证与资源 API 的成功率、延迟,以及创建等异步操作的完成时间;实例层观察宿主机、虚拟机和相关网络存储状态;业务层观察入口成功率、请求延迟、订单写入及读取结果。每组信号说明自己的范围,关联后再判断影响。单项 CPU 利用率很低,也不能证明任务没有在等待消息或外部服务。

另一个常见坑是把健康检查做成“端口开放即成功”。应用可能能接受连接,却无法取得数据库连接;数据库也可能可以读取旧数据,却不能继续写入。检查应按用途分层:轻量检查帮助发现进程失效,关键路径探测帮助判断业务能力。探测要有超时和频率限制,测试数据应隔离并能清理,否则监控本身可能产生额外负载或污染统计。

排障时先确定影响范围:只影响新建实例,还是已有实例也异常;只影响某个项目、可用区,还是广泛出现;失败是立即返回,还是长时间停在中间状态。随后选取少量有代表性的失败与成功样本比较。没有这些边界,容易把网络、权限和容量错误混在一起,最终用重启整个集群来掩盖问题,也丢失了定位根因所需的证据。

团队还应定义告警的行动含义。创建耗时上升对应检查异步工作链,入口失败率升高对应核查业务路径,数据恢复演练失败对应修复备份与恢复流程。对于订单 API,面向用户的可用性以业务探测和真实请求为依据,平台告警则说明交付和恢复能力。两者共同回答“现在能不能用”以及“坏掉后能不能及时修复”。

7 案例:Rabbit 积压拖垮调度

某教学平台在集中发布期间出现异常:创建 API 仍能返回实例标识,但大量新实例长时间处于 BUILD。现有订单 API 的大多数请求暂时正常,自动扩容却迟迟补不出新实例。有人据此判断“计算资源不足”,准备提高配额。管理员先检查失败项目的剩余配额、候选宿主机和请求时间线,发现问题更像是异步工作没有及时向前推进。

在这个案例中,调查发现支撑计算工作链的 RabbitMQ 队列持续积压,相关消费者处理速度下降。这里的“拖垮调度”指创建与调度相关工作整体迟滞,不代表调度算法一定消耗了过多 CPU。消息无法及时送达或处理,后续资源选择和执行就可能等待、超时或失败。必须先确认受影响的队列与工作职责,不能仅看到 RabbitMQ 就认定所有服务故障都有相同原因。

排查需要同时看可投递消息、未确认消息、消费者数量、发布速率和处理速率,并与实例创建耗时对齐。可投递消息不断增长,说明等待消费的工作在增加;未确认消息增加,可能说明消费者已接收工作但处理或确认变慢。某个队列深度为 0 也不保证整条链路健康,可能是上游未能发布,或工作积在其他位置。要把队列指标放回请求路径解释。

从创建迟滞到队列与下游证据的排查路径
从创建迟滞到队列与下游证据的排查路径

接着检查消费者日志、服务连接、消息节点磁盘与内存告警,以及下游数据库或 API 的延迟。消费者慢可能来自数据库锁等待,也可能来自某个依赖超时;消息节点可能因资源告警施加流控。案例最终确认:数据库响应恶化使相关消费者处理变慢,集中创建又持续送入新工作,积压和重试进一步放大延迟。结论来自时间对应与处理日志,而非队列长度的单独变化。

处置先限制非必要的批量创建,避免新工作继续淹没系统;再恢复数据库服务能力和消费者的正常处理,观察积压是否持续下降。平台团队可以在确认容量和下游承受能力后调整处理能力,但盲目增加消费者可能把瓶颈进一步推向数据库。也不应直接清空业务队列:其中可能包含尚未完成的资源操作,丢弃后会留下需要人工核对的不一致状态。

用户侧应停止无边界重试,保留已返回的实例标识并查询结果。超时不等于服务端没有执行;再次创建可能产生重复实例,继而占满配额。恢复后要核对原请求是否完成、是否产生重复或残留资源,并分别验证小规模创建、端口连通和订单交易。队列回落说明工作在消化,不能单独证明全部任务已正确完成。最终复盘应补齐创建完成时间告警、批量申请限速和故障期间的扩容预案。

8 把云控制面依赖写进平台方案

平台方案首先要写清楚向业务团队提供什么:哪些实例规格、镜像、网络和卷类型可以申请,谁维护这些资源,哪些操作由业务团队负责。每项能力都应有可验证的完成条件。例如“交付应用实例”若只到 ACTIVE,必须说明应用安装与健康检查由谁接手;若承诺交付可服务的节点,就必须把初始化和网络验证纳入交付链,而非留在口头约定里。

接着按动作写依赖。创建实例依赖身份、计算管理、调度资源记录以及相应网络和存储能力;查询状态、调整规则、挂卷和删除资源也各有路径。没有必要在入门方案里堆出所有进程名称,但应指出共同依赖的数据库、消息系统、内部网络和时间服务等。共享依赖出问题时,可能同时影响多个服务,这比只罗列“每项服务部署几个副本”更能说明风险。

把平台动作、共同依赖和恢复验证写进方案
把平台动作、共同依赖和恢复验证写进方案

方案还要定义失败时的业务策略。创建变慢时是否暂停发布,扩容失败时如何限制入口负载,某个故障域不可用时是否还有足够运行副本。对于订单 API,若日常高峰必须依赖即时新建实例才能承受,就需要评估控制面中断期间的容量缺口。保留基础容量、允许排队或限制非关键请求,都是可以讨论的选择;仅写“自动扩容解决高峰”没有交代依赖条件。

身份与权限也要进入交付约定。自动化使用可追踪的服务身份,权限覆盖所需动作,并遵守平台的凭据轮换方式。不要把管理员凭据写入应用镜像,或让普通应用启动时必须持有创建整个平台资源的权限。资源标签、项目归属和操作日志应能关联到申请方,使残留资源、配额争议和异常创建可以追责与回收。

最后给出验收证据和恢复演练。验收至少覆盖资源创建完成、网络访问、数据保留及删除策略;演练则验证某类依赖故障时的影响和恢复步骤。报告应说明测试负载、时间窗口与适用范围,避免将教学环境的结果直接推广为生产承诺。更细的消息系统可靠性、数据库高可用和调度内部机制留待专题学习,本课要求的是能把边界、依赖和证据写清楚。

9 从OpenStack走向容器原理(C26)

学完 OpenStack,我们已经见过把资源操作抽象为 API 的方法:用户描述目标,平台检查约束,再协调底层执行。下一课转向容器时,这种观察方式仍然适用,但承载对象与隔离方式会发生变化。不要因为都出现“镜像”和“调度”,就认为虚拟机与容器具有相同的启动过程、资源边界和故障表现。

虚拟机通常运行自己的客户操作系统内核,由虚拟化层提供硬件抽象。常见的 Linux 容器则依赖宿主机内核提供隔离与资源控制,让应用进程在受约束的环境中运行。这个区别帮助解释容器为何常有较小的打包与启动开销,也提示宿主机内核是重要的共享边界。具体隔离机制和限制将在 C26 展开,这里不需要提前记忆系统调用或配置参数。

容器镜像与虚拟机镜像都承担软件交付的起点角色,但格式、运行方式和包含内容不同,不能把任意虚拟机镜像直接当作容器镜像使用。订单 API 可以先运行在 OpenStack 提供的虚拟机中,再由虚拟机承载容器运行环境。这样会出现多层资源与责任边界:底层实例可用,不代表容器进程可用;容器进程可用,也不代表订单数据库可写。

基础设施平台与容器编排系统可以协作。前者提供虚拟机、网络和存储等资源,后者管理容器化工作负载的放置及运行目标。两者不是简单的替代关系。是否叠加这些层次,应根据团队能力、隔离要求和交付需求决定,不能因为容器启动较快就推导出可以省略网络设计、持久化和平台恢复能力。

带着 3 个问题进入下一课:运行单元共享了什么,隔离了什么;应用重建后哪些数据仍然存在;健康判断依赖哪条真实路径。它们也能回头检验本课理解:OpenStack 提供可管理的基础设施,控制面负责推进资源状态,业务可用性则必须结合实际运行与数据证据判断。把这些问题固定下来,比背诵服务缩写更有助于迁移到新的平台。

放进方案里

本项目在 OpenStack 上部署订单 API,初始使用 2 台应用实例,分散放置到经平台确认的不同宿主机故障域。实例由固定版本镜像创建,规格为每台 2 个虚拟 CPU、4 GiB 内存。应用通过受控入口提供服务,安全组只允许入口访问应用端口,管理访问限定来源。数据库采用独立持久化方案,明确卷的删除策略,并以恢复演练验证备份;应用日志集中保存。

业务团队负责应用发布、业务探测与数据库恢复流程;平台团队负责资源 API、计算节点、网络和存储服务,并维护数据库、消息系统等控制面依赖。交付完成条件包括实例运行、初始化结束、端口可达和测试订单读写成功。API 返回实例标识仅作为受理证据,ACTIVE 作为计算状态证据,不单独作为业务验收结论。

项目配额根据计划规模申请,并与物理容量、放置限制及故障预留分别核对。常态容量应覆盖约定的基础负载,扩容能力通过演练评估。控制面故障期间暂停非必要资源变更;扩容失败时执行入口限流和负载降级。故障预留不视为自动恢复承诺,重建仍需验证镜像、网络、存储和调度路径。

监控同时覆盖资源操作完成时间、消息处理延迟、实例运行状态和订单成功率。创建迟滞时记录项目、实例标识、时间窗口与请求标识,核查队列和下游依赖,避免重复创建或直接清空队列。恢复验收包括小规模创建、网络连通、数据读写及残留资源核对。上线前补齐容量规模、恢复时间目标和数据恢复点目标,以演练结果确认方案适用范围。

10 小结:下一步容器原理(C26)

OpenStack 将计算、网络与存储组织成可授权、可申请的基础设施服务。镜像决定软件起点,卷承担块存储,安全组约束网络访问;配额、容量与故障预留需要分别核对。实例创建是跨服务推进的过程,受理成功、运行状态和业务可用必须分开验证。

自测时试着解释:为什么还有配额却创建失败?为什么控制台正常而订单提交失败?为什么 Rabbit 积压后已有实例仍可能运行,但故障恢复能力已经下降?如果能沿依赖路径给出证据,下一课就可以继续研究容器怎样隔离进程、约束资源并承载应用。

同阶段相关课

AI 答疑

默认关闭。启用后,只发送本课标题、最近阅读的屏幕内正文摘录(最多 6000 字)与本次问题。

配置自己的服务