1
2
3
4
5
6
7
作者:李晓辉

联系方式:

1. 微信:Lxh_Chat

2. 邮箱:939958092@qq.com

迁移or疏散?

迁移就是把服务器实例从一个计算节点搬到另一个节点。OpenStack里有三种迁移方式,每种都有自己的特点。

冷迁移

第一种是冷迁移。想象一下,你的电脑在运行某个程序,突然要把它搬到另一台电脑上。管理员会先关掉实例(如果它在运行的话),然后把实例的镜像从原来的计算节点拷贝到目标节点。在数据库里把实例的归属改一下,再在新的节点上重新启动它。这个过程就像搬家,先把东西打包好,再搬到新地方。

热迁移

第二种是热迁移。这个就厉害了,它能让实例在运行的时候直接搬到另一个节点,而且实例自己还不知道发生了什么!比如你在玩一个在线游戏,服务器突然要迁移,热迁移就能保证你游戏不掉线,其他玩家也完全察觉不到。这个过程中,客户端的连接保持不断,实例的磁盘也要跟着搬到新的虚拟机上。磁盘的传输有两种方法:一种是基于块的,另一种是共享存储。如果用共享存储,就好比大家共用一个大硬盘,迁移起来就方便多了。

疏散

第三种是疏散(Evacuate)。这个通常发生在计算节点出故障或者要关机的时候。比如,一个服务器突然坏了,疏散功能就能把上面的实例重新建在另一个节点上。不过,疏散有个问题,如果实例的磁盘不是放在共享存储或者块存储卷上,那这个过程可能会导致数据丢失。因为疏散的时候,OpenStack会直接在新的节点上重建实例,而不会去管原来磁盘上的数据。不过,如果实例的磁盘是共享的,那疏散就比较安全了。

对了,迁移实例也很简单。如果实例在运行,可以用openstack server migrate命令加上--live选项,这样就能热迁移。如果实例是关机状态,就用同样的命令,但不用加--live。管理员还可以用--target选项,告诉OpenStack把实例迁移到指定的计算节点。

还有,迁移的时候,磁盘的传输方式也很关键。可以用--shared-migration,这是OpenStack默认的方式,也可以用--block-migration。Red Hat建议用Ceph RBD存储集群来搭建共享存储,这样迁移起来很方便。如果用块存储服务部署实例,不管是临时盘还是持久盘,都比用计算服务的临时存储好。不过,如果不同的计算节点用的存储类型不一样,那迁移的时候就得把存储也一起搬过去。

云主机迁移

先看看特定服务器上都有哪些云主机

1
2
3
4
5
6
7
8
9
(undercloud) [stack@director ~]$ source overcloudrc
(overcloud) [stack@director ~]$ openstack server list --host compute0.overcloud.example.com --all-projects -c ID -c Name
+--------------------------------------+-----------------+
| ID | Name |
+--------------------------------------+-----------------+
| e1060cd2-154b-48fc-930e-36ac92ad00ae | finance-server3 |
| d70a2397-77f3-4fa4-8af4-1404ac4f2b0d | finance-server2 |
| a181bb99-e8b1-4d74-8e46-37d46a7d5024 | finance-server1 |
+--------------------------------------+-----------------+

在OpenStack里,如果你用openstack server migrate命令来热迁移服务器,但没有指定--shared-migration或者--block-migration选项,那它就会默认用共享存储迁移的方式。

简单来说,共享存储迁移就是假设你的计算节点之间有一个大家都能访问的存储池,就像一个公共的“硬盘”,服务器的磁盘数据就存在那里。迁移的时候,OpenStack只需要把服务器的运行状态和配置信息从一个计算节点搬到另一个节点,而不用操心磁盘数据的传输,因为磁盘数据已经在共享存储里了,新节点可以直接访问。

这种方式的好处是迁移速度快,而且对用户来说几乎是无缝的,就像你在用手机的时候,突然手机的“大脑”换了个地方,但你完全没感觉出来,因为数据还在原来的地方。

不过,这也要求你的环境得支持共享存储,比如用Ceph之类的存储集群。如果没有共享存储,那可能就得用块存储迁移了,这种迁移方式就需要把磁盘数据也一起搬过去,会稍微复杂一点。

1
(overcloud) [stack@director ~]$ openstack server migrate a181bb99-e8b1-4d74-8e46-37d46a7d5024 --live compute1.overcloud.example.com

云主机疏散

云主机疏散有普通疏散和强制疏散两种

温柔疏散(Evacuate)

疏散通常用在计算节点已经不可用或者即将不可用的情况下。比如:

  • 计算节点突然宕机了,或者硬件坏了。

  • 计算节点要进行计划性的维护,比如要关机升级硬件或者打补丁。

在这种情况下,你用nova host-evacuate命令,OpenStack会尝试把宕机节点上的实例重新创建到其他可用的计算节点上。这个过程有点像“重建”,因为实例会在新的节点上从头开始启动。

带来的影响

  1. 实例重建:疏散过程中,实例会被重新创建,这意味着实例的运行状态会丢失。比如,如果实例正在运行一个任务,任务可能会中断。

  2. 数据安全性:如果实例的磁盘存储在共享存储(比如Ceph)或者块存储卷(Cinder)上,数据通常是安全的。但如果磁盘是本地存储的,可能会导致数据丢失,因为重建过程不会复制本地磁盘数据。

  3. 时间成本:重建实例需要时间,尤其是实例比较大或者依赖复杂配置的时候。

说到疏散(Evacuate),这个操作其实有点像给服务器“搬家”,不过是在它出问题或者要关机的时候。要是你想用nova host-evacuate命令来疏散一个计算节点,得先把它“关掉”,也就是禁用它。

禁用计算节点的时候,可以用openstack compute service set命令,加上--disable选项。这就像是给服务器打了个“暂停营业”的牌子,告诉OpenStack:“嘿,这个节点暂时不能用了,别再往这儿分配新实例了。”这样,当节点被禁用后,你就可以安心地用nova host-evacuate命令把上面的实例都搬到别的节点上,而不用担心新的实例又跑过来“凑热闹”。

1
2
3
4
5
6
7
8
9
10
11
(overcloud) [stack@director ~]$ openstack compute service set compute0.overcloud.example.com nova-compute --disable
(overcloud) [stack@director ~]$ openstack compute service list -c Host -c Status -c Binary
+----------------+-----------------------------------+----------+
| Binary | Host | Status |
+----------------+-----------------------------------+----------+
| nova-conductor | controller0.overcloud.example.com | enabled |
| nova-scheduler | controller0.overcloud.example.com | enabled |
| nova-compute | compute1.overcloud.example.com | enabled |
| nova-compute | computehci0.overcloud.example.com | enabled |
| nova-compute | compute0.overcloud.example.com | disabled |
+----------------+-----------------------------------+----------+

既然已经暂停营业了,那我们来疏散一下吧

nova host-evacuate命令把上面的实例都疏散到其他健康的节点上。这个过程就像是把一个快要“塌”的房子里的东西都搬出来,放到别的安全的地方,等房子修好了再搬回去。

不过,疏散的时候要特别注意,如果实例的磁盘不是放在共享存储或者块存储上,那可能会有点麻烦,因为疏散过程可能会导致数据丢失。所以,最好提前做好备份,或者确保你的存储环境是安全的。

1
(overcloud) [stack@director ~]$ nova host-evacuate compute0.overcloud.example.com

强制疏散(Live Evacuate)

强制疏散用在计算节点还在运行,但你出于某种原因需要立刻把实例迁移到其他节点的情况。比如:

  • 计算节点的硬件出现故障预警,虽然还没完全宕机,但随时可能会出问题。

  • 你需要对计算节点进行紧急维护,但实例不能停机。

  • 你发现某个计算节点的负载过高,需要把实例迁移到负载较低的节点。

在这种情况下,你用nova host-evacuate-live命令。这个命令会尝试热迁移实例到其他节点,而不会中断实例的运行。它会保持实例的运行状态,就像实例只是换了个“家”,但还在继续工作。

带来的影响

  1. 运行状态保持:实例的运行状态不会丢失,用户几乎不会察觉到任何中断。比如,一个正在运行的数据库实例或者在线游戏服务器可以无缝迁移到新的节点。

  2. 资源要求:强制疏散需要更多的资源和时间来完成,因为系统要同时处理实例的运行状态和数据迁移。如果实例很大或者网络带宽有限,可能会导致迁移速度较慢。

  3. 存储要求:强制疏散通常需要共享存储或者块存储卷,因为这样可以快速访问磁盘数据。如果使用本地存储,可能会导致迁移失败或者性能下降。

  4. 风险:虽然强制疏散尽量减少中断,但如果目标节点的资源不足(比如CPU、内存不够),可能会导致迁移失败或者目标节点过载。

这个情况得注意一下!如果你想要强制从一个正在运行的计算节点疏散服务器到另一个计算节点,就得用nova host-evacuate-live命令。这个命令就像是给正在运行的服务器来一次“紧急转移”,把它们安全地搬到别的地方,同时尽量保证它们的运行不受影响。

但是,如果你用普通的nova host-evacuate命令去疏散一个正在运行的计算节点,那可不行!因为nova host-evacuate通常是用来处理那些已经“挂掉”或者被禁用的计算节点的。如果用它去疏散一个还在正常运行的节点,系统就会报错,告诉你:“嘿,这个节点还在运行呢,你不能这么干!”

这个错误就好比你试图在一个正常营业的餐厅里强行清场,餐厅老板肯定不乐意,系统也会拒绝你的操作。所以,如果确实需要从一个运行中的节点疏散实例,一定要用nova host-evacuate-live,这样才能保证疏散过程既安全又顺利。

存储迁移(Storage Migration)

共享存储(Shared Storage)迁移

想象一下,你有两个房间(计算节点),它们都连接到了同一个公共仓库(共享存储)。这个仓库里存着你要迁移的实例的磁盘数据。

迁移过程

  • 当你用openstack server migrate命令迁移实例时,计算节点之间不会真的“搬动”磁盘数据,因为它们都可以直接访问共享存储。

  • 源计算节点(原来的房间)会停止使用磁盘,目标计算节点(新的房间)会接管磁盘的读写操作。

  • 这就好比你把一个房间的钥匙交给另一个人,让他去仓库里取东西,而你不再去仓库了。

优点

  • 速度快:因为不需要复制磁盘数据,迁移速度非常快。

  • 效率高:对网络带宽的要求低,因为主要操作是内存内容的传输。

块存储(Block Storage)迁移

块存储迁移和共享存储迁移有点像,但有一些关键区别,块存储迁移是当没有共享存储时的替代方法。如果源计算节点和目标计算节点无法共享存储,那么实例的根磁盘、临时磁盘、交换磁盘和持久化卷都需要传输到目标计算节点使用的存储位置。

块存储迁移的性能问题

  • 块存储迁移会先复制磁盘内容,再传输内存内容,因此速度比共享存储迁移慢。

  • 如果性能是首要考虑因素,建议避免使用块存储迁移,而是使用共享存储。

迁移过程

  • 在迁移之前,块存储会先复制磁盘内容到目标计算节点。这个过程有点像先把你房间里的东西打包好,再搬到另一个房间。

  • 磁盘内容复制完成后,才会开始传输内存内容。

  • 这意味着块存储迁移的速度会比共享存储迁移慢一些,因为多了一个复制磁盘的步骤。

  • 优点

    • 灵活性高:即使计算节点之间没有共享存储,也可以通过块存储完成迁移。

    • 安全性高:磁盘数据在迁移过程中会被完整复制,减少了数据丢失的风险。

Red Hat推荐在部署OpenStack时使用Ceph RBD存储集群作为共享存储。不过,早期的部署中也有不同的配置方式:

  • /var/lib/nova/instances目录可以通过GlusterFS或NFS在计算节点之间共享,但默认配置是每个计算节点都维护实例的磁盘存储。

  • 如果实例被重新调度到另一个计算节点,会在新节点上重新部署实例的磁盘。

不同计算节点的存储配置

即使在同一网络中,不同的计算节点也可能连接到不同的存储阵列、Red Hat Virtualization数据存储或其他后端存储系统。

块存储迁移的实施要求

实施块存储迁移需要满足以下具体要求:

  • 同一子网:源计算节点和目标计算节点必须位于同一子网。

  • 相同处理器类型:两个计算节点必须使用相同的处理器类型。

  • 一致的名称解析:所有控制器节点和计算节点必须能够一致地解析其他节点的名称。

  • 用户ID和组ID一致novalibvirt用户的UID和GID在所有计算节点上必须相同。

  • 使用KVM和Libvirt:计算节点必须使用KVM和Libvirt(这是Red Hat OpenStack Platform的默认配置)。KVM和Libvirt平台对热迁移的支持最好,功能最完整,稳定性也最高。

  • 本地目录权限一致:所有节点上的本地目录权限和系统访问权限必须一致。

  • 安全通信:Libvirt必须能够在节点之间安全通信。

  • 多路径设备命名一致:源计算节点和目标计算节点必须使用一致的多路径设备命名。实例在两个位置都需要能够以类似的方式解析多路径设备名称。

内存迁移的细节

不管用哪种存储方式,内存内容的迁移过程都差不多:

  1. 初始传输

    • 源计算节点会把实例的内存内容发送到目标计算节点。

    • 但是,内存页面在传输过程中可能还在被修改(比如实例还在运行,内存数据还在变化)。

  2. 追踪和重传

    • 源计算节点会记录在传输过程中被修改的内存页面。

    • 初始传输完成后,源计算节点会把这些修改过的页面重新发送给目标计算节点。

    • 这个过程会一直重复,直到所有修改过的内存页面都成功传输完毕。

  3. 启动新实例

    • 一旦所有内存页面都传输完成,目标计算节点就会启动一个和原来一模一样的实例。

    • 同时,虚拟网络基础设施会把网络流量重定向到新的实例上,这样用户就不会察觉到任何变化。

Libvirt的配置选项

在OpenStack中,Libvirt是一个常用的虚拟化管理工具。它的配置文件nova.conf(通常在/var/lib/config-data/puppet-generated/nova_libvirt/etc/nova/nova.conf路径下)包含了用于配置热迁移的选项。

这些配置选项和它们的默认值决定了迁移的行为,比如:

  • 迁移的速度:你可以设置内存传输的速率。

  • 重试机制:如果某些内存页面传输失败,可以设置重试的次数。

  • 网络配置:决定网络流量如何重定向。

这些配置文件存在于所有计算节点和HCI(超融合基础设施)节点上,管理员可以根据需要调整这些配置,以优化迁移性能。

参数描述
live_migration_retry_count = 30热迁移失败时的重试次数。
max_concurrent_live_migrations = 1同时允许运行的最大热迁移任务数量。
live_migration_bandwidth = 0热迁移时的最大带宽,单位是MiB/s。如果设置为0,系统会自动选择一个合适的值。
live_migration_completion_timeout = 800热迁移完成的超时时间,单位是秒。这个值取决于实例的大小。
live_migration_downtime = 500热迁移过程中允许的最大停机时间,单位是毫秒。
live_migration_downtime_delay = 75在每次增加迁移停机时间时的等待时间,单位是秒。
live_migration_downtime_steps = 10达到最大停机时间所需的增量步数。
live_migration_flag = VIR_MIGRATE_UNDEFINE_SOURCE, VIR_MIGRATE_PEER2PEER, VIR_MIGRATE_LIVE, VIR_MIGRATE_TUNNELLED设置热迁移的标志,这些标志决定了迁移的具体行为。
live_migration_progress_timeout = 150等待迁移在传输数据时取得进展的时间,单位是秒。如果在这个时间内没有进展,操作会被终止。
live_migration_uri = qemu+tcp://%s/system热迁移的目标URI,用于指定迁移的目标地址。

内存拷贝的停机时间

当实例的内存拷贝接近完成时,实例会被暂停一段时间。这个停机时间是为了让剩余的内存页面能够顺利拷贝,而不会被实例运行时的内存写操作干扰。停机时间的长短取决于实例的大小,默认是500毫秒

如果内存拷贝没有按预期进度完成,停机时间会逐渐增加。这个停机时间的算法受到以下参数的影响:

  • live_migration_downtime:允许的最大停机时间(毫秒)。

  • live_migration_downtime_delay:每次增加停机时间的等待时间(秒)。

  • live_migration_downtime_steps:达到最大停机时间所需的增量步数。

故障排除

遇到迁移问题?别慌,来看看怎么解决!

迁移服务器实例的时候,要是碰上失败或者拖拖拉拉的情况,别急,这时候就得去“翻翻账本”——也就是查看相关的日志文件啦!这些日志文件就像是“问题侦探”,能帮你找到迁移出问题的蛛丝马迹。

1. 源节点和目标节点的nova-compute.log

  • 文件位置/var/log/containers/nova/nova-compute.log

  • 作用:这个日志文件记录了计算服务在源节点和目标节点上的所有活动。要是迁移过程中出了什么岔子,比如实例启动失败、磁盘空间不足之类的,这里都能找到线索。

2. 控制节点上的日志

  • nova-api.log

    • 文件位置/var/log/containers/nova/nova-api.log

    • 作用:这个日志记录了API服务的活动,比如用户发起的迁移请求、API调用失败等信息。如果迁移请求都没发出去,这里可能会有提示。

  • nova-scheduler.log

    • 文件位置/var/log/containers/nova/nova-scheduler.log

    • 作用:调度器日志记录了OpenStack是如何选择目标计算节点的。如果调度器出了问题,比如找不到合适的节点,这里会有详细记录。

  • nova-conductor.log

    • 文件位置/var/log/containers/nova/nova-conductor.log

    • 作用:这个日志记录了与数据库交互的活动,比如实例状态更新、资源分配等。如果迁移过程中实例状态更新失败,这里可能会有线索。

排查问题的小贴士

  1. 查看时间戳:日志文件里的每条记录都有时间戳,通过对比源节点、目标节点和控制节点的日志时间,可以大致判断问题发生在哪个环节。

  2. 搜索关键字:在日志文件中搜索一些常见的错误关键字,比如ERRORWARNFailed等,能快速定位问题。

  3. 检查资源:有时候迁移失败可能是因为目标节点资源不足(比如CPU、内存或磁盘空间不够),检查一下目标节点的资源使用情况。

  4. 网络问题:如果迁移过程中涉及到网络传输(比如块存储迁移),检查一下网络连接是否正常。