欢迎光临
我们一直在努力

云原生运维笔记:硬核拆解OpenStack计算与存储——从主机聚合到Cinder挂载全流程

云原生运维笔记:硬核拆解OpenStack计算与存储——从主机聚合到Cinder挂载全流程

前面的时间里,我们把Keystone的认证逻辑、Glance的镜像管理,以及那个神秘的“29步创建虚拟机”的黑盒流程里里外外扒了个遍,算是把OpenStack的“地基”和“仓库”给摸透了。但如果光有镜像和一套认证体系,我们连个毛线都跑不起来。今天算是正式进入了实战的深水区——OpenStack计算管理(Nova)与存储管理(Cinder)。

说实话,这两块的复杂度比前面高了一个量级。计算管理涉及到物理资源的划分、调度算法、实例规格的限制,以及虚拟机极其丰富的生命周期状态流转(暂停、挂起、搁置,傻傻分不清楚对吧?)。而存储管理更是重量级,Cinder的架构、后端LVM的对接、卷的挂载卸载、快照与扩容,每一个概念如果不搞清楚,后面搞生产环境绝对是一踩一个不吱声。

这篇博客当作我今天的实验复盘。我会严格按照实验手册以及补充的管理资料,把Dashboard上的图形化操作,和背后对应的CLI命令完整梳理一遍,并且把今天踩过的坑(比如主机聚合的AZ冲突、规格为什么变不成Public、卷处于in-use状态删不掉)统统记录在案。内容很长,但全都是实打实的干货,建议连同代码块一起直接复制进Typora当字典查。


一、 OpenStack计算管理(Nova)实操复盘

计算管理就是管“算力”。在Nova的世界里,我们要搞清楚谁在提供算力(Hypervisor)、算力怎么分组(主机聚合/可用域)、算力的套餐(实例类型/Flavor),以及虚拟机实例的完整生命周期。

1.1 Hypervisor 与 主机聚合(Host Aggregates)

首先得了解底层的物理资源。登录Dashboard后,进入管理员 -> 计算 -> 虚拟机管理器。这里能直观看到我们实验环境里的两个计算节点:controller 和 compute。它们的状态都是“激活/启动”,后面跟着它们所剩的VCPU和内存。

接下来是重头戏:主机聚合(Host Aggregate)。这个概念在考试和面试里经常和**可用域(Availability Zone, AZ)**放在一起问。简单来说,主机聚合是底层物理机的一个逻辑分组,而AZ是暴露给最终用户的逻辑概念。一个主机聚合通常会对应一个AZ,但一个主机可以加入多个主机聚合。

在界面上创建主机聚合:

  • 进入 管理员 -> 计算 -> 主机聚合,点击“创建主机聚合”。
  • 名称填入 HostAggr_web,可用域填入 nova。
  • 在“管理聚合内的主机”页签,把 controller 移入选中的主机,点击“创建”。
  • 踩坑记录:一个主机能不能加入不同的AZ?
    手册里有个验证环节,我照着做了一下。我尝试再创建一个名为 HostAggr_web_test 的聚合,可用域设置为 AZ_web,然后把 controller 加进去。结果直接弹窗报错:“错误:向聚合中添加主机时出错”。这说明同一个物理主机在同一个时间点,只能属于一个AZ。但是,如果你把 HostAggr_web_test 的AZ改回 nova(和第一个聚合一样),再添加 controller,是可以成功的。也就是说,同一个主机可以加入多个主机聚合,但这些聚合的AZ必须相同。

    用命令行验证一下:

    [root@controller ~]# source keystonerc_admin
    [root@controller ~(keystone_admin)]# openstack hypervisor list –long
    # 这里会列出 controller 和 compute 的详细资源情况

    # 创建主机聚合
    [root@controller ~(keystone_admin)]# openstack aggregate create –zone nova HostAggr_cli
    +——————-+—————————+
    | Field | Value |
    +——————-+—————————+
    | availability_zone | nova |
    | created_at | 2024-08-13T06:30:24.269570|
    | id | 4 |
    | name | HostAggr_cli |
    | hosts | None |
    +——————-+—————————+

    # 验证AZ冲突
    [root@controller ~(keystone_admin)]# openstack aggregate create –zone AZ_cli HostAggr_cli_test
    [root@controller ~(keystone_admin)]# openstack aggregate add host HostAggr_cli_test controller
    # 报错:Cannot add host to aggregate 5. Reason: One or more hosts already in availability zone(s) ['nova', 'nova']. (HTTP 409)

    这背后的逻辑其实很好理解,AZ往往对应着机架或者数据中心,防止单点故障。如果一台机器同时属于两个不同的AZ,那高可用调度的时候就彻底乱套了。

    1.2 实例类型(Flavor)管理与公有/私有之惑

    规格(Flavor)就是虚拟机的硬件套餐。创建虚拟机时,你只能选规格,不能自己随便填CPU和内存。

    界面操作: 进入 管理员 -> 计算 -> 实例类型,点击“创建实例类型”。填入名称 Flavor_web,VCPU给1,RAM给128MB,根磁盘给1GB。在“实例类型使用权”页签,只勾选 Project_web,点击创建。这说明这个规格是私有的,只有Project_web能用。

    踩坑记录:移除所有项目,规格会变成公有(Public)吗?
    手册里特别提了一个验证题。如果我把刚才选中的 Project_web 移除,是不是等于所有项目都能用了?
    答案是否定的。移除所有项目后,该规格不仅不是Public,反而变成了“谁都不能用(不可见)”。如果你想要一个Public的规格,在命令行创建时,直接不指定任何项目就行了。

    # 创建指定项目可见的规格
    [root@controller ~(keystone_admin)]# openstack flavor create –vcpus 1 –ram 128 –disk 1 –private –project Project_cli Flavor_cli
    +—————————-+————————————–+
    | Field | Value |
    +—————————-+————————————–+
    | OS-FLV-DISABLED:disabled | False |
    | name | Flavor_cli |
    | os-flavor-access:is_public | False |
    | ram | 128 |
    | vcpus | 1 |
    +—————————-+————————————–+

    # 移除项目的可见性,它依然不是 Public
    [root@controller ~(keystone_admin)]# openstack flavor unset –project Project_cli Flavor_cli
    [root@controller ~(keystone_admin)]# openstack flavor show Flavor_cli | grep is_public
    | os-flavor-access:is_public | False |

    # 如何创建 Public 的规格?直接建,不加 –private
    [root@controller ~(keystone_admin)]# openstack flavor create –vcpus 1 –ram 128 –disk 1 Flavor_cli_public

    总结:规格一旦创建,就无法动态修改其属性(比如从Private变Public)。想改?只能删了重建,这是Nova的一个硬性规定。

    1.3 密钥对与虚拟机组(Server Group)

    密钥对(Key Pair)大家都很熟悉了,就是SSH登录凭证。在 项目 -> 计算 -> 密钥对 中,点击“创建密钥对”,生成 KeyPair_web 并自动下载 .pem 文件。

    虚拟机组(Server Group)是控制虚拟机调度的一种策略。我们在创建时,有几种策略可选:

    • 关联(Affinity):组内的虚拟机必须挤在同一台物理机上。适合需要极低延迟通信的集群(比如HPC)。
    • 不关联(Anti-Affinity):组内的虚拟机绝对不能在同一台物理机上。适合高可用场景,防止物理机宕机导致全军覆没。
    • 软关联 / 软不关联:柔性策略,资源充足时遵守,不充足时妥协。

    我们在界面创建一个名为 ServerGroup_web 的组,策略选择“关联”。

    1.4 虚拟机实例的“一生”:发放与状态流转

    在界面 项目 -> 计算 -> 实例 中点击“创建实例”,一路Next。选源(Img_web)、选规格(Flavor_web_test)、选网络(shared)、选密钥对,最后在服务器组里选中刚才创建的那个亲和性组,点击创建。

    但这只是开始,真正的重头戏是虚拟机的生命周期管理。今天的实验里,我几乎把所有的状态都点了一遍:

  • 关机 / 开机:常规操作,Status 变为 关机。
  • 软重启 / 硬重启:软重启只是重启OS(相当于Linux里的 reboot),硬重启是直接拔电源再开机。界面上执行软重启后,任务状态会显示“软重启中”。
  • 锁定 / 解锁:为了防止手滑误删实例,admin用户可以将实例“锁定”。踩坑点:默认情况下,普通用户(非admin)是可以对admin锁定的实例进行“解锁”并删除的!这非常不安全。后来我跟着资料把 /etc/openstack-dashboard/nova_policy.json 里面的 unlock 权限改为了 rule:admin_api,普通用户就彻底懵了,完全动不了锁定的实例。
  • 暂停(Pause)与 挂起(Suspend):
    • 暂停:把虚拟机的状态直接保存在宿主机的内存里,电源状态变为“已暂停”。恢复(Unpause)极快。
    • 挂起:把状态保存到宿主机的磁盘上,电源状态变为“关闭”。恢复(Resume)需要从磁盘读回内存,相对较慢。
  • 废弃(Shelve):这个最狠。它会把虚拟机变成Glance里的一个镜像,然后在宿主机上把它彻底删掉,释放所有资源。需要的时候(UnShelve)再重新创建出来。适合长期不用的僵尸机。
  • 快照与重建:给运行中的机器打快照(本质上是变成一张新镜像),如果虚拟机系统崩了,可以选择“重建实例”,选择刚才的快照,相当于一键还原。
  • 用CLI看下实例列表和发放过程:

    [root@controller ~(keystone_admin)]# openstack server create –availability-zone nova –image Img_cli –flavor Flavor_cli –network shared –key-name KeyPair_cli Instance_cli_01
    # 命令回显中会显示 OS-EXT-STS:task_state 为 scheduling,然后 building,最后 active

    # 查看实例列表
    [root@controller ~(keystone_admin)]# openstack server list
    +————————————–+—————-+——–+———————–+
    | ID | Name | Status | Networks |
    +————————————–+—————-+——–+———————–+
    | 0f0b35d5-4c7d-42dd-8edf-9655748a5013 | Instance_cli_01| ACTIVE | shared=192.168.233.186|
    +————————————–+—————-+——–+———————–+

    1.5 调整实例大小(Resize)的坑

    在实例的操作列表里,有个“调整实例大小”。我们试着把原本 128MB 内存的规格调整为 156MB 的 Flavor_web_new。

    界面点击调整后,状态会变成 确认或放弃调整大小/迁移。你必须再点一次“确认调整大小/迁移”,才算真正完成。
    踩坑点:手册里提到,如果把内存调到“64MB”(比当前还小),或者环境里没有共享存储(NFS/Ceph)且是多节点环境,调整大小会失败。因为调整大小本质上是一个带迁移的动作,底层存储如果不在共享目录里,数据根本拉不过去。这为后面搞Cinder NFS存储埋下了伏笔。


    二、 深入OpenStack存储管理(Cinder)

    计算折腾完,终于来到了存储。按照资料里说的,OpenStack的持久化存储有三大类:块存储(Cinder)、对象存储(Swift)和文件系统存储(Manila)。今天重点折腾的是块存储Cinder。

    2.1 Cinder 架构与核心概念

    不要把Cinder当成一个真实的物理硬盘,它其实是一个抽象的中间层。
    架构上,cinder-api 负责收请求,cinder-scheduler 负责选后端节点,cinder-volume 负责真正干活,底层对接的可能是LVM、SAN、Ceph等。

    默认的实验环境里,Cinder对接的后端就是LVM。具体来说,它是把Linux的物理卷(PV)做成卷组(VG),然后从中切出逻辑卷(LV)给虚拟机用。我们可以在控制节点执行 vgdisplay cinder-volumes 看到,系统切了 20GB 的空间作为存储池。

    在创建卷之前,得先搞定**卷类型(Volume Type)**和 QoS(服务质量)。

    • 界面操作:管理员 -> 卷 -> 卷类型,创建 VolumeType_web,勾选“公有”。
    • 接着创建 QoS 规格 QoS_web,消费者选“后端”。
    • 然后回到卷类型列表,把 QoS 关联到 VolumeType_web 上。

    用CLI走一遍:

    # 创建卷类型
    [root@controller ~(keystone_admin)]# openstack volume type create –public VolumeType_cli

    # 创建QoS
    [root@controller ~(keystone_admin)]# openstack volume qos create –consume back-end QoS_cli

    # 将QoS关联到卷类型
    [root@controller ~(keystone_admin)]# openstack volume qos associate QoS_cli VolumeType_cli

    2.2 卷的创建、挂载与卸载

    这是最核心的日常操作。我们在 项目 -> 卷 -> 卷 里创建一个基于镜像的卷。

    • 卷名称:Volume_web_01
    • 卷来源:镜像
    • 使用镜像:Img_web
    • 类型:VolumeType_web
    • 大小:1GB

    创建完成后,状态从“创建中”变为“可用”。接着,我们要把它挂载到刚才发放的虚拟机 Instance_web_01 上。
    点击“管理连接”,选择实例,点击“连接卷”。此时,卷的状态变为“正在使用”,在实例内部,你会多出一块 /dev/vdb 的裸盘。

    如果不需要了,点击“管理连接”,点击“分离卷”,状态重新回到“可用”。

    CLI 操作流:

    # 创建卷
    [root@controller ~(keystone_admin)]# openstack volume create –image Img_cli –type VolumeType_cli –size 1 Volume_cli_01

    # 挂载给实例
    [root@controller ~(keystone_admin)]# openstack server add volume Instance_cli_01 Volume_cli_01
    # 查看卷挂载状态
    [root@controller ~(keystone_admin)]# openstack volume list
    | aa0caa97-3369-4310-b159-e5ade3eea939 | Volume_cli_01 | in-use | 1 | Attached to Instance_cli_01 on /dev/vdb |

    # 卸载
    [root@controller ~(keystone_admin)]# openstack server remove volume Instance_cli_01 Volume_cli_01

    2.3 高级操作:上传、快照、扩容与基于快照建卷

    Cinder的强大之处在于它的快照和克隆能力。

    上传卷到镜像:如果我们把系统盘装好了环境,可以直接把这个卷打包成Glance镜像。在界面上点击卷的“上传镜像”,填入名称,格式选QCOW2。在CLI下就是:

    [root@controller ~(keystone_admin)]# openstack image create –volume Volume_cli_01 –disk-format qcow2 Volume_Img_cli

    创建卷快照:点击卷的“创建快照”,起名 Volume_Snap_web。注意,快照依赖原卷,如果原卷不删,快照就占着坑。

    卷扩容:点击“扩展卷”,把大小从1GB改成2GB。

    [root@controller ~(keystone_admin)]# openstack volume set –size 2 Volume_cli_01

    注意:扩容后,只是Cinder层面的容量变大了,如果里面已经跑着文件系统,还需要在虚拟机内部执行 resize2fs 或 xfs_growfs 才能真正用上新增的空间。

    基于卷快照创建卷:在快照列表里,点击“创建卷”,相当于恢复数据。
    基于卷发放虚拟机实例:如果卷里已经有完整的OS,可以直接用这个卷当启动盘发虚拟机。

    # 使用已有卷创建实例
    [root@controller ~(keystone_admin)]# openstack server create –volume Volume_cli_02 –flavor Flavor_cli Instance_cli_03

    踩坑点:如果这个卷被标记为“非启动卷”(–non-bootable),用它是建不了虚拟机的,直接报错 Block Device … is not bootable。

    2.4 删不掉!卷的删除依赖链

    实验到最后,我想把创建的东西清理一下。结果发现卷删不掉。
    系统报错:Invalid volume: Volume status must be available or error… and must not be migrating, attached, belong to a group, have snapshots…
    这个报错信息其实极其精准:

  • 卷现在是 in-use,必须先卸载(如果卸载报错说它是系统盘,那你只能先删虚拟机)。
  • 卷还有快照,必须先删快照。
  • 如果状态是 error,反而可以直接删。
  • 删卷的顺序必须是:卸载卷 -> 删快照 -> 删卷。

    # 尝试直接删卷(失败)
    [root@controller ~(keystone_admin)]# openstack volume delete Volume_cli_01
    # 报错,因为有快照

    # 删除快照
    [root@controller ~(keystone_admin)]# openstack volume snapshot delete Volume_Snap_cli

    # 再次删除卷(成功)
    [root@controller ~(keystone_admin)]# openstack volume delete Volume_cli_01

    2.5 扩展实战:配置 NFS 共享存储后端

    手册最后提到了一个非常关键的配置项:配置NFS共享存储。因为我们在虚拟机调整大小(Resize)的时候,如果是多节点且没有共享存储,就一定会失败。为了彻底解决这个问题,我们需要把Cinder的后端从纯本地LVM改为对接NFS。

    操作步骤:

  • 准备一台NFS服务器(或者用模板克隆一台IP为 192.168.108.12 的节点)。
  • 在NFS节点上安装服务并配置共享目录:
  • mkdir /nfs_share
    chmod -R 777 /nfs_share
    yum -y install nfs-utils
    echo "/nfs_share *(rw,sync,no_root_squash)" > /etc/exports
    systemctl stop firewalld.service
    systemctl restart nfs-server
    systemctl enable nfs-server

  • 在控制节点上,修改 /etc/cinder/cinder.conf:
  • # 开启多后端支持
    enabled_backends = lvm,nfs

    [lvm]
    volume_backend_name = lvm
    volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
    target_ip_address = 192.168.108.10
    target_helper = lioadm
    volume_group = cinder-volumes

    [nfs]
    nfs_mount_point_base = /mnt/nfs_share
    nfs_shares_config = /etc/cinder/nfs_shares
    volume_driver = cinder.volume.drivers.nfs.NfsDriver
    volume_backend_name = nfs

  • 创建共享配置文件:
  • echo "192.168.108.12:/nfs_share" > /etc/cinder/nfs_shares
    mkdir -p /mnt/nfs_share
    chown -R cinder:cinder /mnt/nfs_share
    systemctl restart openstack-cinder-volume

  • 关键一步:创建对应的卷类型。在界面上创建一个名为 nfs 的卷类型,并在“扩展规格”里配置键值对:键填 volume_backend_name,值填 nfs。这样用户在创建卷时,选择 nfs 类型,Cinder就会把数据写进NFS共享目录里了。
  • 当有了这个共享存储后,多节点间的虚拟机调整大小和迁移就完全不在话下了。


    三、 踩坑总结与心得感悟

    今天这一大波计算和存储的实操,信息量确实有点大。挑几个印象最深的说:

  • 主机聚合(Host Aggregate)的坑:同一台物理机不能跨AZ加入多个聚合,Nova死板是为了保护高可用机制。
  • Flavor的Public到底怎么来:移除所有项目可访问权,并不会让它变成所有人可见的Public,而是变成了“隐形人”。要Public,建的时候别指定项目。
  • 虚拟机生命周期里的细节:暂停(Pause)是把内存存在宿主机,挂起(Suspend)是存在磁盘。废弃(Shelve)是直接删机器存镜像。这几个动作如果不亲手点一遍,光看书真的很容易混。
  • 安全组的解锁策略:默认配置下普通用户居然能解开管理员上的锁,这是一个很危险的设计,必须改 nova_policy.json 才能达到真正的“防误删”目的。
  • Cinder的删除链:删卷之前必须断挂载、删快照、删备份。哪个环节卡住都会报 Invalid volume,学会看报错原因,按顺序清资源才是王道。
  • Cinder背后有LVM和NFS:Cinder本身不存数据,它是在指挥后端存储。本地的LVM只能单机玩,要搞热迁移和调整大小,还得是共享的NFS或者Ceph。
  • 从图形界面的直觉操作,到CLI命令行的底表操作,再到配置文件里的深水区(比如Cinder的 cinder.conf 和后端对接),这不仅是把知识点过了一遍,更是对“云”这个东西从抽象走向了具体的认知。

    云原生这条路确实很长,光是一个Nova的计算调度(Filter和Weight的计算)就足够写几篇论文了,更别提还有对象存储Swift和网络Neutron还没正式开搞。但今天这一套组合拳打下来,我已经能脑补出:当你在Dashboard上轻轻点一下“创建实例”时,底下的物理资源是如何被Flavor限制、被Scheduler调度、被Cinder挂盘、最后被Hypervisor拉起来的全貌了。

    赞(0)
    未经允许不得转载:171主机测评 » 云原生运维笔记:硬核拆解OpenStack计算与存储——从主机聚合到Cinder挂载全流程
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址