Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1490013
  • 博文数量: 230
  • 博客积分: 474
  • 博客等级: 下士
  • 技术积分: 1955
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-19 18:40
文章分类

全部博文(230)

文章存档

2020年(3)

2019年(3)

2018年(12)

2017年(13)

2016年(11)

2015年(55)

2014年(74)

2013年(39)

2012年(2)

2011年(18)

我的朋友

分类: 云计算

2015-03-30 10:26:08

原文地址()

网上查找CloudStack源码的文章还是很少的,不像OpenStack那样多,花了两天的时间,将CloudStack 创建VM的源码读了一遍,感叹几点:创建一个VM流程中,查询操作数据库真多。 前几天听 CloudStack 的人说,CloudStack Management Server 装在一个16G/4C 的物理机上,运行半年,会挂掉,当时那个汗啊。。。


先把整理的流程图附上


下面按照每个步骤进行说明:

1、com.cloud.api.ApiServlet.processRequest(HttpServletRequest, HttpServletResponse) 函数处理所有请求。具体处理登录、登出请求其他请求进行转发,进入下一步


2、com.cloud.api.ApiServer.handleRequest(Map, String, StringBuffer)

收到创建VM的请求,解析参数根据参数“command” 实例化处理该API的类,并将请求参数赋值到该类创建的对象,对于创建VM,实例化的类为:

org.apache.cloudstack.api.command.user.vm.DeployVMCmd。

由于继承自BaseAsyncCreateCmd,所以需要首先调用DeployVMCmd的create函数,再调用execute函数

Note:基于注解赋值:com.cloud.api.ApiDispatcher.processParameters(BaseCmd, Map),权限管理也是通过注解完成的。


3、org.apache.cloudstack.api.command.user.vm.DeployVMCmd.create()

3.1 检查zone、serviceoffering、templateId、diskoffering、zone是否启用了本地存储、获取ipv4,、ipv6地址,判断是基本zone,还是高级zone

3.2 如果是基本zone,需要调用函数

com.cloud.vm.UserVmManagerImpl.createBasicSecurityGroupVirtualMachine(DataCenter,ServiceOffering, VirtualMachineTemplate, List, Account, String, String, Long, Long, String, HypervisorType, HTTPMethod, String, String, Map, IpAddresses, Boolean, String, List, Map)

3.3 如果是高级zone,首先判断该zone是否启用了安全组,如果启用了安全组,调用函数

com.cloud.vm.UserVmManagerImpl.createAdvancedSecurityGroupVirtualMachine(DataCenter, ServiceOffering, VirtualMachineTemplate, List, List, Account, String, String, Long, Long, String, HypervisorType, HTTPMethod, String, String, Map, IpAddresses, Boolean, String, List, Map)

如果没有启用安全组,调用函数:

com.cloud.vm.UserVmManagerImpl.createAdvancedVirtualMachine(DataCenter, ServiceOffering, VirtualMachineTemplate, List, Account, String, String, Long, Long, String, HypervisorType, HTTPMethod, String, String, Map, IpAddresses, Boolean, String, List, Map)


以在基本zone创建VM为例,进行源码阅读


4、函数

com.cloud.vm.UserVmManagerImpl.createBasicSecurityGroupVirtualMachine(DataCenter,ServiceOffering, VirtualMachineTemplate, List, Account, String, String, Long, Long, String, HypervisorType, HTTPMethod, String, String, Map, IpAddresses, Boolean, String, List, Map)


(4.1) 根据zoneId 获取该zone内的默认网络,执行的SQL

select *from networks where data_center_id=1 and account_id=1 and guestType=’Shared’ and traffic_type=’Guest’;

将查询到的默认网络保存到内存,后面使用.(需要将虚拟机加入到该网络,进行管理)

(4.2) 判断虚拟机模板是否为vmware类型,或者 hypervisor 是否为vmware,两张有一个为true,如果配置了安全组策略,则报错。(即目前不支持vmware 虚拟机配置安全组)

(4.3) 检查该zone是否支持安全组,查询数据表ntwk_service_map ,确定该网络是否支持安全组服务。如果存在,还有检查服务的提供者是否存在(在数据表ntwk_service_map 存放)。查询数据表configuration,其中的network.securitygroups.defaultadding 字段,设置为true表示可以将VM加入默认安全组。(这个时候会进行检查是否存在默认安全组,如果不存在,创建一个安全组,存入数据库)

(4.4) 查询该用户是否有安全组,如果有的话,将该安全组加入虚拟机安全组列表,如果该用户不存在安全组,为该用户创建默认安全组,并加入到虚拟机安全组列表

security_group 数据表中添加数据

insert into security_group (‘name’,’domain_id’,’account_id’,’description’) values (....)


Note:1、CloudStack不支持vmware配置安全组,在高级zone内,只支持KVM主机配置安全组。

2、只能在guest网络中配置安全组


5、 函数:

com.cloud.vm.UserVmManagerImpl.createVirtualMachine(DataCenter, ServiceOffering, VirtualMachineTemplate, String, String, Account, Long, Long, List, List, String, HTTPMethod, String, String, HypervisorType, Account, Map, IpAddresses, Boolean, String, List, Map)

(5.1) 查询虚拟机模板详情,查询数据表 vm_template。查询数据表dedicated_resources,判断该zone是否进行了domain划分,查看用户在domain是否有 权限进行操作。查询serviceoffering信息,如果设置了自定义serviceoffering参数,需要进行参数设置。

(5.2) 获取模板大小,以及diskoffering的磁盘大小,检查该用户的cpu,memory资源是否足够,查询卷是否足够,查询主存储是否有足够空间 (涉及到的数据表resource_limit)

(5.3) hypervisor 不是裸金属时,检查存储池,禁止使用系统模板创建系统虚拟机

(5.4) 配置网卡信息,设置默认网卡,数据库获取vm的id,检查新建的虚拟机主机名是否合法,如果没有设置主机名,系统会生成一个,生成虚拟机名称

(5.5) 执行存储vm操作,见步骤6

(5.6) 将VM加入security group 和affinitygroup

6、

com.cloud.vm.UserVmManagerImpl.commitUserVm(DataCenter, VirtualMachineTemplate, String, String, Account, Long, Long, String, HypervisorType, Account, Boolean, String, long, ServiceOfferingVO, boolean, String, LinkedHashMap, long, String, String, HypervisorType, Map)

(6.1)构造 com.cloud.vm.UserVmVO.UserVmVO(long, String, String, long, HypervisorType, long, boolean, boolean, long, long, long, String, String, Long),存放虚拟机信息

(6.2) 当主机为vmware,判断是否需要进行链接克隆。通过设置vmware.create.full.clone


(6.3) 设置 主机标签,如果是使用iso创建虚拟机进入函数:

org.apache.cloudstack.engine.orchestration.CloudOrchestrator.createVirtualMachineFromScratch(String, String, String, String, String, String, String, int, int, long, Long, List, List, Map, DeploymentPlan)

使用非iso创建虚拟机

org.apache.cloudstack.engine.orchestration.CloudOrchestrator.createVirtualMachine(String, String, String, String, String, String, int, int, long, Long, List, List, Map, DeploymentPlan)

(6.4) 将使用的资源存放到数据库


7、函数

org.apache.cloudstack.engine.orchestration.CloudOrchestrator.createVirtualMachineFromScratch(String, String, String, String, String, String, String, int, int, long, Long, List, List, Map, DeploymentPlan)

设置rootdisk和nic


8、函数

com.cloud.vm.VirtualMachineManagerImpl.allocate(String, VirtualMachineTemplate, ServiceOffering, Pair, LinkedHashMap, LinkedHashMap>, DeploymentPlan, HypervisorType)

(8.1) 调用network manager 分配网络

根据networkid 查询数据表networks,获取guru_name,判断调用哪个network adapter。基本zone,没有安全组,使用的是DirectPodBasedNetworkGuru

调用函数com.cloud.network.guru.DirectPodBasedNetworkGuru.allocate(Network, NicProfile, VirtualMachineProfile) ,获取网卡的IP、网关,mac地址等信息

将网卡数据存入数据库


(8.2) 调用volume manager 分配卷,分为root盘和data盘,将数据存入数据库



9、执行函数org.apache.cloudstack.api.command.user.vm.DeployVMCmd.execute()


判断是否启动虚拟机,如果是,执行第10步,如果不是,只需要从数据库获取虚拟机信息


10、com.cloud.vm.UserVmManagerImpl.startVirtualMachine(DeployVMCmd)


(10.1) 只有admin用户可以在创建VM的时候指定创建VM,构造部署策略(选择数据中心,提供点,群集,主机,物理网络,资源池)

(10.2) 数据库查询虚拟机的相关信息,调用

com.cloud.vm.VirtualMachineManagerImpl.advanceStart(String, Map, DeploymentPlan, DeploymentPlanner)


11、函数

com.cloud.vm.VirtualMachineManagerImpl.orchestrateStart(String, Map, DeploymentPlan, DeploymentPlanner)

(11.1) 确认部署计划中,虚拟机卷所在的主存储对应的群集,与选择的群集相同,根据VM配置选择部署的目的(数据中心,提供点,群集,主机,存储)

(11.2) 如果用户没有设置VM的cpu,memory 超分配系数,则该VM的超分配系数采用群集的超分配系数

(11.3) 准备网络与存储


12函数

com.cloud.agent.manager.AgentManagerImpl.send(Long, Commands)

将创建虚拟机的信息传到 KVM主机

13、

com.cloud.agent.Agent.processRequest(Request, Link)

cloudstack-agent 收到请求,根据agent.properties 中的resource的设置,确定将请求转发到哪种hypervisor进行处理,如果是KVM,则转到14步


14、com.cloud.hypervisor.kvm.resource.LibvirtComputingResource.executeRequest(Command)

根据参数类型确定具体执行哪个操作,构造libvirt需要的参数创建虚拟机

阅读(2686) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~