openstack-nova笔记

在OpenStack中创建实例的大致流程为:

  1. 用户通过Dashboard界面或命令行发起实例创建请求,Keystone从请求中获取用户相关信息并进行身份验证
  2. 验证通过后,用户获得认证Token,实例创建请求进入Nova-api;
  3. 在向Keystone验证用户Token有效后,Novaapi将请求转入Nova-scheduler;
  4. Nova-scheduler进行实例创建目的主机的调度选择,目标主机选取完成后,请求转入Nova-compute;
  5. Nova-compute与Nova-conductor交互以获取创建实例的信息,在成功获取实例信息后,Nova-compute分别与Glance、Neutron和Cinder交互以获取镜像资源、网络资源和云存储资源;
  6. 一切资源准备就绪后,Nova-compute便通过LibvirtAPI与具体的Hypervisor交互并创建虚拟机

流程图

graph TD a[Dashboard/CLI] -->|1.获取token| b(keystone) b -->|2.返回token| a a --> |3.创建实例请求|c(Nova-api) c --> |3.1.检查token合法性|b b --> |3.2.认证通过|c c --> |3.3.image flavor neutorn是否合法|c c --> |6.请求转发至队列|d(Nova-scheduler) d --> |7.filter weight进行调度选择.确定目标主机|e(Nova-compute) e --> |8.请求存储| f(glance) e --> |8.请求网络| g(Neutron) e --> |8.请求镜像| h(Cinder) f --> |9.返回|e g --> |9.返回|e h --> |9.返回|e e --> |10.通过Libvirt API创建虚拟机| i(Hypervisor)

keystone内流程

sequenceDiagram participant Client participant Keystone participant LDAP participant Token Store Client->>Keystone: Authentication Request Keystone->>LDAP: auth LDAP-->>Keystone:request Keystone->>Token Store: save token Token Store-->>Keystone:request Keystone-->>Client: auth token

nova-api工作流程

sequenceDiagram Client->>Nova_api: launch instance Nova_api->>Keystone: Token verification Keystone-->>Nova_api: reply Nova_api->>Nova_api: image flavor neutorn是否合法 Keystone->>Nova_DB: Create initial entry /vm_states=building task_state=scheduling Nova_DB-->>Keystone: reply Nova_api->>MQ: [rpc.cast] to request new instance (rpc dont have reply!!) Nova_api->>Client: instance request complete

nova-api函数调用过程

以下全位于nova-api内:
身份认证成功后

graph TD 1[位于nova/api/openstack/compute/servers.py的函#数ServersContorller.create]-->|1|2[位于nova/compue/api.py的函数#API.create] 2-->|2|3[位于nova/compue/api.py的函数#API._create_instance] 3-->|3|4[位于nova/compue/api.py的函数#API._provision_instances] 4-->|4|5[位于nova/compue/api.py的函数#API.create_db_entry_for_new_instance] 5-->6[Nova.DB] 5-->|7|3 3-->|8|7[位于nova/conductor/api.py的函数#ComputeTaskAPI.build_instances] 7-->|9|8[位于nova/conductor/rpcapi.py的函数#COMputeTaskAPI.build_instances] 8-->|cast to topic:condistor|9[MQ]

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的消息队列中
sequenceDiagram Nova_compute->>MQ: subcribe new instance reques Nova_compute->>MQ: rpc.call to nova_conductor to fetch the instance info Nova_conductor->>MQ: Subcribe new instance request Nova_conductor->>MQ: Publish selected host request MQ->>Nova_scheduler:Subcribe selected host request Nova_scheduler->>Nova_conductor: selected host Nova_conductor->>DB: Read instance state Nova_conductor->>MQ:Publish new instance state Nova_compute->>MQ: Subcribe new instance request

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调用过程
sequenceDiagram Nova_conductor->>MQ: Publish selected host request Nova_scheduler->>MQ: Subcribe selected host request Nova_scheduler->>DB: read filtering and weighing infQ Nova_scheduler->>DB: Read cluster state Nova_scheduler->>DB: Read instance state Nova_scheduler->>MQ: rpc.cast selected hosts MQ->>Nova_conductor: Subcribe selected host request Nova_scheduler->>MQ: rpc.cast to launch instance

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存储集群。
sequenceDiagram Nova_compute->>Glance_api:REST get image URI by Image ID from glance Glance_api->>Keystone: Vaildata token and permissions Keystone-->>Glance_api: updated auth headers with roles and acl Glance_api->>Nova_compute: return image URL Nova_compute->>ceph_mon: get cluster map ceph_mon->>Nova_compute: return cluster map Nova_compute->>ceph_rgw: REST request object ceph_rgw->>ceph_osd: socket get object ceph_rgw->>Nova_compute:return object Nova_compute->>Cinder_api: REST get volume data Cinder_api->>Keystone:vaildate token and permissions Keystone-->>Cinder_api: updated auth headers with roles and acl Cinder_api->>Nova_compute:return volume info
  • 在获取镜像和存储资源后,Nova-compute还需与OpenStack的网络服务项目Neutron进行交互访问以获取网络资源。由于网络资源的有效性和可用性已经在Nova-api工作流程中完成,这里主要是获取虚拟机的FixedIP等网络资源

Nova-compute 与 Neutron 交互获取网络资沥

sequenceDiagram Nova_compute->>Neutron_server:allocate分配 and configure the network for instance Neutron_server->>MQ: request IP Neutron_server->>MQ: request L2 config Neutron_DHCP_agent->>MQ: read request IP Neutron_DHCP_agent->>dnsmasq: allcate分配 IP dnsmasq->>Neutron_DHCP_agent: reply Neutron_DHCP_agent->>MQ: repay IP Neutron_server->>MQ: read IP Neutron_L2_agent->>MQ:read request L2 config Neutron_L2_agent->>libvirt: config L2 Neutron_L2_agentt->>MQ:repay L2 config Neutron_server->>DB: save instance network state Neutron_server->>Nova_compute: pass network info

在准备好常见实例所需的一切资源后, Nova-compute将通过Libvirt与对应的Hypervisor API进行交互,并通过Libvirt API 接口进行虚拟机的创建工作.

Nova-compute 与 Libvirt 交互创建实例的过

sequenceDiagram Nova_compute->>libvirt: start VM Nova_compute->>libvirt: port_update Nova_compute->>MQ: rpc.call to Nova_conductor to fetch获取 the instance info Nova_conductor->>MQ: subcribe 确收new instance request Nova_conductor->>MQ: publish new instance state Nova_compute->>libvirt:pass volume info libvirt->>ceph_mon: get cluster map ceph_mon->>libvirt: return cluster map libvirt->>ceph_osd: mount volume

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的准备工作

需要调整的参数

  1. 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
    
  2. libvirt 配置文件/etc/libvirt/libvirtd.conf

     //修改前
     #listen_tls = 0
     #listen_tcp = 1
     #auth_tcp = "sasl"
     
     //修改后
     listen tls = 0
     listen_tcp = 1 
     auth_tcp= "none"
    
  3. 修改/etc/sysconfig/libvirtd

     //修改前
     #LIBVIRED_ARGS="--listen"
     //修改后
     LIBVIRED_ARGS="--listen"
    
  4. 重启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是真正的还原,包括系统和用户数据。

posted @ 2020-01-10 13:29  暴走的馒头  阅读(1059)  评论(0编辑  收藏  举报