openstack 笔记

OpenStack

IaaS(Infranstracture As A Service) : 基础设施服务,这个阶段实现了时间灵活性和空间灵活性,实现了计算,网络,存储资源的弹性,称此为资源层面的弹性,管理资源的云平台,称为基础设施服务,这层的作用是提供虚拟机或者其他资源作为服务提供给用户。
Paas (Platform As A Service):平台服务,把服务器平台或者开发环境作为一种服务提供的商业模式,通过PaaS这种模式,用户可以在一个包括SDK,文档和测试环境等在内的开发平台上非常方便地编写应用,而且不论是在部署,或者在运行的时候,用户都无需为服务器,操作系统,网络和存储等资源的管理操心,这些繁琐的工作都由PaaS供应商负责处理,这层的作用是将开发平台作为服务提供给用户。
SaaS (Software As A Service):软件服务,用户只要接上网络,并通过浏览器,就能直接使用在云端上运行的应用,而不需要顾虑类似安装等琐事,并且免去初期高昂的软硬件投入。这层的作用是将应用作为服务提供给客户。

在这里插入图片描述

openstack 是一个云计算平台,他能管理数据中心的大量计算 存储 网络资源,并且向用户提供一个管理资源的Web界面,同时提供功能相同的命令行 和 RESTful API接口

在这里插入图片描述

一 、 OpenStack 的基本架构:
在这里插入图片描述
在这里插入图片描述

组件简介

Heat 组件

位于最上层,这个组件的主要作用是对OpenStack
中的资源进行编排,例如,通过Heat组件,我们可以编排出网络资源,也可以编排出存储资源,还可以编排出虚拟机资源。但最常使用的还是用Heat进行系统编排,例如,通过Heat可以编排出弹性扩缩容的主机组,也可以编排出Redis集群,还可以编排出负载均衡器等。随着OpenStack
组件的不断发展,Heat现在还可以对容器进行编排。 Horizon 组件
这个组件的主要作用是提供OpenStack的UI服务,可以对OpenStack中的资源进行可视化展示,对于OpenStack
的用户而言,通过Horizon可以很方便地创建诸如虚拟机、网络、存储等资源而不需要记忆烦琐的命令。这个组件极大地提高了OpenStack的易用性。

Neutron 组件

这个组件用来提供OpenStack
中的网络相关的服务,比如,创建Network、Subnet、防火墙、安全组等。这个组件也是OpenStack
中比较复杂的一个组件,参与这个组件开发的人员众多,代码的风格也不尽相同,所以如果想学习OpenStack
代码的话,不建议从这个组件入手,可以从Nova组件入手。 Cinder 组件 为OpenStack提供块存储服务

Nova 组件

为OpenStack提供计算服务,通过这个组件可以在OpenStack 中创建虚拟机,可以选择不同CPU/RAM的配置来创建虚拟机。

Glance 组件

提供镜像服务,通过Glance提供的镜像一般会被Nova创建虚拟机时使用。

Swift 组件

提供对象存储服务。

Ceilometer 组件

提供数据监控与告警服务。这里需要注意的是,在Ocata版以后的版本中,Ceilometer组件的功能(如数据存储、告警)被拆分了出去,分别由其他组件负责,Ceilometer更多的关注于数据的采集。

Keystone 组件

这是一个与其他组件交互最多的组件,它的主要功能是为其他组件提供认证服务,用户只有通过了Keystone的认证才有资格执行其他操作。例如,Nova创建虚拟机时,需要通过Glance来获取镜像,Nova
发送请求时需要从Keystone中获取认证信息,当Glance接收到Nova的请求,需要拿认证信息到Keystone中再次确认。

组件运行步骤:

在这里插入图片描述

  • 登录界面或命令行通过RESTful API向keystone获取认证信息。
  • keystone通过用户请求认证信息,并生成auth-token返回给对应的认证请求。 界面或命令行通过RESTful
  • API向nova-api发送一个boot instance的请求(携带auth-token)。
  • nova-api接受请求后向keystone发送认证请求,查看token是否为有效用户和token。
  • keystone验证token是否有效,如有效则返回有效的认证和对应的角色(注:有些操作需要有角色权限才能操作)。
  • 通过认证后nova-api和数据库通讯。 初始化新建虚拟机的数据库记录。
  • nova-api通过rpc.call向nova-scheduler请求是否有创建虚拟机的资源(Host ID)。
  • nova-scheduler进程侦听消息队列,获取nova-api的请求。
  • nova-scheduler通过查询nova数据库中计算资源的情况,并通过调度算法计算符合虚拟机创建需要的主机。
  • 对于有符合虚拟机创建的主机,nova-scheduler更新数据库中虚拟机对应的物理主机信息。
  • nova-scheduler通过rpc.cast向nova-compute发送对应的创建虚拟机请求的消息。
  • nova-compute会从对应的消息队列中获取创建虚拟机请求的消息。
  • nova-compute通过rpc.call向nova-conductor请求获取虚拟机消息。(Flavor)
  • nova-conductor从消息队队列中拿到nova-compute请求消息。
  • nova-conductor根据消息查询虚拟机对应的信息。 nova-conductor从数据库中获得虚拟机对应信息。
  • nova-conductor把虚拟机信息通过消息的方式发送到消息队列中。 nova-compute从对应的消息队列中获取虚拟机信息消息。
  • nova-compute通过keystone的RESTfull
  • API拿到认证的token,并通过HTTP请求glance-api获取创建虚拟机所需要镜像。
  • glance-api向keystone认证token是否有效,并返回验证结果。
  • token验证通过,nova-compute获得虚拟机镜像信息(URL)。 nova-compute通过keystone的RESTfull
  • API拿到认证k的token,并通过HTTP请求neutron-server获取创建虚拟机所需要的网络信息。
  • neutron-server向keystone认证token是否有效,并返回验证结果。
  • token验证通过,nova-compute获得虚拟机网络信息。 nova-compute通过keystone的RESTfull
  • API拿到认证的token,并通过HTTP请求cinder-api获取创建虚拟机所需要的持久化存储信息。
  • cinder-api向keystone认证token是否有效,并返回验证结果。
  • token验证通过,nova-compute获得虚拟机持久化存储信息。
  • nova-compute根据instance的信息调用配置的虚拟化驱动来创建虚拟机。

二 、

OpenStack 的核心组件

一) 计算资源管理 : Nova 组件

Nova是OpenStack中最早的核心组件之一,主要负责OpenStack 中的计算服务,直白点儿说就是它主要服务于虚拟机,对虚拟机的生命周期进行管控,但Nova本身并不会提供任何虚拟化能力,它仅仅是调用相关的API与第三方 Hypervisor进行交互。

当Nova进行虚拟机生命周期管理时,同样也需要与OpenStack 中的其他组件进行交互。虚拟机创建过程中,首先需要有相应的镜像,虚拟机获取镜像的方式是调用Glance 的API 从 Glance中获取镜像;其次虚拟机中网络创建时,Nova也需要调用Neutron的相关API进行创建。

在OpenStack 中比较重要的一点就是,当需要调用相关组件的API时,首先要做的事情就是得通过Kestone的认证,当通过认证拿到Token后,才能再去调用其他组件,同样的,当其他组件收到REST请求后,需要拿这个Token再次到负责认证的组件进行二次认证,只有通过认证后,此组件才会为其他组件提供服务。
作为OpenStack的核心组件之一,Nova的主要功能和特点如下:

  • 虚拟机生命周期管理;
  • 提供REST风格API;
  • 使用RPC进行通信;
  • 管理计算资源;
  • 支持不同的虚拟化方式。

为方便对虚拟机生命周期进行管理,Nova内部维护了一个针对虚拟机的状态机,从虚拟机开始创建到最终的删除操作,都有相应的状态与之对应。虚拟机创建成功后,会在数据库中存放一条与之对应的记录;当虚拟机被删除时,与虚拟机相关的记录会被“软删除”,即记录还是存在的,只是这条记录中的某个字段被设置为1,用以表示此记录被删除。

图1.3简单列出了Nova中虚拟机的一些状态。这个状态并非虚拟机的全部状态,只是列出了其中比较常用的几种,有关虚拟机的所有状态信息,可以参考Nova的代码: nova/compute/vm_states.py,里面是虚拟机的所有状态。
在这里插入图片描述

对于虚拟机而言,有三类状态我们需要特别关注一下:

  • 虚拟机状态(VM State);
  • 任务状态(Task State);
  • 电源状态(Power State)

以上三类状态分别可以从 novalcompute/vm_states.py 、nova/compute/task_states.py和 novalcompute/power_state.py中查看到详细信息。以上三类状态有助于对出现的问题虚拟机进行排查,因为根据出错时的状态,大致可以推测出虚拟机出错的原因并给出解决方案。

注意:上述只是虚拟机的部分状态,在实际的应用场景中,虚拟机还有许多状态,所有状态都依靠Nova自身的状态机来实现。

Nova组件本身代码逻辑相对其他代码比较清晰,并且它在进行虚拟机创建时会涉及到与其他组件的交互,所以,读者如果想要了解代码的话,可以从这个模块入手。

二) 存储资源管理:Cinder/Swift 组件

Cinder 和Swift是为OpenStack 提供存储服务的两个组件,虽然它们都可以提供存储服务,但是二者还是有较大差别的,前者提供的是块存储,后者提供的是对象存储。与其他组件类似,它们也是通过REST API为别的组件提供服务。

  1. Cinder 组件
    我们知道,对于操作系统而言,存储空间一般可以有两种方式。第一种是通过诸如 iSCSI*、SAN等协议,将裸盘直接挂载到虚拟机上,然后对这个磁盘分区、格式化及创建文件系统等;第二种是通过 NFS* 等协议远程挂载文件系统。像第一种这样挂载裸盘的方式叫作块存储,每一块裸盘也被称为卷( Volume)。

iSCSI协议是一个C/S结构,主要功能是利用TCP/IP网络,在主机系统(可称为initiator)和目标存储设备(称为target)之间进行大量的数据封装和可靠传输过程。此外,iSCSI协议还将SCSI协议封装在IP网络上,并且运行在TCP上
NFS协议是一种用于文件共享的协议,它可以使得主机之间进行文件的共享。客户端可以像在本机上的文件一样操作远程主机的文件。NFS协议最初仅支持UDP协议,目前最新版本的NFS可以支持UDP和TCP协议,不过UDP协议的速度会更快。

Cinder的基本功能如下:

  • 创建/删除Volume;·
  • 从快照创建Volume;
  • Volume QoS设置;
  • 镜像与Volume相互复制;
  • 转移Volume的所有权;
  • 支持不同的Volume 驱动。

在OpenStack中,Cinder默认情况下只会支持LVM这一类型的存储后端。在实际的应用场景中,这样的使用方式往往不能满足用户的需求,云环境下用户对存储的需求是多种多样的,针对用户需求,Cinder也开始支持多存储后端。
Cinder支持配置多个后端,各个后端可以配置成SATA磁盘组成的容量存储池、SAS/SSD磁盘组成的性能存储池,也可以使用传统存储阵列SAN组成一个存储池,还可以用开源SDS存储,如用Ceph、GlusterFS等作为后端存储。Cinder的多后端能力,为构建完整的存储解决方法提供了可行的途径,配置多后端之后,OpenStack会为每个后端启动一个cinder-volume服务。

  1. Swift 组件
    Swift是OpenStack 中比较成熟的一个组件,它的功能类似于一个分布式的存储平台,对外提供REST API进行访问,它不但可以集成到应用程序中,同时,还可以存储或归档一些比较小的文件。
    在Swift 中有两个比较重要的概念:对象和容器。对象就是存储的实体,当我们把一个文件通过Swift存储时,实际上Swift 会把这个文件进行切片,然后把这个数据片分别存放到不同的磁盘中,这样做可以极大地提高数据的安全性。而容器类似于Windows中文件夹的概念,对象必须存放在容器中。
    Swift采用分层的数据模型,除了对象和容器的逻辑结构外,还包含名为“账户”的逻辑结构,其分层的数据模型如图1.4所示。

在这里插入图片描述

与传统的文件服务器不同,Swift可以在多个系统中进行分布式存储。它会自动存储每个对象的多个副本,最大限度地提高可用性和可扩展性。对象版本控制为防止数据意外丢失或覆盖提供了额外保护。

三) 网络资源管理:Neutron组件

Neutron为OpenStack 提供了网络服务,它可以说是OpenStack 中最为复杂的一个组件了。Neutron可以提供多种网络功能,比如一些基础功能:防火墙、路由器、网络和子网等,还有一些高级功能,如负载均衡、VPC等。不过需要注意的一点是,Neutron组件中的大部分网络功能,都是通过插件的形式来实现的,但像是DHCP这样的功能除外。从功能上而言,如图1.5所示,Neutron可以分成两部分:提供REST API和运行相应的Plugin(插件)。

在这里插入图片描述

Neutron按照三层交换机的概念,把网络分为了如下三种。

  • Network:它类似于交换机根据不同的VLAN创建的一个三层接口,不同的网络可以通过VLANtag 进行包的转发与流量控制。
  • Subnet:它属于某一个Network,创建一个Subnet就相当于交换机创建了一个三层的接口地址。
  • Port:它相当于交换机的一个物理端口,需要与某一个Subnet 相关联,即 Neutron 会从Subnet中为某个Port分配IP;对于虚拟机而言,如果一个Port被绑定到了虚拟机上,那么可以把Port看成是它的一块网卡,与正常的网卡一样,Port也是MAC地址的。

Neutron不同租户创建的网络可以通过VLAN或VxLAN实现天然隔离,即默认情况下,不同租户中的网络是相互隔离的。图1.6总结了Neutron中一些核心的数据模型。

从图1.6可以看出,端口在Neutron中实际上处于很重要的位置,首先,它可以作为虚拟机的网卡,绑定内网IP和Floating IP;其次,它还可以作为路由器的端口,与路由器绑定;第三,我们可以在端口上绑定安全组,进而实现对虚拟机的访问端口的控制。

端口中的IP是从子网上分配的,而Floating IP是从外部网络上分配得到。当把 Floating IP绑定到某个端口上后,这个端口就可以从外部进行访问了。还需要注意的一点就是,端口与子网是一对多的关系,即某个端口必须属于某个子网,一个子网可以有多个端口。

在这里插入图片描述

Neutron仅由一个主要的服务进程Neutron-server,它运行于控制节点
Neutron-server对外提供Openstack网络API作为Neutron的入口,收集请求后调用plugin(插件)进行处理,最终由计算节点和网络节点上的各种agent(代理)完成请求

network-provider(网络提供者)是指提供OpenStack网络服务的虚拟机或者物理网络设备,比如Linux Brigde、Open vSwitch或者其他支持neutron的物理交换机。与其他的五福一样,Neutron的各个组件服务之间需要相互协调通信,Neutron-server、插件之间通过消息队列(默认用RabbitMQ实现)进行通信和相互协调
Neutron-database(数据库,默认使用MariaDB)用于存放OpenStack的网络状态信息,包括网络、子网、端口、路由器等
Client(客户端)是指使用Neutron服务的应用程序,可以是命令行工具(脚本)、Horizon和Nova计算服务等

在这里插入图片描述

四) 认证服务管理:Keystone组件

User:指使用Openstack service的用户,可以是人、服务、系统,但凡使用了Openstack service的对象都可以称为User。
Project(Tenant):可以理解为一个人、或服务所拥有的 资源集合 。在一个Project(Tenant)中可以包含多个User,每一个User都会根据权限的划分来使用Project(Tenant)中的资源。比如通过Nova创建虚拟机时要指定到某个Project中,在Cinder创建卷也要指定到某个Project中。User访问Project的资源前,必须要与该Project关联,并且指定User在Project下的Role。
Role:用于划分权限。可以通过给User指定Role,使User获得Role对应的操作权限。Keystone返回给User的Token包含了Role列表,被访问的Services会判断访问它的User和User提供的Token中所包含的Role。系统默认使用管理Role admin和成员Role member
Policy:OpenStack对User的验证除了OpenStack的身份验证以外,还需要鉴别User对某个Service是否有访问权限。Policy机制就是用来控制User对Tenant中资源(包括Services)的操作权限。对于Keystone service来说,Policy就是一个JSON文件,默认是/etc/keystone/policy.json。通过配置这个文件,Keystone Service实现了对User基于Role的权限管理。
Token:是一个字符串表示,作为访问资源的令牌。Token包含了在 指定范围和有效时间内 可以被访问的资源。EG. 在Nova中一个tenant可以是一些虚拟机,在Swift和Glance中一个tenant可以是一些镜像存储,在Network中一个tenant可以是一些网络资源。Token一般被User持有。
Credentials:用于确认用户身份的凭证
Authentication:确定用户身份的过程
Service:Openstack service,即Openstack中运行的组件服务。
Endpoint:一个可以通过网络来访问和定位某个Openstack service的地址,通常是一个URL。比如,当Nova需要访问Glance服务去获取image 时,Nova通过访问Keystone拿到Glance的endpoint,然后通过访问该endpoint去获取Glance服务。我们可以通过Endpoint的region属性去定义多个region。Endpoint 该使用对象分为三类:
admin url –> 给admin用户使用,Post:35357
internal url –> OpenStack内部服务使用来跟别的服务通信,Port:5000
public url –> 其它用户可以访问的地址,Post:5000
创建完service后创建API EndPoint. 在openstack中,每一个service都有三种end points. Admin, public, internal。 Admin是用作管理用途的,如它能够修改user/tenant(project)。 public 是让客户调用的,比如可以部署在外网上让客户可以管理自己的云。internal是openstack内部调用的。三种endpoints 在网络上开放的权限一般也不同。Admin通常只能对内网开放,public通常可以对外网开放internal通常只能对安装有openstack对服务的机器开放。
一个实例:
用户alice登录keystone系统(password或者token的方式),获取一个临时的token和catalog服务目录(v3版本登录时,如果没有指定scope,project或者domain,获取的临时token没有任何权限,不能查询project或者catalog)。
alice通过临时token获取自己的所有的project列表。
alice选定一个project,然后指定project重新登录,获取一个正式的token,同时获得服务列表的endpoint,用户选定一个endpoint,在HTTP消息头中携带token,然后发送请求(如果用户知道project name或者project id可以直接第3步登录)。
消息到达endpoint之后,由服务端(nova)的keystone中间件(pipeline中的filter:authtoken)向keystone发送一个验证token的请求。(token类型:uuid需要在keystone验证token,pki类型的token本身是包含用户详细信息的加密串,可以在服务端完成验证)
keystone验证token成功之后,将token对应用户的详细信息,例如:role,username,userid等,返回给服务端(nova)。
服务端(nova)完成请求,例如:创建虚拟机。
服务端返回请求结果给alice。

三 、虚拟化

虚拟化的现状:
虚拟化是构建云基础架构不可缺少的关键技术之一。对于云计算而言,它就是一个分布式系统;而对于虚拟化而言,它可以为云平台提供虚拟化的能力,在这个分布式系统中虚拟出更多的虚拟设备或虚拟平台,而这些虚拟出的平台或设备,又可以独立作为一个平台或设备对外提供服务。通过云计算与虚拟化的结合,用户可以极大地提高其对物理设备的管控能力及利用率。
虽然云计算只是近几年才兴起的热门名词,但它并非是一个非常新的技术。实际上在早期,就已经有与云计算相近似的概念,只是碍于当时计算机和网络技术的发展,许多都只是停留在研究上,云计算的发展没有形成气候。
虚拟化实际上是一个比较宽泛的概念,虚拟机仅仅是虚拟化技术的一种体现。从更加广泛的角度去理解,虚拟化其实就是把计算机中的物理设备放到虚拟的基础上去运行、去提供服务,而不是在物理的基础上去实现其功能。
1.虚拟化的角度
按虚拟化的角度不同,虚拟化技术又分为软件虚拟化和硬件虚拟化,前者即为软件方案,后者即为硬件方案。
(1)软件方案,顾名思义,就是使用纯软件的技术,实现物理平台对物理平台访问的模拟,常见的软件虚拟化有QEMU,它是通过纯软件来实现对x86平台上处理器的取指、解码与执行等操作;VMWare也可看作是一种纯软件的虚拟化技术,它与QEMU不同的是,它使用了动态二进制翻译的技术。
(2)硬件方案,就是结合了软件虚拟化和硬件虚拟化技术,通过二者共同完成对处理器的模拟。
2.虚拟化的程度
按虚拟化的程度不同,虚拟化技术又可以分为半虚拟化和全虚拟化。
对于非专业人员,面对虚拟化方案,可能会感到一头雾水,并且,对于上层开发人员而言,如果再让他们从事底层虚拟化的开发,势必会导致产生层次水平不同的虚拟化方案。
在OpenStack中谈及虚拟化,不得不提KVM。KVM是一个虚拟机管理程序,它是基于虚拟化扩展的x86硬件,现已集成到Linux内核中,由标准的Linux调度程序进行调度。它可以具备内存管理、存储、设备驱动及可伸缩性等特点。
除了KVM虚拟化外,目前的虚拟化产品还有Xen、VMWare、VirtualBox、Hyper-V等。

KVM 的管理工具Libvirt:
Libvirt*是一套对平台虚拟化技术进行管理的管理工具和Linux API。作为连接底层多种虚拟机管理器(Hypervisor)与上层应用的中间适配层(见图3.1),它可以支持KVM、Xen、QEMU、VirtualBox等多种虚拟机管理器。
* libvirt是什么?从字面上看,由lib和virt两部分组成。lib是指库library的缩写,virt是虚拟化virtualization的缩写,所以他的定位是“虚拟化的库”。它是一套开源的API、管理工具,用来管理虚拟化平台。可以应用在KVM、XEN、VMware ESX、QEMU等虚拟化技术,在OpenStack Nova中,默认采用libvirt对不同类型的虚拟机(OpenStack默认KVM)进行管理。

在这里插入图片描述

对于OpenStack、virsh、virt-manager而言,其底层虚拟化接口及虚拟机管理功能也是通过调用Libvirt APl来实现的。Libvirt通过提供一个统一的API接口,对底层不同Hypervisor的实现细节进了屏蔽。
在这里插入图片描述

另外,Libvirt 采用过一种基于驱动(Driver)的架构(见图3.2),来实现对多种不同Hypervisor 的支持,即每种 Hypervisor 都需要提供一个Driver,这个Driver可以借助Libvirt操控特定的虚拟机。
在这里插入图片描述

Libvirt是通过C语言实现的一套应用程序接口,但同时也支持像Python、Perl、Ruby、Java等程序库,故它可以在不同的环境中集成与使用。
Libvirt中的主要模块有API库、命令行工具virsh和后台deamon程序Libvirtd。通过Libvirt 提供的API库,一些诸如virsh的管理工具可以管理各种不同的Hypervisor 及它上面运行的虚拟机,它们之间的层次结构如图3.3所示。

在这里插入图片描述

Libvirt中主要支持的功能包括:
(1)虚机管理。可以实现对各个节点上的虚拟机(域)进行生命周期及多种设备类型的管理。(nova)
(2)存储管理。在运行了Libvirtd的机器上,可以通过Libvirt 来操作卷、挂载 iSCSI共享存储、创建镜像等。(Cinder/Swift)
(3)网络管理。可以管理物理网络接口和虚拟网络接口,并且支持虚拟NAT和基于路由的网络。(Neutron)
(4)远程节点管理。可以对远程节点进行管理。

Libvirt 的体系结构
在讲解 Libvirt 的体系结构之前,不妨让我们先看一下在没有Libvirt的情况下,虚拟机的管理方式,如图3.4所示。
在该模型中,处于底层的是整个物理硬件系统,主要是我们常见的CPU、RAM 及IO 等,硬件系统上运行着Host OS和 Hypervisor。Hypervisor 的主要作用就是对真实的物理平台进行管理,与此同时,它也为每个虚拟机(Guest OS)提供虚拟硬件平台。
该模型存在一个比较严重的缺点:平台的可扩展性在一定程度上受到了限制,因为对于不同的Hypervisor,应该会有各自不同的Driver来实现硬件平台的虚拟。
为了能够提高平台的可扩展性以及对不同的 Hypervisor进行支持,Libvirt 实现了一组API来对不同的Hypervisor进行封装,并且通过一种虚拟机监控程序的特定机制与每个有效虚拟机监控程序进行通信,以完成API 请求。图3.5展示了Libvirt API与相关驱动程序的层次结构。

  • GuestOS:VM(虚拟机)里的的系统(OS)
  • HostOS:物理机里的系统(OS)
  • Node:物理主机或物理节点
  • Domain:虚拟机实例、Guest OS或虚拟机。在Xen中 Domain 0表示宿主机系统;在KVM中,Domain完全指虚拟机系统。
  • Hypervisor:虚拟机管理器( VMM),如KVM、Xen、Hyper-V等
    在这里插入图片描述

对于每一个Libvirt的连接,我们都可以把它看成是一个C/S模型,其中,在Server(服务器)上运行着Hypervisor,Client(客户端)会主动去连接Server 上的Hypervisor,并且实现相应的虚拟化管理的功能。当然,对于图3.5所示的通过Libvirt API实现本地化管理模型而言,Server与Client都在同一台物理节点上,它们之间的连接不会依赖于网络。
除了Libvirt API之外,另外一个比较关键的是Libvirtd。它是一个运行在Server 上的后台进程,Client可以通过连接到Libvirtd 来实现管理操作。根据虚拟机管理应用程序与虚拟机是否在同一节点上,我们可以把Libvirt 的控制方式分成两种:本地控制和远程控制。
1.本地控制
如图3.5所示,管理应用程序(Mgmt APP)与虚拟机(图中是Domain)位于同一个Node 上。关于本地控制的方式不作详解,只介绍Libvirt 中比较重要的几个概念。
(1) Node:物理主机或物理节点。
(2) Domain:虚拟机实例、Guest OS或虚拟机。在Xen中 Domain 0表示宿主机系统;在KVM中,Domain完全指虚拟机系统。
(3) Hypervisor:虚拟机管理器( VMM),如KVM、Xen、Hyper-V等。
2.远程控制
如图3.6所示,管理应用程序(Mgmt APP)和域(Domain)位于不同节点(Node)上时,本例中,需要进行远程RPC通信(如图3.6中虚线所示)。

在这里插入图片描述

该模式需要借助运行于远程节点上的Libvirtd这一特殊守护进程。此守护进程会随着Libvirt 的安装而自动启动,可自动确定本地虚拟机监控程序并为其安装驱动程序。该管理应用程序通过RPC从本地Libvirt连接到远程Libvirtd。对于QEMU,协议在QEMU 监视器处结束。QEMU包含一个监测控制台,它允许检查运行中的虚拟机操作系统并控制虚拟机(VM)各部分。
不过,并不是所有的Hypervisor都需要运行Libvirtd守护进程,像VMWare ESX和ESXi就不需要在 Server上运行这一进程,在此不做详细介绍。
目前,Libvirt实现了以下几种类型的Driver,每一种类型的 Driver 代表对某种功能模块的抽象封装:
虚拟化驱动( virDriverPtr)
虚拟网络驱动( virNetworkDriverPtr)
物理网卡驱动( virInterfaceDriverPtr)
存储驱动(virStorageDriverPtr)
监控驱动( virDeviceMonitorPtr)
安全驱动( virSecretDriverPtr)
过滤驱动( virNWFilterDriverPtr)
状态驱动( virStateDriverPtr)

openstack和虚拟化的结合:
OpenStack是一个开源的云管平台,它自身并不会提供实现虚拟化的技术,在OpenStack 中进行虚拟机创建等虚拟化功能是通过与之连接的Hypervisor 来实现的。Nova是OpenStack 中与虚拟化技术联系比较密切的组件,它提供了一种Virt Driver 的开源框架,借助此框架,它可以实现各种虚拟化。
注意:OpenStack中与虚拟化相关的功能主要集中在Nova组件中,这里所说的虚拟化是指相关的虚拟机。
当我们部署完OpenStack后,可以通过/etc/nova/nova.conf 来配置底层所调用的VirtDriver。假如我们想使用Libvirt 的 Driver,可以在 nova-compute服务所在的节点上,对nova.conf做修改,修改compute_driver 的值为 libvirt.LibvirtDriver,如下:
[root@jeguan-cmpt-01 ~]# cat /etc/nova/nova.conf l grep compute_drivercompute_driver=libvirt.LibvirtDriver
对于不同的用户而言,单一的Hypervisor Dirver可能无法满足用户需求。有时客户为了避免受单一产品供应商的限制,他们往往会使用多种Hyervisor;另外,现行的单一的Hypervisor有时并不能满足用户对虚拟化功能的需求。随着虚拟化技术的成熟度越来越高,multi-hypervisor的云平台环境逐渐成为可能。
通过图3.7我们能够很容易地看到,OpenStack 可以利用Libvirt 实现对多种Hypervisor的操作,同时也支持直接调用原生的API进行操作。

在这里插入图片描述

这里需要说明的是,OpenStack宣称兼容EC2*的API。兼容的意思就是说,假如你以前开发了一套操作EC2的软件,利用了EC2的API,那么你可以无缝把这个软件应用到OpenStack里。

  • EC2(elastic compute cloud,弹性计算云),即云中的虚拟服务器。 是用于在云中创建和运行虚拟机的 Amazon Web 服务。简言之,EC2就是一部具有无限采集能力的虚拟计算机,用户能够用来执行一些处理任务。EC2是一种可选择的虚拟集群的服务模型。本质是运行在云中虚拟机上的web服务。EC2实例的本质是云上的虚拟机
    除此之外,OpenStack 所说的公有云和私有云管理,并不是可以管理第三方公有云,而是企业可以借助OpenStack,搭建云管平台,对外提供服务,自己作为公有云厂商。
    前一小节,我们提到过Libvirt 提供了很好的Python绑定,那么下面我们以Nova为例,简单看一下OpenStack 如何与Libvirt进行交互。
    Nova创建虚拟机的过程比较复杂,这里只介绍Nova如何实现对Libvirt的调用。
    创建虚拟机时,Nova最终通过nova-compute服务调用到LibvirtDriver类的spawn()函数。
    在这里插入图片描述

在这个函数中,会执行获取磁盘信息、创建虚似机所需要的镜像等,由于spawn()中的实现代码比较长,我们只关注其中与本节相关的关键部分:

在这里插入图片描述

上述代码中,_get _guest_xml)函数的主要作用是生成创建虚拟机所需要的XML,在XML中同时指定了虚拟机所需要的CPU/RAM/Disk等信息;然后通过_create_domain_and_network 来创建虚拟机的网络;最终通过launch()函数调用Libvirt方法中的createWithFlags()来创建并启动虚拟机。

在这里插入图片描述
在这里插入图片描述

其中,virDomainCreateWithFlags()是Libvirt 的Python接口。根据Libvirt API的不同功能,我们可以将它们划分成5类: Hypervisor连接管理APl ( virConnectPtr)、Domain管理API (virDomainPtr)、网络API (virNetworkPtr)、存储卷API (virStorageVolPtr)、存储池API (virStoragelPoolPtr),这5者之间的关系如图3.8所示。
在这里插入图片描述

virConnectPtr:负责建立与Hypervisor的连接。其他所有API都要依靠这个连接提供各自的功能。与Hypervisor连接的建立是通过函数virConnectPtr=virConnectOpen()实现的,virConnectPtr的对象作为返回值,可以被其他API调用。Libvirt中并发调用通过 virConnectGet Capabilities()和virNodeGetInfo()接口实现,前者返回相应Hypervisor和驱动程序的功能,后者可以获取有关节点的信息。
virDomainPtr:表示一个处于active或defined(即以配置文件和存储状态存在,但是目前并没有在物理节点上启动的虚拟机。这里的“配置文件”也称为虚拟机定义文件或XML文件,如3.4节中用到的 libvirt.xml)状态的虚拟机。处于这些状态的虚拟机可以通过接口virConnectionListAllDomains(从 Hypervisor中获取。
virNetworkPtr:表示一个处于 active 或defined(以配置文件和存储状态存在,但是目前并没有在物理节点上启动的网络)状态的网络。
virStorageVolPtr:代表一个存储卷,它可以为虚拟机提供块设备。
virStoragePoolPtr:代表一个存储池,用来分配和管理存储卷的逻辑区域。可以通过接口virConnectListAllStoragePools()来获取Hypervisor上所有存在的存储池。

虚拟机配置 libvirt.xml 详解
我们简单介绍了如何通过virsh*来实现对虚拟机的管理,但并没有对其中用到的libvirt.xml文件进行详细介绍。本节将对libvirt.xml中的相关内容做详细讲解,Nova在创建虚拟机时,就是通过用户提供的参数,最终生成一个XML文件,然后Libvirt 再通过这个XML文件创建并启动虚拟机。

  • virsh :命令行工具
    通过学习libvirt.xml,有助于我们从Libvirt这一层了解Nova在创建虚拟机时应该准备的配置信息。除了创建虚拟机,对于虚拟机的删除、挂起、迁移、调整Flavor 的大小等操作,也要用到这个XML文件。
    在分析用到的 libvirt.xml文件之前,我们先从整体上了解一下,一个XML文件应该包含哪些重要部分,如下所示:
    在这里插入图片描述

整体上了解XML文件中应该包含的内容后,下面具体来看用到的libvirt.xml 中的内容,具体解释请看代码的内部注释。
登录到虚拟机所在的计算节点的以下目录:/var/lib/nova/instances/6334ae76-ccO0-4fa2-ba96-547dbd70debb/libvirt.xml

# type表示Hypervisor的类型,如果使用的是KVM这种虚拟化技术,那么应该是"type=kvm"
<domain type='qemu'>
# name表示virsh中虚拟机的名字,我们可以在虚拟机所在计算节点上通过virsh list来查看
    <name> instance-00000018 </name>
# uuid表示虚拟机的uuid,这个值与我们通过nova list看到的虚拟机的id是一致的。
    <uuid>6334ae76-cc00-4fa2-ba96-547dbd70debb</uuid>
    <metadata>
        <nova:instance
            xmlns:nova="http://openStack.org/xmlns/libvirt/nova/1.0">
            <nova:package version="14.0.3-1.el7"/>
            <nova:name>jeffreyguan</nova:name>
            <nova:creationTime>2017-07-07 09:20:08</nova:creationTime>
            <nova:flavor name="8-8-100">
                <nova:memory>8196</nova:memory>
                <nova:disk>100</nova:disk>
                <nova:swap>0</nova:swap>
                <nova:ephemeral>0</nova:ephemeral>
                <nova:vcpus>8</nova:vcpus>
            </nova:flavor>
            <nova:owner>
# user_uuid/project_uuid:表示虚拟机所属的用户及Project。前者可以登录到控
# 制节点上,通过Openstack user list来查看;后者可以登录到控制节点
# 上通过,OpenStack project list查看
                <nova:user uuid="498e2348370a441ab9db99b202c1bf83">admin</nova:user>
                <nova:project uuid="f5951321fbff4a8698afdbdd04b5ff8d">admin</nova:project>
            </nova:owner>
# type="image":表示创建虚拟机时所用的虚拟机镜像,可以登录到控制节点
# 上,通过glance image-list查看
            <nova:root type="image" uuid="b9dfc156-98ea-4fb8-811d-2c382b261cdd" />
        </nova:instance>
    </metadata>
    <memory unit='KiB'>8392704</memory>
    <currentMemory unit='KiB'>8392704</currentMemory>
    <vcpu placement= 'static'>8</vcpu>
    <cputune>
        <shares>8192</shares>
    </cputune>
    <sysinfo type=' smbios'>
        <system>
            <entry name='manufacturer'>RDO</entry>
            <entry name='product '>0penstack Compute</entry>
            <entry name='version'>14.0.3-1.el7</entry>
            <entry name='serial'>317544f5-0748-4844-ac73-595a9fb83d06</entry>
            <entry name='uuid'>6334ae76-cc00-4fa2-ba96-547dbd70debb</entry>
            <entry name=' family' >Virtual Machine</entry>
        </system>
    </sysinfo>
# 系统信息,boot dev=' hd'表示默认从硬盘启动
    <os>
        <type arch='x86_64' machine='pc-i440fx-rhel7.3.0 '>hvm</type>
        <boot dev='hd ' />
        <smbios mode= 'sysinfo'/>
    </os>
# 硬件资源信息
    <features>
        <acpi/>
        <apic/>
    </features>
    <cpu mode=' host-model'>
        <model fallback='allow ' />
        <topology sockets='8'cores='1' threads='1'/>
    </cpu>
    <clock offset='utc'/>
# begin:表示系统出现power off/reboot/ crash的时候应该做的处理
    <on_poweroff>destroy</on_poweroff>
    <on_reboot>restart</on_reboot>
    <on_crash>destroy</on_crash>
# end:表示系统出现power off/reboot/ crash的时候应该做的处理
    <devices>
        <emulator>/usr/libexec/ qemu-kvm</emulator>
# begin:虚拟机磁盘信息
        <disk type='file' device='disk '>
            <driver name= ' qemu' type='qcow2' cache='none'/>
            <source file='/var/lib/nova/instances/6334ae76-cc00-4fa2-ba96-547dbd70debb/disk'/>
            <target dev= 'vda' bus='virtio'/>
            <address type='pci' domain='0x0000' bus='Ox00' slot='0x04' function='0x0'/>
        </disk>
# end:虚拟机磁盘信息
        <controller type= 'usb ' index='0'>
            <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
        </controller>
        <controller type='pci' index='0' model='pci-root'/>
# 网络配置,这里的网络配置使用的是网桥。其中: 'tapedaaee4b-b5'可以理解为虚拟
# 机的一个网络设备,'edaaee4b-b5'是虚拟机的Port的前几位; 'brq1d936455-9c'是
# Linux Bridge上的一个端口; 'virtio'表示这是一个虚拟设备。关于前两者的详细介
# 绍将会在网络部分进行详细解释
        <interface type='bridge '>
            <mac address=' fa : 16: 3e : 64 :87 : 11'/>
            <source bridge='brq1d936455-9c'/>
            <target dev='tapedaaee4b-b5'/>
            <model type='virtio'/>
            <driver name= 'qemu'/>
            <address type='pci' domain='0x0000' bus='0x00' slot='Ox03' function='0x0'/>
        </interface>
        <serial type='file'>
            <source path='/var/lib/nova/instances/6334ae76-cc00-4fa2-ba96-547dbd70debb/console.log'/>
            <target port='0'/>
        </serial>
        <serial type='pty'>
            <target port='1'/>
        </serial>
        <console type='file'>
            <source path=' /var/lib/nova/instances/6334ae76-cc00-4fa2-ba96-547dbd70debb/console.log'/>
            <target type='serial' port='0'/>
        </console>
        <input type='tablet' bus='usb'>
            <address type='usb' bus='0' port='1'/>
        </input>
        <input type='mouse' bus='ps2'/>
        <input type='keyboard' bus='ps2'/>
        <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='en-us'>
            <listen type= 'address' address= '0.0.0.0'/>
        </graphics>
        <video>
            <model type='cirrus' vram='16384' heads='1' primary='yes'/>
            <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
        </video>
#表示每10秒去收集一次虚拟内存的使用情况。我们可以通过
# virDomainMemorystats()来获取虚拟机内存的状态。这样可以帮助像ceilometer这样的#计量模块来收集内存的使用量。要想让memballoon起作用,Libvirt的版本应该满足
# 1.1.1+,并且QEMU的版本要满足1.5+
        <memballoon model='virtio'>
            <stats period='10'/>
            <address type='pci' domain='Ox0000' bus='0x00' slot='0x05'function='0x0'/>
        </memballoon>
    </devices>
</domain>

四 、OpenStack通用技术

RPC服务实现分析
OpenStack 的项目(如 Nova、Cinder、Glance 以及 Neuron等)中,各个组件之间(比如,Nova与Neutron通信、Nova与Glance通信等)主要通过RESTAPI接口进行通信,而同一组件内部(比如,Nova中的nova-scheduler与nova-compute通信、nova-conductor与nvoa-scheduler通信等)都采用基于AMQP通信模型的RPC通信。
单从上面这些解释,对于初学者而言可能会有一些抽象,为了让大家更好地理解上面的这些解释,下面以Nova的架构为例,来进一步说明哪些通信需要通过REST,哪些通信需要通过RPC。。。
未完。。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值