OpenStackNova启动实例流程

OpenStackNova启动实例流程
1、概述
启动⼀个新的实例,会涉及到OpenStack Nova中的多个组件:
API服务器,接收⽤户端的请求,并且将其传递给云控制器。
云控制器,处理计算节点、⽹络控制器、API服务器和调度器之前的通信。
调度器,选择⼀个执⾏命令的主机。
计算节点,管理计算实例:启动/终⽌实例,添加/删除卷…
⽹络控制器,管理⽹络资源:分配固定IP地址,配置VLAN
启动⼀个实例的流程如下:API服务器收到⽤户的run_instance命令,API服务器将消息传递给云控制器(1);对⽤户进⾏⾝份验证;云控制器将消息转发到调度器(2);调度器将消息扔给⼀个随机的⼀个主机,并通知它启动⼀个新实例(3);主机上的计算服务接收该消息;计算服务启动实例需要⼀个固定的IP,所以发送消息给⽹络控制器(5,6,7,8);之后,计算服务⽣产出⼀个新的实例。
2、API
可以使⽤OpenStack API或者EC2 API来启动新的实例。下⾯以EC2 API为例。添加⼀个新的key pair,并使⽤它启动⼀个新的m1.tiny类型的实例:
cd /tmp/
euca-add-keypair test > test.pem
euca-run-instances -k test -t m1.tiny ami-tiny
调⽤⽂件api/ec2/cloud.py中的run_instances()函数,在该函数中会调⽤⽂件compute/API.py中的compute API 的create函数:
玻璃房子def run_instances(self, context, **kwargs):
...
instances = ate(context,
instance_type=_by_type(
<('instance_type', None)),
image_id=kwargs['image_id'],
...
compute API  create函数流程如下:
检查此种类型的实例数是否已经达到最⼤值;
如果不存在安全组,则创建⼀个;
为新的实例创建MAC地址和主机名;
发送消息给调度器以运⾏实例。
3、消息投递
发送消息给调度器,在OpenStack中,这种类型的消息传递定义为RPC投递,使⽤RabbitMQ进⾏传递。消息⽣产者(API)发送消息到⼀个topic exchange(scheduler  topic)。消费者(调度器)从队列中接收消息。因为是消息投递,所以⽆需响应消息。
下⾯是消息投递的代码:
LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's"
" instance %(instance_id)s") % locals())测量空间
rpc.cast(context,
FLAGS.scheduler_topic,
{"method": "run_instance",
"args": {"topic": FLAGSpute_topic,
"instance_id": instance_id,
"availability_zone": availability_zone}})
可见在消息投递时使⽤了scheduler topic,并且希望调度器在发送消息时,使⽤compute topic。
4、调度器
调度器接收消息,并且发”run_instance”消息给随机的主机。这⾥使⽤的是chance 调度器。还有其他类型的调度器,⽐如zone调度器(在⼀个特定的可⽤区域内随机选择主机)、简单调度器(选择最⼩负载的主机)。现在主机已经选择好了,接下来就是发送消息给该主机的计算服务了。
rpc.cast(context,
db.queue_get_for(context, topic, host),
{"method": method,
"args": kwargs})
LOG.debug(_("Casting to %(topic)s %(host)s for %(method)s") % locals())
5、计算节点
计算节点接收消息,然后调⽤compute/manager.py中的run_instance⽅法:
def run_instance(self, context, instance_id, **_kwargs):
"""Launch a new instance with specified options."""
...
run_instance()的流程如下:
检查实例是否已经运⾏;
分配固定的ip低值;
设置⼀个VLAN或者桥;
使⽤virtualization driver产⽣⼀个实例。
6、调⽤⽹络控制器
在分配固定IP时,会⽤到RPC调⽤。RPC调⽤不同于RPC投递,它使⽤topic.hostexchange,表明它的⽬的地为特定主机,⽽且RPC调⽤需要响应。
7、产⽣实例
下⾯就是由virtualization driver执⾏产⽣实例的过程。以libvirt为例,代码在virt/libvirt_conn.py中。
启动实例的第⼀件事就是创建libvirt xml。⽅法to_xml⽤来⽣成xml的内容。下⾯是我们实例的XML⽂件:
<domain type='qemu'>
<name>instance-00000001</name>
<memory>524288</memory>
<os>
<type>hvm</type>
<kernel>/opt/novascript/trunk/nova/..//instances/instance-00000001/kernel</kernel>
<cmdline>root=/dev/vda console=ttyS0</cmdline>
<initrd>/opt/novascript/trunk/nova/..//instances/instance-00000001/ramdisk</initrd>
</os>
<features>
<acpi/>
光纤环网</features>
<vcpu>1</vcpu>
<devices>
<disk type='file'>
<driver type='qcow2'/>
电子货币兑换<source file='/opt/novascript/trunk/nova/..//instances/instance-00000001/disk'/>
<target dev='vda' bus='virtio'/>
eeg平台</disk>
<interface type='bridge'>
<source bridge='br100'/>
<mac address='02:16:3e:17:35:39'/>
<!--  <model type='virtio'/>  CANT RUN virtio network right now -->
<filterref filter="nova-instance-instance-00000001">
<parameter name="IP" value="10.0.0.3" />
<parameter name="DHCPSERVER" value="10.0.0.1" />
<parameter name="RASERVER" value="fe80::1031:39ff:fe04:58f5/64" />
<parameter name="PROJNET" value="10.0.0.0" />
<parameter name="PROJMASK" value="255.255.255.224" />
<parameter name="PROJNETV6" value="fd00::" />
<parameter name="PROJMASKV6" value="64" />
</filterref>
</interface>
<!-- The order is significant here.  File must be defined first -->
<serial type="file">
<source path='/opt/novascript/trunk/nova/..//instances/instance-00000001/console.log'/>
<target port='1'/>
</serial>
<console type='pty' tty='/dev/pts/2'>
<source path='/dev/pts/2'/>
<target port='0'/>
</console>
<serial type='pty'>
<source path='/dev/pts/2'/>
<target port='0'/>
</serial>
</devices>
</domain>
使⽤的虚机管理程序为qemu,客户机的内存为524字节,客户端OS从存储于主机OS中的内核和initrd启动。
分配各客户机的虚拟CPU个数为1. 电源管理中使能了ACPI。还定义了多个设备:
磁盘镜像为主机OS上的⼀个⽂件,使⽤qcow2驱动器,qcow2是⼀种qemu磁盘镜像的写时复制格式;
⽹络接⼝是客户机可见的桥,定义了⼀系列⽹络过滤器参数,⽐如IP地址10.0.0.3意味着始终使⽤该地址作为源IP地址;
⽇志⽂件,所有发送给字符设备的数据全部写⼊console.log中;
伪终端,virsh控制台可⽤于连接本地串⼝。
接下来是⽹络过滤器的配置。默认使⽤的防⽕墙driver是iptables。规则由IptablesFirewallDriver类的
apply_ruleset⽅法定义。下⾯是本实例的防⽕墙规则:
*filter
...
:nova-ipv4-fallback - [0:0]
:nova-local - [0:0]
:nova-inst-1 - [0:0]
:nova-sg-1 - [0:0]
-A nova-ipv4-fallback -j DROP
-A FORWARD -j nova-local
-A nova-local -d 10.0.0.3 -j nova-inst-1
-A nova-inst-1 -m state --state INVALID -j DROP
-A nova-inst-1 -m state --state ESTABLISHED,RELATED -j ACCEPT
-A nova-inst-1 -j nova-sg-1
-A nova-inst-1 -s 10.1.3.254 -p udp --sport 67 --dport 68
-A nova-inst-1 -j nova-ipv4-fallback
-A nova-sg-1 -p tcp -s 10.0.0.0/27 -m multiport --dports 1:65535 -j ACCEPT
-A nova-sg-1 -p udp -s 10.0.0.0/27 -m multiport --dports 1:65535 -j ACCEPT
线性驱动器
-A nova-sg-1 -p icmp -s 10.0.0.0/27 -m icmp --icmp-type 1/65535 -j ACCEPT
COMMIT
定义了防⽕墙规则之后,就是创建镜像,由⽅法_create_image()处理:
def _create_image(self, inst, libvirt_xml, suffix='', disk_images=None):
...
在该⽅法中,会根据上⾯的XML创建l;复制虚拟机管理程序要使⽤的randisk、initrd和磁盘镜像;如果使⽤flat⽹络管理器,则会将⼀个⽹络配置植⼊到客户端的OS镜像中。本例中使⽤VLAN管理器。
实例的SSH key植⼊到镜像中,本过程是调⽤disk.inject_data⽅法:
disk.inject_data(basepath('disk'), key, net,
partition=target_partition,
nbd=FLAGS.use_cow_images)
basepath('disk')表⽰实例的磁盘镜像在主机OS中的位置,key是SSH key字符串,在我们的例⼦中不
设置⽹络,因为不需要植⼊⽹络配置。因为使⽤的是内核镜像,所以没有分区,否则的话会使⽤分区的磁盘镜像。在inject_data内部:
第⼀件事就是链接镜像到⼀个设备,这发⽣在_link_device中:

本文发布于:2024-09-25 18:22:53,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/180075.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:消息   实例   计算   调度   启动   镜像   IP地址   接收
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议