nova虚拟机镜像从创建到文件系统resize完整流程

简介: 1. 虚拟机镜像的创建和resize流程nova创建虚拟机涉及的组件比较多,调用比较复杂,这里只列出跟虚拟机镜像创建相关的流程,方便理清虚拟机状态变化的整个流程。nova-apinova.api.

1. 虚拟机镜像的创建和resize流程

nova创建虚拟机涉及的组件比较多,调用比较复杂,这里只列出跟虚拟机镜像创建相关的流程,方便理清虚拟机状态变化的整个流程。

nova-api

nova.api.openstack.compute.servers.ServersController.create() # 接受创建请求,解析出image_uuid
  nova.compute.api.API.create ()
    nova.compute.api.API._create_instance() # 调用glance api获取image对象
      nova.conductor.api.LocalComputeTaskAPI.build_instances()
        nova.conductor.manager.ConductorManager.build_instances() # 此处虽然接收block_device_mapping参数,但是是为了兼容旧版,没有使用。实际通过nova.objects.BlockDeviceMappingList.get_by_instance_uuid()获取
          nova.compute.rpcapi.ComputeAPI.build_and_run_instance() # 使用cast方法调用nova-compute的build_and_run_instance方法。

nova-compute

nova.compute.manager.ComputeManager.build_and_run_instance()
  nova.compute.manager.ComputeManager._do_build_and_run_instance()
    nova.compute.manager.ComputeManager._build_and_run_instance()

      nova.compute.manager.ComputeManager._build_resources()
        nova.compute.manager.ComputeManager._prep_block_device()
          nova.virt.block_device.attach_block_devices()
            nova.virt.block_device.DriverImageBlockDevice.attach()
              nova.volume.cinder.API.create()

      nova.virt.libvirt.driver.LibvirtDriver.spwan()
        nova.virt.libvirt.driver.LibvirtDriver._create_image() # 此处会判断如果不是从volume启动,则调用imagebackend去创建虚拟机镜像
          nova.virt.libvirt.driver.LibvirtDriver._try_fetch_image_cache()
            nova.virt.libvirt.imagebackend.Image.cache()

              nova.virt.libvirt.imagebackend.Rbd.create_image()
                nova.virt.libvirt.imagebackend.Rbd.clone()
                  nova.virt.libvirt.storage.rbd_utils.RBDDriver.clone() # 创建虚拟机镜像,此处如果所使用的image后端不支持clone,或者镜像不可clone(比如rbd中不是raw格式的镜像),会触发异常,create_image调用下面的fetch_image函数
                
                nova.virt.libvirt.utils.fetch_image()
                  nova.virt.images.fetch_to_raw()
                    nova.virt.images.fetch()
                      nova.image.API.download()
                    nova.virt.images.convert_image()
                      nova.virt.images._convert_image() # 将镜像拷贝到本地的/var/lib/instances/_base/目录下,文件名为md5(image).part,然后用qemu-img convert转换为raw格式,名为md5(image).converted,最后重命名为md5(image)
                nova.virt.libvirt.storage.rbd_utils.RBDDriver.import_image() # 这一步是在clone失败,执行fetch_image的情况下,判断虚拟机镜像不存在,执行import_image将fetch的镜像导入到RBD后端作为虚拟机镜像。

                nova.virt.libvirt.storage.rbd_utils.RBDDriver.resize() # 调整虚拟机镜像大小

              nova.virt.libvirt.imagebackend.Rbd.resize_image() # 调整虚拟机镜像大小,RBD后端实际上在create_image时已经resize了,不会执行这一步,这里应该是为了确保其他后端能够正确设置虚拟机镜像的大小

为了便于分析,用graphviz画了在nova-compute的调用关系图:

 

注:存储后端用的是Ceph,所以调用的后端代码是nova.virt.libvirt.imagebackend.Rbd,如果nova使用了不同的后端,比如本地的qcow2镜像、raw镜像、lvm等,只需要对照nova.virt.libvirt.imagebackend中提供的对应实现,出入不会太大,因为它们都继承nova.virt.libvirt.imagebackend.Image,有相同的接口。

至此,虚拟机的镜像已经创建完毕,并且resize为flavor所设置的大小。后面是虚拟机启动后,resize分区和文件系统的过程。

 

一般虚拟机镜像中会安装cloud-init或者配置启动脚本来对虚拟机做初始化配置。在cloud-init或启动脚本中调用growpart和resizefs来完成分区和文件系统的扩容。

 

2. 分区的resize

cloud-init支持使用growpart和gpart对分区进行扩容,时配置的mode而定,默认会按顺序检测系统中是否安装了这两个工具,使用第一个找到的。

growpart是AWS的扩展分区工具,它分别使用sfdisk和sgdisk对MBR和GPT分区表操作,先将分区表导出,然后改写分区的其实扇区位置,最后将改写后的分区表导入,完成分区的扩容。

# growpart [diskdev] [partnum]

 

gpart是FreeBSD推出的磁盘管理工具,GPT分区表将metadata的主本保存在硬盘的开始,将副本保存在硬盘的末尾,所以当虚拟机镜像被扩容,相当于硬盘的容量变大,在GPT看来末尾的metadata副本丢失了,需要先执行recover命令恢复,然后再进行扩容。

# gpart recover [diskdev]
# gpart resize -i [partnum] [diskdev]

 

3. 文件系统的resize

cloud-init通过依次尝试解析/proc/$$/mountinfo、/etc/mtab和mount命令的输出,来获取根目录所挂载的分区和文件系统格式。

针对不通的文件系统,使用不同的命令扩容:

# resize2fs [devpth]    # ext文件系统
# xfs_growfs [devpth]    # xfs文件系统
# growfs [devpth]        # ufs文件系统
# btrfs filesystem resize max [mount_point]    # btrfs文件系统

 

目录
相关文章
|
1天前
|
运维 Linux KVM
KVM详解(五)——KVM虚拟机镜像格式
KVM详解(五)——KVM虚拟机镜像格式
5 0
|
8天前
|
安全 Linux 数据安全/隐私保护
Centos7的虚拟机创建流程
Centos7的虚拟机创建流程
43 6
|
8月前
|
存储 缓存 Ubuntu
【Docker】Docker比虚拟机快的原因、ubuntu容器、镜像的分层概念和私有库的详细讲解
【Docker】Docker比虚拟机快的原因、ubuntu容器、镜像的分层概念和私有库的详细讲解
269 0
|
8月前
|
存储 数据可视化 Linux
【Docker】Docker容器与虚拟机的对比、三要素、架构和镜像加速器的详细讲解
【Docker】Docker容器与虚拟机的对比、三要素、架构和镜像加速器的详细讲解
907 1
|
9月前
|
Ubuntu 数据安全/隐私保护 Windows
virtualbox虚拟机环境搭建之一---Ubuntu1804安装Virtualbox,在Virtualbox中导入Win7镜像
virtualbox虚拟机环境搭建之一---Ubuntu1804安装Virtualbox,在Virtualbox中导入Win7镜像
278 0
|
10月前
|
存储 XML 缓存
关于云平台虚拟机核心组件 libvirt 热迁移流程及关键参数介绍 | 龙蜥技术
一键了解libvirt虚拟机热迁移整体流程,迁移方式及关键迁移参数作用及影响。
|
11月前
|
算法 云计算 虚拟化
硬件加速器IAA的最佳实践解读和libvirt虚拟机热迁移流程简介| 第80-81期
本周二,了解 IAA 加速器的原理及其应用&云上最佳实践;libvirt 虚拟机热迁移整体流程等。
|
Docker 微服务 容器
在虚拟机中部署jeecg微服务--Docker镜像启动微服务项目不显示gateway界面问题
在虚拟机中部署jeecg微服务--Docker镜像启动微服务项目不显示gateway界面问题
在虚拟机中部署jeecg微服务--Docker镜像启动微服务项目不显示gateway界面问题
|
存储 Java
【JVM原理探索】带你梳理分析虚拟机栈映射源代码的流程
【JVM原理探索】带你梳理分析虚拟机栈映射源代码的流程
108 0
【JVM原理探索】带你梳理分析虚拟机栈映射源代码的流程
|
XML 存储 Ubuntu
RK3568开发笔记(五):在虚拟机上使用SDK编译制作uboot、kernel和ubuntu镜像
buildroot虽然灵活,但是基于实际情况,本身是侧重驱动和应用定制开发的只定制一次文件系统投入有点多,还不如直接ubunt自己交叉编译依赖库,做一些库的移植裁剪。   于是本篇就使用ubuntu系统了,至于其他库自己下源码在宿主机交叉编译号后,再拷贝过去或者直接在板子上编译也行(只是会比较慢),但是意义不大,因为开发过程肯定是用宿主机,不然核心板编译太慢,在编译上会花费不少可以省去的时间。
RK3568开发笔记(五):在虚拟机上使用SDK编译制作uboot、kernel和ubuntu镜像