分享

nova.scheduler.filters.disk_filter 分析

doscho 发表于 2016-8-6 14:25:01 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 1 10675
模块中 host_passes 函数分析
   requested_disk                 为创建虚机需要申请的磁盘。
   host_state.free_disk_mb  为compute主机空闲磁盘,数据来源:nova.scheduler.host_manager.HostState.__init__() 中的compute
                                           free_gb = compute.free_disk_gb                           # compute host vm instance所在磁盘的空闲空间
                                           least_gb = compute.disk_available_least                 # compute host 计算获取如下
                                           在nova.scheduler.host_manager.HostState.update_from_compute_node() 中更新
                                                    host_state.free_disk_mb 以min(free_gb,least_gb )最新值。
  重点是free_disk_mb 在过滤中至关重要。

compute.disk_available_least  计算详见nova.virt.libvirt.driver.LibvirtDriver.get_available_resource()
    通过os.ovfs() 获取compute host主机中instance所在目录的文件系统的磁盘情况: 总磁盘空间、空闲磁盘空间、可用磁盘空间
    可用空间 减去 compute host在主机上已经创建的虚机申请的磁盘大小减去已使用的磁盘大小。
                                   详见: nova.virt.libvirt.driver.LibvirtDriver._get_disk_over_committed_size_total()
                                              nova.virt.libvirt.driver.LibvirtDriver._get_instance_disk_info()

如下是分析工程中间数据:
在 libvirt 通过虚拟化层获取资源信息
   根据nova.conf中libvirt的libvirt.images_type的配置项,不同及时磁盘空间的方式不同:
   nova.virt.libvirt.driver.LibvirtDriver._get_local_gb_info
    if CONF.libvirt.images_type == 'lvm':
            info = lvm.get_volume_group_info(
                               CONF.libvirt.images_volume_group)
        elif CONF.libvirt.images_type == 'rbd':
            info = LibvirtDriver._get_rbd_driver().get_pool_info()
        else:
            info = libvirt_utils.get_fs_info(CONF.instances_path)

        for (k, v) in six.iteritems(info):
            info[k] = v / units.Gi           // units.Gi=1024**3   即单位从B转为GB

        return info

     :total: How big the overall usable filesystem is (in gigabytes)
     :free: How much space is free (in gigabytes)
     :used: How much space is used (in gigabytes)

     缺省是default值,libvirt_utils.get_fs_info(CONF.instances_path)   conf.instances_path=/var/lib/nova
     libvirt_utils.get_fs_info(CONF.instances_path):
     """   :free: How much space is free (in bytes)
             :used: How much space is used (in bytes)
             :total: How big the filesystem is (in bytes)
     """
     hddinfo = os.statvfs(path)
     total = hddinfo.f_frsize * hddinfo.f_blocks                       = 4096*4474556 = 18327781376         = 17.07 = 17
     free = hddinfo.f_frsize * hddinfo.f_bavail                        = 4096*2537172 = 10392256512         = 9.68  = 9
     used = hddinfo.f_frsize * (hddinfo.f_blocks - hddinfo.f_bfree)    = 4096*(4474556-2770234)=6980902912  = 6.50  = 6
     return {'total': total,
            'free': free,
            'used': used}

     >>> os.statvfs(path)                                 // https://docs.python.org/2/library/statvfs.html 在v3.0版本中已经废弃 用于返回包含文件描述符fd的文件的文件系统的信息。
         posix.statvfs_result(  f_bsize=4096,                         // Preferred file system block size.                    文件系统块大小
                                f_frsize=4096,                        // Fundamental file system block size.                   分栈大小
                                f_blocks=4474556,   18327781376B  // Total number of blocks in the filesystem.                文件系统数据块总数
                                f_bfree=2770234,    11346878464B  // Total number of free blocks.                         可用块数
                                f_bavail=2537172,   10392256512B  // Free blocks available to non-super user.                 非超级用户可获取的块数
                                f_files=1146880,                      // Total number of file nodes.                        文件结点总数
                                f_ffree=1060196,    // Total number of free file nodes.                                可用文件结点数
                                f_favail=1060196,   // Free nodes available to non-super user.                        非超级用户的可用文件结点数
                                f_flag=4096,        // Flags. System dependent: see statvfs() man page.                挂载标记
                                f_namemax=255)      // Maximum file name length.                                文件名最大长度


    nova.virt.libvirt.driver.LibvirtDriver.get_available_resource()  获取磁盘
       data["local_gb"] = disk_info_dict['total']     = 18327781376/(1024**3) = 17.07
       data["local_gb_used"] = disk_info_dict['used'] = 6980902912/(1024**3)  = 6.50
       disk_free_gb = disk_info_dict['free']          = 10392256512/(1024**3) = 9.68
       disk_over_committed = self._get_disk_over_committed_size_total()    =
       available_least = disk_free_gb * units.Gi - disk_over_committed     =
       data['disk_available_least'] = available_least / units.Gi           =

    #
    nova.virt.libvirt.driver.LibvirtDriver._get_disk_over_committed_size_total()   
        """Return total over committed disk size for all instances."""
        # Disk size that all instance uses : virtual_size - disk_size


    #
    nova.virt.libvirt.driver.LibvirtDriver._get_instance_disk_info()
        """Get the non-volume disk information from the domain xml

        :param str instance_name: the name of the instance (domain)
        :param str xml: the libvirt domain xml for the instance
        :param dict block_device_info: block device info for BDMs
        :returns disk_info: list of dicts with keys:

          * 'type': the disk type (str)
          * 'path': the disk path (str)
          * 'virt_disk_size': the virtual disk size (int)
          * 'backing_file': backing file of a disk image (str)
          * 'disk_size': physical disk size (int)
          * 'over_committed_disk_size': virt_disk_size - disk_size or 0
        """


数据库中的数据
free_disk_gb                  13
disk_available_least         7            
local_gb_used                 4
local_gb                17



df中的数据
[root@vStack ~]# df
文件系统                          1K-块    已用     可用 已用% 挂载点
devtmpfs                        4064616       0  4064616    0% /dev               
tmpfs                           4075884      16  4075868    1% /dev/shm
tmpfs                           4075884  235544  3840340    6% /run
tmpfs                           4075884       0  4075884    0% /sys/fs/cgroup
/dev/mapper/vstack_vstack-root 17898224 6826160 10139816   41% /                       17898224*1024=18327781376   6826160*1024=6989987840   10139816*1024=10383171584
/dev/sdc                       20961280   33032 20928248    1% /srv/node/sdc
/dev/sda1                        487634  116596   341342   26% /boot
tmpfs                            815180       0   815180    0% /run/user/0

[root@vStack ~]# df -h
文件系统                        容量  已用  可用 已用% 挂载点
devtmpfs                        3.9G     0  3.9G    0% /dev
tmpfs                           3.9G   16K  3.9G    1% /dev/shm
tmpfs                           3.9G  231M  3.7G    6% /run
tmpfs                           3.9G     0  3.9G    0% /sys/fs/cgroup
/dev/mapper/vstack_vstack-root   18G  6.6G  9.7G   41% /
/dev/sdc                         20G   33M   20G    1% /srv/node/sdc
/dev/sda1                       477M  114M  334M   26% /boot
tmpfs                           797M     0  797M    0% /run/user/0


确认 host_stat中  free_disk_mb  中的数据来源:nova.scheduler.host_manager.HostState.__init__() 中的compute
        free_gb = compute.free_disk_gb
        least_gb = compute.disk_available_least
   nova.scheduler.host_manager.HostState.update_from_compute_node() 中 更新 host_state.free_disk_mb 以min(free_gb,least_gb )最新值。

跟踪 compute.disk_available_least 值来源 nova.virt.libvirt.driver.LibvirtDriver.get_available_resource()
    通过os.ovfs() 获取compute host主机中instance所在目录的文件系统的磁盘情况。
    设置 compute host的 系统磁盘的可用大小 减去 compute host中已有vm的disk_over_committed_size=virt_disk_size - disk_size 虚机申请的大小减去现有磁盘文件的大小(已计算过)


终于知道创建虚机时,磁盘不足的原因了。







已有(1)人评论

跳转到指定楼层
L_Zou 发表于 2016-8-29 15:05:19
好帖,我也一直遇到类似问题,现在申请磁盘超过3G就不能启动实例
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条