Writer:Cgm 醉里挑灯写bug;
热爱旅游和美食。
一、背 景
迁移一台内存密集型实例时,由于写内存的速度较快,脏页产生的速度一直比迁移虚拟机机,源目的虚拟机同步内存速度快,导致迁移一直完不成,结果超出了keystone token默认的1小时超时时间,最后导致虚拟机状态错误,迁移完不成。
二、迁移超时导致token超时
1、原 因
keystone token默认超时时间为1小时。
虚拟机默认热迁移超时取消迁移时间为(非块迁移):虚拟机内存GB * 默认800s
得出以下关系:
因此,当虚拟机的规格大于4GB时,且一直无法完成迁移,持续超过keystone的1小时时间,这时会发生虚拟机变成错误状态。而虚拟机规格大于4GB是常见的情况,因此需要避免虚拟机因热迁移时间超过keystone超时时间(默认的1小时),虚拟机状态异常错误。
值得说明的是,多数情况下虚拟机热迁移时间在大约10分钟以内(虚拟机64G/1Gb网卡)。因此,如迁移大于10分钟还未迁移完成,建议取消迁移,选择虚拟机io空闲时段再次迁移。
2、避免虚拟机迁移token超时
- 增加迁移最大超时时间
修改nova代码,设置虚拟机热迁移最大的超时时间小于1小时(keystone默认token超时时间为1小时)。
这里为了使代码修改最少,采用在代码中写成固定的3400s的方法。
代码位置:/usr/lib/python2.7/site-packages/nova/virt/libvirt/driver.py_live_migration_monitor函数中:
@@ -7558,12 7559,15 @@ class LibvirtDriver(driver.ComputeDriver): progress_timeout = CONF.libvirt.live_migration_progress_timeout completion_timeout = int( CONF.libvirt.live_migration_completion_timeout * data_gb) completion_timeout = min(completion_timeout, 3400) if libvirt_migrate.should_abort(instance, now, progress_time, progress_timeout, elapsed, completion_timeout, migration.status): try: guest.abort_job() LOG.warning("Abort migration because of completion timeout(%ss)", completion_timeout) except libvirt.libvirtError as e: LOG.warning("Failed to abort migration %s", e, instance=instance)
重启nova-compute服务生效,systemctlrestart openstack-nova-compute。
三、迁移加速功能开启
上图为在迁移网络是1Gb网卡下,脏页产生速度和downtime(最小停机时间)之间的关系。
1、差异传输xbzrle功能
- 功能说明
xbzrle功能开启后,在迁移的时候,会在迁移源端保存一份缓冲区(默认是64MB),用于缓存传输过的脏页面;当下次迭代传输时,若缓存过的页面写入(比如:128B的)数据,而被标记为脏页面,这时只会传输(比如:128B的)数据,而不是整个4KB页面,这将减少传输的数据量。
若某个用户程序频繁写申请过的内存,开启该功能会,将会大大增加热迁移效率,提高热迁移成功率。
但若用户程序是频繁申请新的内存(如malloc等),开启该功能,将不会对热迁移效率有大的提升。因为新申请的页面,并没有被xbzrle历史缓存。另外迁移时,会使用64MB的宿主机系统内存,迁移完成后释放。
后面章节有结果数据比较。
- 开启xbzrle功能方法
由于目前nova还没有开启qemu xbzrle的功能,因此需要修改代码支持。
代码位置:nova/virt/libvirt/driver.pyb/nova/virt/libvirt/driver.py
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.pyindex a3feb6b..1b47f1e 100644--- a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py@@ -7295,6 7295,7 @@ class LibvirtDriver(driver.ComputeDriver): else: migration_flags = self._live_migration_flags
migration_flags |= 1 << 11 serial_listen_addr = libvirt_migrate.serial_listen_addr( migrate_data) if not serial_listen_addr:
重启nova-compute服务生效,systemctlrestart openstack-nova-compute
2、自动降频功能
- 功能说明
开启该功能后,nova(Libvirt)检测到迁移不太可能完成(虚拟机的写内存速度大于迁移数据速度),并减慢了其CPU的速度,直到内存复制过程比实例的内存写入快,提高迁移成功率。
缺点:它会降低虚拟机的运行速度,可能会对某些应用影响,因此在开启该功能前,请确认降低虚拟机的运行速度不会对应用产生大的影响。
- 测试数据
因此当cpu阻塞很高时(90%),才会对内存密集型实例迁移有较大帮助。
- 使用
在迁移内存密集型实例时(事先确认了用户应用接受CPU阻塞),在虚拟机所在节点使用命令;
virsh domjobinfo virsh-list-id
注:virsh-list-id是virsh list中虚拟机的id/name;
查看Dirty rate速度是否一直很高(比如大于30000pages/s),且虚拟机的cpu使用率较高,此时建议打开自动降频功能((请先确认用户应用能接受CPU阻塞));在迁移成功之后,关闭该功能。
关闭方法:
在/etc/nova/nova.conf的[libvirt]属性下,删除live_migration_permit_auto_converge=true
并重启nova-compute服务:systemctl restartopenstack-nova-compute
- 迁移完不成时打开
A.先取消迁移过程
1)找到迁移虚拟机的uuid(用instance_id代表)
2)找到迁移id:novaserver-migration-list instance_id.用migration_id代表迁移id。
3)执行取消迁移命令:novalive-migration-abort instance_idmigration_id
B.打开自动降频功能
在/etc/nova/nova.conf的[libvirt]属性下,添加live_migration_permit_auto_converge=true
并重启nova-compute服务:systemctl restart openstack-nova-compute
C.再次迁移
D.迁移成功之后关闭自动降频功能
在/etc/nova/nova.conf的[libvirt]属性下,删除live_migration_permit_auto_converge=true
并重启nova-compute服务:systemctl restartopenstack-nova-compute
- 提前开启
在迁移内存密集型实例时或虚拟机热迁移无法完成时,打开自动降频功能,提高迁移成功率(请先确认用户应用能接受CPU阻塞)。
开启方法:
在/etc/nova/nova.conf的[libvirt]属性下,添加live_migration_permit_auto_converge=true
并重启nova-compute服务:systemctl restartopenstack-nova-compute
3、功能使用对比及建议
本次测试虚拟机规格为8核16G(同监控云虚拟机规格,监控云虚拟机迁移为问题频发事例)。
- 该虚拟机无负载时,热迁移耗时5s.
- 循环写内存程序test.
test.c程序如下:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdint.h>
int main(){ int c,i,j; int test[1000][2000]; for(c=0; c < 1000000; c ) { for(i=0; i < 2000; i ) { for(j=0; j<1000; j ) { test[j][i]=j; } } } return 0;}
开启的功能指标项 | 耗时(s) | cpu阻塞率 |
---|---|---|
都不开启 | 无法完成 | 无阻塞 |
xbzrle | 5 | 无阻塞 |
auto-converge | 20 | 阻塞90%(阻塞时间约1s) |
xbzrle auto-converge | 5 | 无阻塞 |
- stress malloc申请新内存压力测试
开启的功能指标项 | 耗时(s) | cpu阻塞率 |
---|---|---|
都不开启 | 无法完成 | 无阻塞 |
xbzrle | 无法完成 | 无阻塞 |
auto-converge | 305 | 阻塞99%(阻塞时间约2s) |
xbzrle auto-converge | 300 | 阻塞99%(阻塞时间约2s) |
4、总结
可以看出,写内存程序test是xbzrle最理想的情况,这时候xbzrle最有效,接近无负载情况;stress malloc程序则是xbzrle最差的情况。
实际应用情况是介于两者之间,因此xbzrle是有效的,建议默认打开xbzrle功能。auto-converge功能建议在xbzrle无效,且虚拟机应用对cpu阻塞可接受的情况下再使用。
四、操作手册
以下为简介操作手册:
建议默认打开xbzrle功能。auto-converge功能建议在xbzrle无效,且虚拟机应用对cpu阻塞可接受的情况下再使用。
1、避免虚拟机迁移token超时
修改nova代码,设置虚拟机热迁移最大的超时时间小于1小时(keystone默认token超时时间为1小时)。
代码位置:/usr/lib/python2.7/site-packages/nova/virt/libvirt/driver.py_live_migration_monitor函数中:
@@ -7558,12 7559,15 @@ class LibvirtDriver(driver.ComputeDriver): progress_timeout = CONF.libvirt.live_migration_progress_timeout completion_timeout = int( CONF.libvirt.live_migration_completion_timeout * data_gb) completion_timeout = min(completion_timeout, 3400) if libvirt_migrate.should_abort(instance, now, progress_time, progress_timeout, elapsed, completion_timeout, migration.status): try: guest.abort_job() LOG.warning("Abort migration because of completion timeout(%ss)", completion_timeout) except libvirt.libvirtError as e: LOG.warning("Failed to abort migration %s", e, instance=instance)
重启nova-compute服务生效,systemctlrestart openstack-nova-compute
2、打开xbzrle差异传输功能
代码位置:nova/virt/libvirt/driver.pyb/nova/virt/libvirt/driver.py
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.pyindex a3feb6b..1b47f1e 100644--- a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py@@ -7295,6 7295,7 @@ class LibvirtDriver(driver.ComputeDriver): else: migration_flags = self._live_migration_flags
migration_flags |= 1 << 11 serial_listen_addr = libvirt_migrate.serial_listen_addr( migrate_data) if not serial_listen_addr:
重启nova-compute服务生效,systemctlrestart openstack-nova-compute
建议把xbzrle功能默认打开。
3、自动降频功能
开启该功能后,nova(Libvirt)检测到迁移不太可能完成(虚拟机的写内存速度大于迁移数据速度),并减慢了其CPU的速度,直到内存复制过程比实例的内存写入快,提高迁移成功率。因此,开启该功能前,请确认用户虚拟机应用能接受CPU被阻塞。
不建议把自动降频功能默认打开。
开启步骤:
A.若在迁移过程中,则先取消迁移过程
1)找到迁移虚拟机的uuid(用instance_id代表)
2)找到迁移id:novaserver-migration-list instance_id.用migration_id代表迁移id。
3)执行取消迁移命令:novalive-migration-abort instance_idmigration_id
B.打开自动降频功能
在/etc/nova/nova.conf的[libvirt]属性下,添加live_migration_permit_auto_converge=true
并重启nova-compute服务:systemctl restartopenstack-nova-compute
C.执行迁移
D.迁移成功之后关闭自动降频功能
在/etc/nova/nova.conf的[libvirt]属性下,删除live_migration_permit_auto_converge=true
并重启nova-compute服务:systemctl restartopenstack-nova-compute
附-虚拟机迁移信息查看命令
1、查看迁移时的速度等信息
virsh domjobinfo virsh-list-id
例如:
[root@openstack-con03 ~]#virsh domjobinfo 323
Job type: Unbounded
Operation: Outgoing migration
Time elapsed: 139135 ms
Data processed: 15.146 GiB
Data remaining: 6.812 MiB
Data total: 4.016 GiB
Memory processed: 15.146GiB
Memory remaining: 6.812 MiB
Memory total: 4.016 GiB
Memory bandwidth: 107.902MiB/s
Dirty rate: 34398 pages/s
Iteration: 2247
Constant pages: 950532
Normal pages: 3960697
Normal data: 15.109 GiB
Expected downtime:1240 ms
Setup time: 50 ms
注:virsh-list-id是virsh list中虚拟机的id/name(下同)。
2、查看虚拟机的迁移特性信息
virsh qemu-monitor-command virsh-list-id --hmp infomigrate_capabilities
3、查看虚拟机迁移的down机时间限制/cpu初始降频信息等
virsh qemu-monitor-command virsh-list-id --hmp info migrate_parameters
4、virsh取消迁移
virsh qemu-monitor-command virsh-list-id --hmp migrate_cancel
●Ceph RGW整体结构,最全干货在这!
●还在为容器时区困扰?送你一剂良药!
●玩转K8S AdmissionWebhook
· END ·
记得文末点个在看鸭~
点就完事儿了!