镜像制作工具diskimage-builder介绍
简介
diskimage-builder(简称dib)是一款用于构建系统镜像的工具,它被设计用于OpenStack的TripleO项目,支持qocw2、vhd、raw等主流镜像格式。
在众多系统镜像构建工具中,dib与众不同的地方在于其对元素(element)的设计。在dib中,所有想要构建的实体都被抽象为一个个的元素,元素与元素之间相互依赖,形成一种类似树的结构。dib拥有一些内置元素,位于diskimage-builder/elements
目录中,可以通过ELEMENTS_PATH
环境变量指定额外的元素目录。
例如:使用dib构建镜像时指定centos-minimal元素。
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:镜像文件所在的位置,可选
- Local Loop:该模块用于生成一个本地镜像文件
- 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
命令的参数列表,可选
- pvs:物理卷的列表,每个列表元素描述了一个物理卷(Physical Volume)
- Partitioning:该模块用于为已有块设备生成分区
- Level 2
- Mkfs:该模块用于为已有分区创建文件系统
- base:分区的名称,Mkfs在此分区上创建文件系统,必选
- name:文件系统的名称,必选
- type:文件系统的类型,比如ext4或xfs,必选
- label:文件系统的标识,可被grub和fstab使用,默认和名称相同,可选
- opts:创建文件系统的可选选项列表,即传递给
mkfs
命令的参数列表,可选 - uuid:文件系统的uuid,目前支持ext2、ext3、ext4、xfs
- Mkfs:该模块用于为已有分区创建文件系统
- Level 3
- Mount:该模块用于挂载一个文件系统
- base:文件系统的名称,Mount会挂载此文件系统,必选
- name:挂载点的名称,必选
- mount_point:挂载点的路径,必选
- Mount:该模块用于挂载一个文件系统
- Level 4
- fstab:该模块用于创建fstab入口
- base:挂载点的名称,用于写入fstab,必选
- name:fstab入口的名称,必选
- options:特殊的挂载选项,对应fstab中的第四列,默认为
default
,可选 - dump-freq:文件系统是否需要导出,对应fstab的第五列,默认为
0
,可选 - fsck-passno:是否需要运行fsck,该工具用来检测/修复文件系统,对应fstab的第六列,默认为
2
,可选
- fstab:该模块用于创建fstab入口
执行阶段
每个元素下有许多目录,这些目录以阶段命名,dib会在不同的阶段执行这些目录下的脚本,这些脚本有着两位数数字的前缀,并会以数字的顺序执行。
dib共有如下阶段:
- root.d:初始化根文件系统,该阶段的主要工作是获取根文件系统的文件,并放置于工作区域($TARGET_ROOT)中。该阶段依赖于各发行版,也可以在已有镜像上定制。
- 运行于:chroot外面
- 输入:
- $ARCH=i386|amd64|armhf|arm64
- $TARGET_ROOT=/path/to/target/workarea
- extra-data.d:从宿主机环境中获取额外数据,这些数据会在镜像构建中使用。该阶段通常用来复制配置文件至工作区域($TMP_MOUNT_PATH)中,比如复制yum repo至
$TMP_MOUNT_PATH/etc/yum.repos.d
。- 运行于:chroot外面
- 输入:
- $TMP_HOOKS_PATH:表示chroot里面的/tmp/in_target.d目录
- pre-install.d:在chroot里面运行代码。该阶段用于在定制镜像之前做一些事先配置工作,比如说在配置dnf包管理工具、更新包缓存、安装python基础环境等等。
- 运行于:chroot里面
- install.d:运行于pre-install.d之后。该阶段用于安装包,也可以做一些镜像特定的操作。
- 运行于:chroot里面
- post-install.d:运行于install.d之后。该阶段往往用来做一些清理工作,比如说清理安装缓存。
- 运行于:chroot里面
- post-root.d:在chroot外面运行代码。该阶段用来执行一些不能在chroot里面做且需要在安装步骤之后做的事情,根文件系统位于
$TMP_BUILD_DIR/mnt
目录下。- 运行于:chroot外面
- block-device.d:自定义镜像所在的块设备。在目标树生成之后执行,该步骤暂时没看到元素在使用。
- 运行于:chroot外面
- 输入:
- $IMAGE_BLOCK_DEVICE={path}
- $TARGET_ROOT={path}
- 输出:
- $IMAGE_BLOCK_DEVICE={path}
- pre-finalise.d:该步骤用来重新挂载文件系统,到此步骤时根文件系统已经复制到最终的文件系统中,该文件系统位于
$TMP_BUILD_DIR/mnt
。- 运行于:chroot外面
- finalise.d:该步骤是根文件系统构建的最后一步,该步骤会运行chroot到最终的文件系统中,然后执行一些脚本。该步骤往往用来生成grub配置。
- 运行于:chroot里面
- 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-mbr
、xxx 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介绍的更多相关文章
- yaffs2文件镜像制作工具yaffs2image
1. 不同nand容量,工具不一样. 首先使用的是mkyaffs2image,编译生成根文件系统的镜像之后,下载到板子上,启动的时候报错,错误代码这里没有上传.问题出在工具使用的不正确,查看工具目录 ...
- Mac OS平台下应用程序安装包制作工具Packages的使用介绍
一.介绍 Windows下面开发好的应用程序要进行分发时有很多打包工具可供选择,如Inno Setup, InstallShield, NSIS, Advanced Installer, Qt Ins ...
- 制作镜像文件工具packer
openstack镜像制作要在openstack上创建虚拟机,必然要使用到虚拟机镜像. 对于普通用户,可以使用已经创建好的虚拟机镜像.一般是操作系统官方构建并提供的. 某些用户可以有自己独特的需求,需 ...
- Mac OS平台下应用程序安装包制作工具Packages的使用介绍(补充)
上一篇:Mac OS平台下应用程序安装包制作工具Packages的使用介绍 补充说明 上一篇文章中介绍了如何使用Packages如何创建mac下的安装包.但是这样制作出来的安装包只能安装到系统的文件路 ...
- 我的Android进阶之旅------>介绍一款集录制与剪辑为一体的屏幕GIF 动画制作工具 GifCam
由于上一篇文章:我的Android进阶之旅------>Android之动画之Frame Animation实例 中展示的是Frame动画效果,但是之前我是将图片截取下来,不好说明确切的动画过程 ...
- [置顶] 我的Android进阶之旅------>介绍一款集录制与剪辑为一体的屏幕GIF 动画制作工具 GifCam
由于上一篇文章:我的Android进阶之旅------>Android之动画之Frame Animation实例 中展示的是Frame动画效果,但是之前我是将图片截取下来,不好说明确切的动画过程 ...
- Docker系列-(2) 镜像制作与发布
上篇文章引入了Docker的基本原理和操作,本节文章主要介绍如何制作Docker镜像和发布. 镜像文件结构 Docker镜像的本质是一系列文件的集合,这些文件依次叠加,形成了最后的镜像文件,类似于下图 ...
- 如何用 ISO 镜像制作 U 盘安装盘(通用方法、无需 WinPE)
今天聊的这个话题属于老生常谈,这几年时常有读者来询问(现在有越来越多的电脑是无光驱的).再加上俺后面要扫盲一些“特殊的 Linux 发行版”,到时候肯定又要涉及到制作可引导U盘的事情.所以,今天先单独 ...
- Docker 镜像制作教程:针对不同语言的精简策略
本系列文章将分为三个部分: 第一部分着重介绍多阶段构建(multi-stage builds),因为这是镜像精简之路至关重要的一环.在这部分内容中,我会解释静态链接和动态链接的区别,它们对镜像带来的影 ...
随机推荐
- 在 C# CLR 中学习 C++ 之了解 extern
一:背景 在 CLR 源码中有很多的 extern 和 extern "C" 这样的关键词,比如下面这些代码: extern size_t gc_global_mechanisms ...
- KingbaseES行转列(PIVOT)
如果以交叉表格式显示,则商业智能查询返回的数据通常是最有用的.SELECT语句的pivot_.数据透视是数据仓库中的一项关键技术.在其中,您可以将多行输入转换为数据仓库中较少且通常较宽的行.进行数据透 ...
- KingbaseES 转义字符
在SQL标准中字符串是用单引号括起来的,在KingbaseES中遵守了该标准,如果在字符串中需要使用到单引号,就需要对其进行转义. 方式一:使用E和反斜杠进行转义 方式二:直接用一个单引号来转义 在K ...
- 跨语言调用C#代码的新方式-DllExport
简介 上一篇文章使用C#编写一个.NET分析器文章发布以后,很多小伙伴都对最新的NativeAOT函数导出比较感兴趣,今天故写一篇短文来介绍一下如何使用它. 在以前,如果有其他语言需要调用C#编写的库 ...
- 使用 Elastic 技术栈构建 K8S 全栈监控 -2: 用 Metricbeat 对 Kubernetes 集群进行监控
文章转载自:https://www.qikqiak.com/post/k8s-monitor-use-elastic-stack-2/ 操作步骤 git clone https://github.co ...
- 使用MinIO中暂未解决的问题
时间显示问题 web页面上创建桶的时间跟使用SDK获取的时间不一样,相差8个小时,但是mc命令行客户端获取的时间跟web上的一样
- Elasticsearch: analyzer
在今天的文章中,我们来进一步了解analyzer. analyzer执行将输入字符流分解为token的过程,它一般发生在两个场合: 在indexing的时候,也即在建立索引的时候 在searching ...
- 3_JSP
一. 引言 1.1 现有问题 在之前学习Servlet时, 服务器通过Servlet响应客户端页面, 有什么不足之处? 开发方式麻烦: 继承父类, 覆盖方法, 配置web.xml或注解 代码修改麻烦: ...
- C++ 队列!还是要从 STL 中的说起……
1. 前言 队列和栈一样,都是受限的数据结构. 队列遵循先进先出的存储原则,类似于一根水管,水从一端进入,再从另一端出去.进入的一端称为队尾,出去的一端称为队头. 队列有 2 个常规操作: 入队:进入 ...
- 成功解决: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 ...