在OpenStack中创建实例的大致流程为:
- 用户通过Dashboard界面或命令行发起实例创建请求,Keystone从请求中获取用户相关信息并进行身份验证
- 验证通过后,用户获得认证Token,实例创建请求进入Nova-api;
- 在向Keystone验证用户Token有效后,Novaapi将请求转入Nova-scheduler;
- Nova-scheduler进行实例创建目的主机的调度选择,目标主机选取完成后,请求转入Nova-compute;
- Nova-compute与Nova-conductor交互以获取创建实例的信息,在成功获取实例信息后,Nova-compute分别与Glance、Neutron和Cinder交互以获取镜像资源、网络资源和云存储资源;
- 一切资源准备就绪后,Nova-compute便通过LibvirtAPI与具体的Hypervisor交互并创建虚拟机
流程图
keystone内流程
nova-api工作流程
nova-api函数调用过程
以下全位于nova-api内:
身份认证成功后
nova-conductor流程
- 在Nova各个组件中,除Nova-api需要接受外部请求外,其他组件仅进行彼此之间的交互调用,并且组件之间的交互以RPC调用的方式通过消息队列来实现。
- 由于Nova conductor提供了build_instances()这个RPC方法,因此一直处于消息队列监昕状态,一旦监昕的队列有消息进入,Nova-conductor便开始执行build_instances()方法。
- Nova-conductor还向Nova-schduler发出RPCcall调用,并要求其返回计算节点调度结果,在收到Nova-scheduler的调度结果后,Nova-conductor的build_instances()方法将请求传递到Nova-compute的消息队列中
Nova_scheduler流程
- Nova-scheduler的功能就是负责监昕消息队列,并在获取消息队列之后进行计算节点的调度选取,同时将调度结果传递给消息队列。
- 为了获取创建实例的目标主机,Novaconductor会向Nova-scheduler发起RPCcall调用,并调用Nova-scheduler的select_destinations()方法;
- Nova-scheduler在消息队列中接收到调用消息后,根据nova.conf配置文件中关于Filters和Weight的配置参数对计算节点主机列表进行过滤和加权调度,在这个过程中,Nova-scheduler需要访问数据库以获取节点相关的信息;
- 在获取信息后,Novascheduler便开始进行节点调度,默认使用的调度驱动为FilterScheduler,调度完成之后,将节点调度结果传递到消息队列,以完成Nova-conductor的RPCcall调用过程
Nova_compute流程
- Nova-compute是Nova服务项目中最复杂和最关键的组件,运行Nova-compute的节点称为计算节点,通常Nova-compute部署在独立的计算节点上,并与Nova项目的其他组件分开部署。
- 在实例创建过程中,Nova-compute随时监昕topic:compute-computeN(computeN为计算节点名称)消息队列,在监昕到Nova-conductor传递的实例创建请求后,Nova-compute开始启动内部工作流程以响应实例创建请求。
- 在Nova-api的工作流程中,请求中创建实例所需的镜像、网络和存储等资源已经做过有效性和可用性的检查,因此Nova-compute将直接与Glance交互以获取镜像资源,与Cinder交互获取块存储资源。如果配置了Ceph块存储或对象存储服务,Nova-compute还会与CephRADOS进行交互以访问Ceph存储集群。
- 在获取镜像和存储资源后,Nova-compute还需与OpenStack的网络服务项目Neutron进行交互访问以获取网络资源。由于网络资源的有效性和可用性已经在Nova-api工作流程中完成,这里主要是获取虚拟机的FixedIP等网络资源
Nova-compute 与 Neutron 交互获取网络资沥
在准备好常见实例所需的一切资源后, Nova-compute将通过Libvirt与对应的Hypervisor API进行交互,并通过Libvirt API 接口进行虚拟机的创建工作.
Nova-compute 与 Libvirt 交互创建实例的过
Nova 实例状态变更
在虚拟机实例的创建和运行维护过程中, Nova 使用三个变量来描述虚拟机当前的状态, 分别为 vm_state、 power_state 和 task_state
vm_state | power_state | task_state(任务状态) |
---|---|---|
本质上反应的是 Hypervisor 的状态,先是底层计算节点上 Hypervisor 状态变更,然后上层数据库对应值变更 其更新过程遵循"bottom-top(由下至上)"原则 | 基于 API 调用的一种稳定状态,是API运行后期望的状态 其更新过程遵循"top-down(由上至下)"原则 | API 调用过程中的过渡状态,反映了不同阶段所调用API对实例进行的操作 |
Power_state
- power_state是Nova程序调用特定虚拟机上的虚拟驱动所获取的状态。
- 数据库中关于特定实例的power_state值仅是虚拟机最近一段时间的快照值,并不能真正反映当前虚拟机的实际power_state,虚拟机当前power_state的实际值位于Hypervisor中。
- 如果出现可能影响到power_state的任务,则在此任务结束时,位于数据库中的power_state值就会被更新。其更新过程遵循"bottom-top原则",即计算节点首先报告虚拟机power_state已经更新,然后再刷新数据库中的power_state字段值。
- power_state状态值衍生自Libvirt(其中BLOCKED状态值也被丢弃),其本质上代表的是RUNNING状态,SHUTOFF被映射为SHUTDOWN状态,FAILED被映射为NOSTATE状态,因此power_state目前有RUNNING、SHUTDOWN和NOSTATE三种状态。
Vm_state
- vmstate状态值是对虚拟机当前稳定状态的描述,而不是过渡状态。也就是说,如果针对特定虚拟机已经没有API继续调用,则应该用vmstate来描述此时虚拟机的稳定状态。
- 例如,当vmstate状态值为ACTIVE,则表示虚拟机正常运行。再如SUSPENDING状态,其表示虚拟机正处于挂起过程中,并且在几秒之后会过度到SUSPENDED状态,因此这是一种过渡状态,即SUSPENDING应该属于task_state的状态值。
- vmstate状态值更新的前提是针对此虚拟机有任务发生,并且任务成功完成(及task_state状态变为NOSTATE),同时taskstate被置为NOSTATE。
- 如果没有API调用发生,则vmstate状态值绝对不会改变;
- 如果对虚拟机的操作任务失败,但是成功回滚(rollback),则vmstate状态值也不会改变
- 如果不能回滚成功,则vmstate被置为ERROR状态。
vm_state 状态与 power_state 状态之间没有必然的对应关系
不一致的情况说明
序号 | power_state值 | vm_state 值 | 原因 |
---|---|---|---|
1 | SHUTDOWN | ACTIVE | 这种情况最可能的原因是虚拟机内部执行shutdonw命令时出现异常,解决这个问题一个简单粗暴的方法就是手动调用stop()API,之后,vm_state应该变为STOPPED。 |
2 | RUNNING | HARD_DELETE | 用户已经发出删除虚拟机的命令,但是执行过程出错,可以尝试再次删除虚拟机。 |
3 | RUNNING | PAUSED | 虚拟机在执行 pause()之前出现了意外情况,这个问题的解决办法就比较多样,可以尝试将其设为 ERROR。 |
task_state
task state 代表的是过渡状态,并且与调用的 API 函数密切相关,其状态值描述了虚拟机当前正在执行的任务。
只有对虚拟机发起了操作任务时,才会有task state 状态值出现, 而当vm_state 处于稳定值时,task_state 通常为 NOSTATE
特殊的force_delete(heard_delete)
- 正常的操作vm_state会随着任务的不同而变化着,直到最终的NOSTATE。
- force_delete()是个存储的数据库操作任务,对数据库的vm_stat字段操作完便结束了,而相应的虚拟机清除工作随后才进行
当任务被确认为虚拟机上唯一执行的任务时,taskstate就会被设置为具体的状态值。
虚拟机中每个正在执行的任务都会被分配一个与虚拟机相关的唯一task_id(UUID格式)。
如果虚拟机已经有个taskid,则表明有任务正在执行,要在任务执行中途更新taskstate,就必须确保虚机的taskid匹配当前的taskid,否则当前执行的任务会被抢占(目前只有forcedelete任务能抢占)。
通常在某个具体的任务执行期间,taskstate的值绝对不能改变。
当一个任务执行完成后,task_state被置为NOSTATE,而task_id被置为NONE。
task_state的状态值名称通常是代表某个API方法动词的正在进行时(“ing”形式)
Nova 实例迁移
冷迁移Resize/Migrate
- 由于 resize/migrate 操作在迁移过程中会关闭源主机上的实例,并在新的主机上重新启动实例.
- 因此resize/migrate对实例的迁移并非实时在线,而是先关闭实例再以copy镜像的形式迁移,迁移完成之后再在新的主机上启动实例.
- resize/migrate 迁移也称为“冷迁移”。如果虚拟机系统镜像较大而网络带宽受限时,则resize/migrate操作可能会花费一定的时间,而且在迁移时间段内不能访问虚拟机。
Resize | Migrate |
---|---|
提供新的资源配置flavor | migrate不提供flavor参数 |
- 对于 resize/migrate 操作,在迁移过程接近尾声,准备在目标主机启动实例和虚拟机状态为resized时,还有两个相关操作需要用户执行,即 confirm resize 和 revert resize。
- confirm resize 操作表示用户接受此次实例迁移操作,revert resize 表示用户不接受(反悔) 此次迁移操作。
- 如果用户需要 Nova 自动确认迁移操作,则可以将resize_confirm_window参数设置为某个大于0的时间值,当迁移完成并且虚拟机处于reszied的时间大于此参数值时,迁移操作将会被自动确认。
CLI下确认的命令
确认: nova resize-revert admin-instance3
回退: nova resize-confirm adrnin-instance3
当用户 执行 resize confirm 操作后,原实例镜像将被删除,而且再也不能回退
热迁移 live-migration
live-migration 迁 移按其实现方式可以划分为三种类型,即基于非共享存储的块迁移( block live migration)、 基于共享存储的迁移( Shared storage-based live migration)和基于 Volume 后端的迁移 ( Volume-backed live migration)。
后两种是使用最多的 live-migration方式,而块迁移在使用上一直存在很多问题,而且也不符合实时迁移的基本设计思想,故不推荐使用。
live-migration的准备工作
需要调整的参数
-
nova 配置文件/etc/nova/nova.conf
vncserver_proxyclient_address=l27.0.0.l vncserverlisten=0.0.0.0 //live_migrationflag是个即将抛弃的参数,可以不用设置 live_migration_flag=VIRMIGRATE_UNDEFINESOURCE,VIRMIGRATE_PEER2PEER
-
libvirt 配置文件/etc/libvirt/libvirtd.conf
//修改前 #listen_tls = 0 #listen_tcp = 1 #auth_tcp = "sasl" //修改后 listen tls = 0 listen_tcp = 1 auth_tcp= "none"
-
修改/etc/sysconfig/libvirtd
//修改前 #LIBVIRED_ARGS="--listen" //修改后 LIBVIRED_ARGS="--listen"
-
重启Nova和libvirtd进程
systemctl restart openstack-nova-compute systemctl restart libvirtd
基于Volume后端的实例迁移其实就是 对 SAN BOOT 形式的实例进行迁移,由于实例系统位于Volume而非临时磁盘上, 因此无须共享存储,其迁移过程就是将Volume从源主机卸载,并重新挂载到目标主机的过程。
所以需要检查目的主机资源是否足够
- 检查需要迁移instance的基本信息
- 检查volume1信息
- 确认主机资源是否足够
- 开始live-migration迁移 nova live-migration volume_bootable_server compute2
- 检查
与基于 Volume 后端的 live-migration不同,基于NFS的迁移需要计算节点之间共享实例镜像文件目录,通常是/var/lib/nova/instances,即每个计算节点都可以对共享的/var/lib/nova/instances目录进行读写。为了说明live-migration迁移会自动重新挂载实例的 Volume,在迁移前为实例nfs-server挂载一块大小lGB的Volume。基于NFS的live-migration操作步骤如下。
openstacke nova实例的高可用
openstack社区认为传统IT的高可用性并不适合现在的环境,既然选择了云计算,应该对服务器持“绵羊”式放养的心态才是未来IT的发展方向,而非传统的“宠物”服务器维护方式。
及应该用应用程序自己的集群和负责均衡系统,而非传统的底层服务器高可用性
故openstack一直不支持该项目,就当前的Openstack高可用部署环境,pacemaker结合corosync是使用较多的服务高可用监控工具。也还有redhat提出的pacmaker_remote
两者都基于之Evacute恢复/rebuild重建
openstacke nova实例的高可用之Evacute/rebuild
nova提供 Evacute API来隔离故障计算节点上的实例
本质上evacuate是对rebuild功能的扩展。
两者主要区别在,rebuild是刷新虚拟机镜像磁盘,使用新的镜像重新创建具有相同ID的实例,所以rebuild无须共享存储即可实现,更像是在相同硬件上重装系统。
evcuate是真正的还原,包括系统和用户数据。