简介

diskimage-builder(简称dib)是一款用于构建系统镜像的工具,它被设计用于OpenStack的TripleO项目,支持qocw2、vhd、raw等主流镜像格式。

在众多系统镜像构建工具中,dib与众不同的地方在于其对元素(element)的设计。在dib中,所有想要构建的实体都被抽象为一个个的元素,元素与元素之间相互依赖,形成一种类似树的结构。dib拥有一些内置元素,位于diskimage-builder/elements目录中,可以通过ELEMENTS_PATH环境变量指定额外的元素目录。

例如:使用dib构建镜像时指定centos-minimal元素。

graph TD
centos-minimal-->yum-minimal
yum-minimal-->redhat-common
yum-minimal-->rpm-distro
yum-minimal-->yum
redhat-common-->package-installs
redhat-common-->sysprep
yum-->install-bin
package-installs-->install-bin
package-installs-->pkg-map

与yum包管理器中的rpm包类似,当构建系统镜像时指定centos-minimal元素时,dib会解析该元素的所有依赖元素,生成所有需要构建的元素,然后按顺序安装它们,最终生成一个完整的镜像。

概念

系统镜像

系统镜像指包含了可运行系统的虚拟磁盘文件。磁盘虚拟化是云计算的基础技术之一,dib支持的系统镜像格式有:qcow2,vhd,raw。在完成系统镜像构建后,dib会输出一个如上格式的虚拟磁盘文件,里面包含了构建好的系统。

如果要构建一个可启动的系统镜像,需要在构建时添加vm元素:disk-image-create <distro> vm

元素

构建镜像需要给dib传递一系列的元素,这些元素决定了镜像该如何构建。

dib有着各种各样的元素。某些元素提供了一个root文件系统,例如ubuntu、fedora等等;另一些元素则在此基础上修改,并最终创建出我们需要的镜像;还有一些比较特殊的元素,例如vm,此元素会为镜像创建一个bootloader,确保镜像是可启动的。

输出格式

默认情况下dib会创建qcow2格式的镜像,可以通过-t <format>参数指定需要的镜像格式,多种格式以逗号分隔。目前dib支持如下格式:

  • qcow2:qemu支持的镜像格式之一,虚拟化中主流的镜像格式
  • tar:归档格式
  • tgz:归档与压缩结合的格式
  • squashfs:基于Linux内核的压缩只读文件系统
  • vhd:Hyper-V支持的一种镜像格式
  • docker:docker支持的镜像格式,可被docker import导入
  • raw:裸镜像格式

镜像布局

镜像文件与真正的硬盘一样,拥有分区、lvm、磁盘加密等等布局,这些布局在镜像构建的初始就应该做好,后续对镜像的改动也几乎不会去修改这些布局。

dib提供了一些针对镜像布局的元素,例如:vm,当使用该元素时还需额外指定一个block-device-*的元素,可选mbr、gpt以及efi,用来表示分区格式。如下命令创建了一个gpt格式的镜像文件。

disk-image-create -o centos vm block-device-gpt centos-minimal

默认情况下,定义镜像布局的配置位于各block-device-*元素目录的block-device-default.yaml文件中,如需额外配置,可以通过DIB_BLOCK_DEVICE_CONFIG环境变量指定一个文件路径。

export DIB_BLOCK_DEVICE_CONFIG=file:///path/to/config

若构建镜像时不指定vm元素,那么镜像中将只包含root文件系统,没有分区信息。

镜像布局从上往下分为5个级别,分别代表着不同的布局划分步骤,以block-device-gpt元素的镜像布局配置文件为例:

- local_loop: # Level 0
name: image0 - partitioning: # Level 1
base: image0
label: gpt
partitions:
- name: BSP
type: 'EF02'
size: 8MiB
- name: root
flags: [ boot ]
size: 100%
mkfs: # Level 2
type: ext4
mount: # Level 3
mount_point: /
fstab: # Level 4
options: "defaults"
fsck-passno: 1

其中:

  • Level 0

    • Local Loop:该模块用于生成一个本地镜像文件

      • name:镜像文件的名称,必选
      • size:虚拟磁盘的大小,可选
      • directory:镜像文件所在的位置,可选
  • Level 1
    • Partitioning:该模块用于为已有块设备生成分区

      • base:块设备的名称,一般指定为Local Loop模块中镜像文件的名称,必选
      • label:分区表类型,可选mbr或gpt,必选
      • align:分区对齐,仅mbr分区需要,可选
      • partitions:分区列表,每一个列表元素描述了一个分区
        • name:分区的名称,必选
        • flags:分区的标识,可选boot或primary,仅mbr分区需要,可选
        • size:分区的大小,可选绝对值,如10GiB、1.75TB,或者相对值,如33%,相对值的话将依据剩余空闲空间计算,必选
        • type:记录在分区表中的分区类型,MBR分区的默认值为0x83,GPT分区的默认值为8300,可选
    • LVM:该模块用于为已有分区生成逻辑卷
      • pvs:物理卷的列表,每个列表元素描述了一个物理卷(Physical Volume)

        • name:物理卷的名称,必选
        • base:分区的名称,LVM在此分区上创建物理卷,必选
        • options:创建物理卷时的可选选项列表,即传递给pvcreate命令的参数列表,可选
      • vgs:卷组的列表,每个列表元素描述了一个卷组(Volume Group)
        • name:卷组的名称,必选
        • base:物理卷的名称列表,LVM在这些物理卷上创建卷组,必选
        • options:创建卷组时的可选选项列表,即传递给vgcreate命令的参数列表,可选
      • lvs:逻辑卷的列表,每个列表元素描述了一个逻辑卷(Logical Volume)
        • name:逻辑卷的名称,必选
        • base:卷组的名称,LVM在此卷组上创建逻辑卷,必选
        • size:逻辑卷的精确大小,与lvcreate命令的-L参数有着同样的语法,可选,size和extents参数必须二选一
        • extents:逻辑卷的相对大小,与lvcreate命令的-l参数有着同样的语法,可选,size和extents参数必须二选一
        • options:创建逻辑卷的可选选项列表,即传递给lvcreate命令的参数列表,可选
  • Level 2
    • Mkfs:该模块用于为已有分区创建文件系统

      • base:分区的名称,Mkfs在此分区上创建文件系统,必选
      • name:文件系统的名称,必选
      • type:文件系统的类型,比如ext4或xfs,必选
      • label:文件系统的标识,可被grub和fstab使用,默认和名称相同,可选
      • opts:创建文件系统的可选选项列表,即传递给mkfs命令的参数列表,可选
      • uuid:文件系统的uuid,目前支持ext2、ext3、ext4、xfs
  • Level 3
    • Mount:该模块用于挂载一个文件系统

      • base:文件系统的名称,Mount会挂载此文件系统,必选
      • name:挂载点的名称,必选
      • mount_point:挂载点的路径,必选
  • Level 4
    • fstab:该模块用于创建fstab入口

      • base:挂载点的名称,用于写入fstab,必选
      • name:fstab入口的名称,必选
      • options:特殊的挂载选项,对应fstab中的第四列,默认为default,可选
      • dump-freq:文件系统是否需要导出,对应fstab的第五列,默认为0,可选
      • fsck-passno:是否需要运行fsck,该工具用来检测/修复文件系统,对应fstab的第六列,默认为2,可选

执行阶段

每个元素下有许多目录,这些目录以阶段命名,dib会在不同的阶段执行这些目录下的脚本,这些脚本有着两位数数字的前缀,并会以数字的顺序执行。

dib共有如下阶段:

  1. root.d:初始化根文件系统,该阶段的主要工作是获取根文件系统的文件,并放置于工作区域($TARGET_ROOT)中。该阶段依赖于各发行版,也可以在已有镜像上定制。

    • 运行于:chroot外面
    • 输入:
      • $ARCH=i386|amd64|armhf|arm64
      • $TARGET_ROOT=/path/to/target/workarea
  2. extra-data.d:从宿主机环境中获取额外数据,这些数据会在镜像构建中使用。该阶段通常用来复制配置文件至工作区域($TMP_MOUNT_PATH)中,比如复制yum repo至$TMP_MOUNT_PATH/etc/yum.repos.d
    • 运行于:chroot外面
    • 输入:
      • $TMP_HOOKS_PATH:表示chroot里面的/tmp/in_target.d目录
  3. pre-install.d:在chroot里面运行代码。该阶段用于在定制镜像之前做一些事先配置工作,比如说在配置dnf包管理工具、更新包缓存、安装python基础环境等等。
    • 运行于:chroot里面
  4. install.d:运行于pre-install.d之后。该阶段用于安装包,也可以做一些镜像特定的操作。
    • 运行于:chroot里面
  5. post-install.d:运行于install.d之后。该阶段往往用来做一些清理工作,比如说清理安装缓存。
    • 运行于:chroot里面
  6. post-root.d:在chroot外面运行代码。该阶段用来执行一些不能在chroot里面做且需要在安装步骤之后做的事情,根文件系统位于$TMP_BUILD_DIR/mnt目录下。
    • 运行于:chroot外面
  7. block-device.d:自定义镜像所在的块设备。在目标树生成之后执行,该步骤暂时没看到元素在使用。
    • 运行于:chroot外面
    • 输入:
      • $IMAGE_BLOCK_DEVICE={path}
      • $TARGET_ROOT={path}
    • 输出:
      • $IMAGE_BLOCK_DEVICE={path}
  8. pre-finalise.d:该步骤用来重新挂载文件系统,到此步骤时根文件系统已经复制到最终的文件系统中,该文件系统位于$TMP_BUILD_DIR/mnt
    • 运行于:chroot外面
  9. finalise.d:该步骤是根文件系统构建的最后一步,该步骤会运行chroot到最终的文件系统中,然后执行一些脚本。该步骤往往用来生成grub配置。
    • 运行于:chroot里面
  10. cleanup.d:最后的清理工作作为收尾,该步骤用来清理一些临时配置。
    • 运行于:chroot外面
    • 输入:
      • $ARCH=i386|amd64|armhf|arm64
      • $TARGET_ROOT=/path/to/target/workarea

只有拥有可执行权限的文件才会执行,所以阶段目录中也可保存其他的文件,不过处于惯例,一般只在阶段目录中保存可执行脚本,数据保存在其他位置中。

除了这些阶段以外,元素还拥有其他特定的目录/文件:

  • environment.d/:该目录用于存放环境变量,每个阶段执行前都会加载该目录下的环境变量文件。注意不要在文件中添加如set -x这样的全局标志,这样会影响到所有的脚本。
  • element-deps:该文件用来保存依赖的元素列表,以换行符分隔。
  • element-provides:该文件用来保存本元素的别名列表,以换行符分隔。举例说表示分区类型的元素有block-device-mbr、block-device-gpt等等,上层元素需要依赖mbr、gpt中的某个分区,却不知道到底依赖其中的哪一个,若mbr、gpt元素都在element-provides文件中写入名为block-device的别名,那么上层元素写入依赖的时候只需要指定block-device元素就可以了。最后在镜像构建时通过指定如xxx block-device-mbrxxx block-device-gpt的方式来真正区分时候哪一个分区。

安装类型

同一个软件,通常会有多种不同的安装方式,例如源代码安装、分发包安装、pip安装等等。在dib中,默认的软件安装方式是源代码安装(source),可以通过添加--install-type参数或DIB_DEFAULT_INSTALLTYPE环境变量修改。

dib中的元素可以定义不同的软件包安装方式,格式为<install-dir-prefix>-<install-type>-install,以nova元素为例,该元素同时提供了source和package两种方式:

# package方式
nova/install.d/nova-package-install/74-nova
# source方式
nova/install.d/nova-source-install/74-nova

dib也可以针对单个元素的软件包安装方式进行修改,环境变量的格式为DIB_INSTALLTYPE_<install_dir_prefx>,例如:

export DIB_INSTALLTYPE_nova=package

示例

centos7-minimal

docker run -it --rm --name dib --privileged -v /dev:/dev af.frankming.com.cn/docker-drpd/openstack/centos-binary-openstack-base:train bash
dnf install -y yum-utils e4fsprogs kpartx qemu-img gdisk
pip install ironic-python-agent-builder diskimage-builder mkdir -p /tmp/repo
echo '[base]
name=CentOS-$releasever - Base
baseurl=http://10.1.14.235/centos/$releasever/os/$basearch/
gpgcheck=0 #released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=http://10.1.14.235/centos/$releasever/updates/$basearch/
gpgcheck=0 #additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://10.1.14.235/centos/$releasever/extras/$basearch/
gpgcheck=0 #additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://10.1.14.235/centos/$releasever/centosplus/$basearch/
gpgcheck=0
enabled=0 [epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
baseurl=http://10.1.14.235/epel/7/$basearch
enabled=1
gpgcheck=0
' > /tmp/repo/base.repo export DIB_YUM_MINIMAL_BOOTSTRAP_REPOS=/tmp/repo disk-image-create vm block-device-gpt centos-minimal

centos7

docker run -it --rm --name dib --privileged -v /dev:/dev af.frankming.com.cn/docker-drpd/openstack/centos-binary-openstack-base:train bash
dnf install -y yum-utils e4fsprogs kpartx qemu-img gdisk
pip install ironic-python-agent-builder diskimage-builder export DIB_DISTRIBUTION_MIRROR=http://mirrors.frankming.com.cn/centos/
export DIB_CLOUD_IMAGES=/data/images/CentOS-7-x86_64-GenericCloud.qcow2
export DIB_LOCAL_IMAGE=/data/images/CentOS-7-x86_64-GenericCloud.qcow2
export IMAGE_NAME=centos7
export DIB_EPEL_MIRROR=http://mirrors.frankming.com.cn/epel
export DIB_EPEL_DISABLED=1
export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive, OpenStack"
# /usr/local/lib/python3.9/site-packages/diskimage_builder/elements/yum/pre-install.d/01-00-centos-python3
# yum install -y http://10.33.41.25/CI/openstack-train/others/python36-PyYAML-3.13-1.el7.x86_64.rpm
disk-image-create centos7 vm cloud-init-datasources dhcp-all-interfaces iscsi-boot dracut-regenerate block-device-efi -o $IMAGE_NAME

centos8

docker run -it --rm --name dib --privileged -v /dev:/dev af.frankming.com.cn/docker-drpd/openstack/centos-binary-openstack-base:train bash
dnf install -y yum-utils e4fsprogs kpartx qemu-img gdisk
pip install ironic-python-agent-builder diskimage-builder export DIB_YUM_MINIMAL_BOOTSTRAP_REPOS=/etc/yum.repos.d
export DIB_RELEASE=8
disk-image-create vm block-device-gpt centos-minimal

ipa-centos8

docker run -it --rm --name dib --privileged -v /dev:/dev af.frankming.com.cn/docker-drpd/openstack/centos-binary-openstack-base:train bash
dnf install -y yum-utils e4fsprogs kpartx qemu-img gdisk
pip install ironic-python-agent-builder diskimage-builder export DIB_YUM_MINIMAL_BOOTSTRAP_REPOS=/etc/yum.repos.d
export DIB_RELEASE=8
export ELEMENTS_PATH=/usr/local/share/ironic-python-agent-builder/dib
export DIB_DEFAULT_INSTALLTYPE=package
export DIB_EPEL_MIRROR=http://mirrors.frankming.com.cn/epel
export DIB_EPEL_DISABLED=1
export DIB_DEV_USER_USERNAME=cloud
export DIB_DEV_USER_PWDLESS_SUDO=yes
export DIB_DEV_USER_PASSWORD=frankming@123++
disk-image-create -o ipa-centos8-stable-train ironic-python-agent-ramdisk centos-minimal devuser stable-interface-names
# ipa-arm64,arm64无biosdevname包,无法使用stable-interface-names元素
# disk-image-create -a aarch64 -o ipa-centos8-stable-train-aarch64 ironic-python-agent-ramdisk centos-minimal devuser

ipa-debian

docker run --privileged -it --rm --cap-add=SYS_ADMIN --device-cgroup-rule="b 7:* rmw" --name test af.frankming.com.cn/docker-drpd/openstack/debian-base:bullseye bash

pip install ironic-python-agent-builder
apt update && apt install -y qemu-utils sudo debootstrap git rsync cpio export DIB_DISTRIBUTION_MIRROR=http://mirrors.frankming.com.cn/debian/
export DIB_DEBIAN_SECURITY_MIRROR=http://mirrors.frankming.com.cn/debian-security/
export DIB_DEFAULT_INSTALLTYPE=source
export DIB_DEV_USER_USERNAME=cloud
export DIB_DEV_USER_PWDLESS_SUDO=yes
export DIB_DEV_USER_PASSWORD=frankming@2022++
echo 'ironic-python-agent tar /tmp/ironic-python-agent http://10.33.41.25/CI/openstack-train/others/ironic-python-agent-train.tar.gz *' > /usr/local/share/ironic-python-agent-builder/dib/ironic-python-agent-ramdisk/source-repository-ironic-python-agent
echo 'ironic-lib tar /tmp/ironic-lib http://10.33.41.25/CI/openstack-train/others/ironic-lib-stable-train.tar.gz *' > /usr/local/share/ironic-python-agent-builder/dib/ironic-python-agent-ramdisk/source-repository-ironic-lib
echo 'requirements tar /tmp/requirements http://10.33.41.25/CI/openstack-train/others/requirements-stable-victoria.tar.gz *' > /usr/local/share/ironic-python-agent-builder/dib/ironic-python-agent-ramdisk/source-repository-requirements
ironic-python-agent-builder -o my-ipa debian -e devuser -e stable-interface-names

注意事项

Cannot open: https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm. Skipping.

centos7独有

文件位于diskimage_builder\elements\yum\pre-install.d\01-00-centos-python3,内网环境需将该行注释,且配置DIB_YUM_MINIMAL_BOOTSTRAP_REPOS环境变量需要有epel仓库

容器中运行需添加--privileged选项

mount -o size=20G -o remount /dev

mount -o size=20G -o remount /dev/shm

dib无法直接得知需要的程序依赖,可能出现构建到一半才报错无此命令的情况。如果通过pip安装,更是需要手动把所有的依赖程序都安装上。

理想的系统镜像构建工具还是得类似于docker那样,通过dockerfile直观、简便地构建。

二次开发后执行发现脚本没执行?

windows下文件无rwx权限管理,所有文件默认无w权限,所以dib执行时将脚本文件当成普通文件,跳过执行

cpio -idmv < xxx.cpio

同类型工具

Oz

image-bootstrap

imagefactory

参考文档

Tool support for image creation — Virtual Machine Image Guide documentation (openstack.org)

镜像制作工具diskimage-builder介绍的更多相关文章

  1. yaffs2文件镜像制作工具yaffs2image

    1.  不同nand容量,工具不一样. 首先使用的是mkyaffs2image,编译生成根文件系统的镜像之后,下载到板子上,启动的时候报错,错误代码这里没有上传.问题出在工具使用的不正确,查看工具目录 ...

  2. Mac OS平台下应用程序安装包制作工具Packages的使用介绍

    一.介绍 Windows下面开发好的应用程序要进行分发时有很多打包工具可供选择,如Inno Setup, InstallShield, NSIS, Advanced Installer, Qt Ins ...

  3. 制作镜像文件工具packer

    openstack镜像制作要在openstack上创建虚拟机,必然要使用到虚拟机镜像. 对于普通用户,可以使用已经创建好的虚拟机镜像.一般是操作系统官方构建并提供的. 某些用户可以有自己独特的需求,需 ...

  4. Mac OS平台下应用程序安装包制作工具Packages的使用介绍(补充)

    上一篇:Mac OS平台下应用程序安装包制作工具Packages的使用介绍 补充说明 上一篇文章中介绍了如何使用Packages如何创建mac下的安装包.但是这样制作出来的安装包只能安装到系统的文件路 ...

  5. 我的Android进阶之旅------>介绍一款集录制与剪辑为一体的屏幕GIF 动画制作工具 GifCam

    由于上一篇文章:我的Android进阶之旅------>Android之动画之Frame Animation实例 中展示的是Frame动画效果,但是之前我是将图片截取下来,不好说明确切的动画过程 ...

  6. [置顶] 我的Android进阶之旅------>介绍一款集录制与剪辑为一体的屏幕GIF 动画制作工具 GifCam

    由于上一篇文章:我的Android进阶之旅------>Android之动画之Frame Animation实例 中展示的是Frame动画效果,但是之前我是将图片截取下来,不好说明确切的动画过程 ...

  7. Docker系列-(2) 镜像制作与发布

    上篇文章引入了Docker的基本原理和操作,本节文章主要介绍如何制作Docker镜像和发布. 镜像文件结构 Docker镜像的本质是一系列文件的集合,这些文件依次叠加,形成了最后的镜像文件,类似于下图 ...

  8. 如何用 ISO 镜像制作 U 盘安装盘(通用方法、无需 WinPE)

    今天聊的这个话题属于老生常谈,这几年时常有读者来询问(现在有越来越多的电脑是无光驱的).再加上俺后面要扫盲一些“特殊的 Linux 发行版”,到时候肯定又要涉及到制作可引导U盘的事情.所以,今天先单独 ...

  9. Docker 镜像制作教程:针对不同语言的精简策略

    本系列文章将分为三个部分: 第一部分着重介绍多阶段构建(multi-stage builds),因为这是镜像精简之路至关重要的一环.在这部分内容中,我会解释静态链接和动态链接的区别,它们对镜像带来的影 ...

随机推荐

  1. 在 C# CLR 中学习 C++ 之了解 extern

    一:背景 在 CLR 源码中有很多的 extern 和 extern "C" 这样的关键词,比如下面这些代码: extern size_t gc_global_mechanisms ...

  2. KingbaseES行转列(PIVOT)

    如果以交叉表格式显示,则商业智能查询返回的数据通常是最有用的.SELECT语句的pivot_.数据透视是数据仓库中的一项关键技术.在其中,您可以将多行输入转换为数据仓库中较少且通常较宽的行.进行数据透 ...

  3. KingbaseES 转义字符

    在SQL标准中字符串是用单引号括起来的,在KingbaseES中遵守了该标准,如果在字符串中需要使用到单引号,就需要对其进行转义. 方式一:使用E和反斜杠进行转义 方式二:直接用一个单引号来转义 在K ...

  4. 跨语言调用C#代码的新方式-DllExport

    简介 上一篇文章使用C#编写一个.NET分析器文章发布以后,很多小伙伴都对最新的NativeAOT函数导出比较感兴趣,今天故写一篇短文来介绍一下如何使用它. 在以前,如果有其他语言需要调用C#编写的库 ...

  5. 使用 Elastic 技术栈构建 K8S 全栈监控 -2: 用 Metricbeat 对 Kubernetes 集群进行监控

    文章转载自:https://www.qikqiak.com/post/k8s-monitor-use-elastic-stack-2/ 操作步骤 git clone https://github.co ...

  6. 使用MinIO中暂未解决的问题

    时间显示问题 web页面上创建桶的时间跟使用SDK获取的时间不一样,相差8个小时,但是mc命令行客户端获取的时间跟web上的一样

  7. Elasticsearch: analyzer

    在今天的文章中,我们来进一步了解analyzer. analyzer执行将输入字符流分解为token的过程,它一般发生在两个场合: 在indexing的时候,也即在建立索引的时候 在searching ...

  8. 3_JSP

    一. 引言 1.1 现有问题 在之前学习Servlet时, 服务器通过Servlet响应客户端页面, 有什么不足之处? 开发方式麻烦: 继承父类, 覆盖方法, 配置web.xml或注解 代码修改麻烦: ...

  9. C++ 队列!还是要从 STL 中的说起……

    1. 前言 队列和栈一样,都是受限的数据结构. 队列遵循先进先出的存储原则,类似于一根水管,水从一端进入,再从另一端出去.进入的一端称为队尾,出去的一端称为队头. 队列有 2 个常规操作: 入队:进入 ...

  10. 成功解决:Can‘t find Python executable “python“, you can set the PYTHON env variable.

    今天跑公司新项目的时候.运行前端vue.报了一个关于python的错误.就离谱 1.问题报错全部代码 actual version of core-js. npm ERR! code 1 npm ER ...