We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
作者:@wjunLu
eulerpublisher作为一款openEuler“一键式”发布工具,提供openEuler容器镜像、云镜像、WSL等镜像定制、发布和测试的能力。本项目主要使用python语言实现,并且以CLI的方式提供给用户使用。
eulerpublisher
CLI
eulerpublisher按照使用场景,分为容器镜像(container)、云镜像(cloudimg)、WSL(wsl)这几个模块,而每个模块又按照子场景划分不同的子功能模块,每个子场景功能模块具备prepare、build、publish、check等能力,因而形成一种按照主场景、子场景、以及对应动作构成的分层软件架构,如图所示:
以下围绕eulerpublisher cli的使用方式,来理解eulerpublisher的软件架构,cli通用形式如下:
eulerpublisher cli
cli
eulerpublisher <Command1> <Command2> <Command3> <Options>
详细说明如下:
Command1 Command1为主场景命令,使用时必填,取值有container、cloudimg、wsl等
Command1
container
cloudimg
wsl
Command2 Command2确定子场景,使用时可选,具体情况如下:
Command2
Docker
aws
azure
hwcloud
Command3 Command3是Command 1~2 组合场景下的“动作”,可选prepare、build、push、publish、check等,具体Command 1~3的可选组合请使用eulerpublisher --help逐级查看
Command3
Command 1~2
prepare
build
push
publish
check
Command 1~3
eulerpublisher --help
Options Options是被执行命令的一组参数,每个不同的Command 1~3组合会有不同的参数选择,使用eulerpublisher --help查看。
Options
示例如下:
container场景
# 容器镜像发布 eulerpublisher container publish --repo openeuler/openeuler --version 22.03-LTS-SP1 --registry registry-1.docker.io --dockerfile /Path/To/Dockerfile
上述效果是向dockerhub(https://hub.docker.com)的openeuler/openeuler仓库发布由Dockerfile定制的tag为22.03-LTS-SP1的支持arm64、amd64多平台的openeuler容器镜像。
cloudimg场景
# AMI镜像构建 eulerpublisher cloudimg aws build --version 22.03-LTS-SP1 --arch aarch64 --bucket openeuler --region ap-southeast-2
此命令将在AWS的ap-southeast-2区的AMI列表生成一个22.03-LTS-SP1版本的aarch64架构的openEuler镜像,其制作的原始镜像来源于openeuler桶中。
ap-southeast-2
22.03-LTS-SP1
aarch64
openeuler
eulerpublisher基于Docker CLI和Dockerfile实现定制Docker容器镜像的功能。在介绍eulerpublisher实现容器镜像构建的原理之前,有必要先梳理一下有关的背景知识:
容器镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的配置参数。关于容器和容器镜像的关系,可以类比为程序设计中的类和实例,容器镜像是静态的类定义,容器是镜像运行时的实例。
Docker镜像是由多个文件系统叠加而成。最底层是一个引导文件系统,即bootfs,第二层是root文件系统 rootfs,它位于bootfs之上,其他的文件系统在rootfs之上。
bootfs
rootfs
在Docker镜像中,所有的文件系统是只读的,这也体现了Docker镜像的静态属性。当Docker启动一个容器时,会加载这些只读层并在这些只读层的上面增加一个读写层,该读写层一般也被称为容器层。这时如果修改正在运行的容器中已有的文件,那么这个文件将会从只读层复制到读写层。该文件的只读版本还在,只是被上面读写层的该文件的副本隐藏。当删除docker,或者重新启动时,之前的更改将会消失。
Dockerfile是构建Docker镜像的“生产手册”,决定着Docker镜像的内容,以下是Dockerfile指令
示例
# eulerpublisher的默认Dockerfile FROM scratch ARG TARGETARCH ADD openEuler-docker-rootfs.$TARGETARCH.tar.xz / RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime && \ sed -i "s/TMOUT=300/TMOUT=0/g" /etc/bashrc CMD ["bash"]
解释
需要注意的是,通过Dockerfile构建Docker镜像时,Dockerfile中的每一个写指令执行后都将会在最终镜像增加一层。因此,为了减少镜像的分层(又称为镜像裁剪),编写Dockerfile时尽可能一行命令执行多个写操作。如上述Dockerfile中RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime && \ sed -i "s/TMOUT=300/TMOUT=0/g" /etc/bashrc使用一行命令执行2个操作也是出于此目的。
RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime && \ sed -i "s/TMOUT=300/TMOUT=0/g" /etc/bashrc
使用eulerpublisher默认Dockerfile构建的镜像分层(size不为0的)如下
IMAGE CREATED CREATED BY SIZE COMMENT d9bff1b2db49 7 months ago CMD ["bash"] 0B buildkit.dockerfile.v0 <missing> 7 months ago RUN |1 TARGETARCH=amd64 /bin/sh -c ln -sf /u… 168kB buildkit.dockerfile.v0 <missing> 7 months ago ADD openEuler-docker-rootfs.amd64.tar.xz / #… 191MB buildkit.dockerfile.v0 <missing> 7 months ago ARG TARGETARCH 0B buildkit.dockerfile.v0
eulerpublisher使用docker buildx build命令构建多架构(linux/arm64, linux/amd64)的openEuler镜像,核心命令示例如下:
docker buildx build
docker buildx build -t openeuler/openeuler:22.03-LTS-SP1 --platform linux/arm64,linux/amd64 --push .
该命令使用默认Dockerfile(见上文)构建openEuler镜像,由于多平台镜像构建结果无法在本地缓存,只能使用--push保存在openeuler/openeuler仓库中。
--push
openeuler/openeuler
有了上述基础以后,eulerpublisher构建容器镜像的思路就很容易理解。
1)按照Dockerfile的内容,eulerpublisher制作镜像前需要先获取openEuler-docker-rootfs.$TARGETARCH.tar.xz。该步骤由prepare功能实现,执行命令示例如下
openEuler-docker-rootfs.$TARGETARCH.tar.xz
eulerpublisher container prepare --version 22.03-LTS-SP1
该命令从http://repo.openeuler.org/下载aarch64和x86_64的原始镜像,将主要文件重新压缩后得到openEuler-docker-rootfs.amd64.tar.xz和openEuler-docker-rootfs.arm64.tar.xz两个文件。
openEuler-docker-rootfs.amd64.tar.xz
openEuler-docker-rootfs.arm64.tar.xz
2)获取openEuler-docker-rootfs.$TARGETARCH.tar.xz之后,使用push功能构建并保存镜像,命令示例如下
eulerpublisher container push --repo openeuler/openeuler --version 22.03-LTS-SP1 --registry registry-1.docker.io --dockerfile /Path/To/Dockerfile
该命令的核心步骤就是执行docker buildx build,构建的镜像将会保存在dockerhub的openeuler/openeuler仓库,tag为22.03-LTS-SP1。
这部分描述eulerpublisher构建符合云商marketplace发布要求的云镜像的基本原理,按厂商不同分开说明
AWS Marketplace对发布的镜像规格存在一定约束:
为了满足上述约束,eulerpublisher提供如下两个脚本
aws_resize.sh
aws_install.sh
eulerpublisher构建AMI分为两个阶段: 1. prepare阶段
# prepare命令 eulerpublisher -v {VERSION} -a {ARCH} -b {BUCKET}
(a). 从repo.openeuler.org下载版本为VERSION、架构为ARCH的原始qcow2镜像 (b). (arm镜像)配置ena.ko使能 (c). 通过aws_resize.sh脚本resize该qcow2镜像并转换格式为RAW (d). 通过AWS CLI将处理后的RAW镜像upload到AWS S3存储桶BUCKET中 以上操作均在本地完成,得到制作AMI的基础镜像。
VERSION
ARCH
BUCKET
2. build阶段
# build命令 eulerpublisher -v {VERSION} -a {ARCH} -b {BUCKET} -r {REGION} -p {RPMLIST}
eulerpublisher通过packer在prepare的结果之上实现对AMI的定制,具体处理如下 (e). 使用packer启动REGION中存储桶BUCKET的 “基础云镜像” 虚拟机实例 (f). 在虚拟机中安装基础软件包,删除 root 密码、禁用password登录等。 (g). 最终制作的云镜像命名为openEuler-{VERSION}-{ARCH}-{DATETIME}-hvm 上述过程中需要准备好packer配置文件,packer配置文件的内容会由eulerpublisher进行填充。此外,若用户需要在最终镜像内预置软件包,需要提供rpmlist
REGION
rpmlist
# x86镜像构建的packer配置文件 { "builders": [ { "type": "amazon-ebs", "name": "amazon-ebs-hvm-amd64", "region": "ap-southeast-2", "ami_regions": [ "ap-southeast-2" ], "source_ami": "ami-0df315962e87a4cae", "instance_type": "t3a.micro", "ssh_username": "root", "ssh_password": "openEuler12#$", "ami_name": "openEuler-22.03-LTS-SP1-x86_64-20230719-hvm", "ena_support": "true" } ], "provisioners": [ { "type": "shell", "environment_vars": [ ], "script": "aws_install.sh" } ] }
# rpmlist示例 cloud-init wget tar telnet unzip curl ...
The text was updated successfully, but these errors were encountered:
No branches or pull requests
作者:@wjunLu
1. EulerPublisher架构
eulerpublisher
作为一款openEuler“一键式”发布工具,提供openEuler容器镜像、云镜像、WSL等镜像定制、发布和测试的能力。本项目主要使用python语言实现,并且以CLI
的方式提供给用户使用。eulerpublisher
按照使用场景,分为容器镜像(container)、云镜像(cloudimg)、WSL(wsl)这几个模块,而每个模块又按照子场景划分不同的子功能模块,每个子场景功能模块具备prepare、build、publish、check等能力,因而形成一种按照主场景、子场景、以及对应动作构成的分层软件架构,如图所示:以下围绕
eulerpublisher cli
的使用方式,来理解eulerpublisher
的软件架构,cli
通用形式如下:详细说明如下:
Command1
Command1
为主场景命令,使用时必填,取值有container
、cloudimg
、wsl
等Command2
Command2
确定子场景,使用时可选,具体情况如下:container
场景,使用Docker
完成镜像构建等一系列动作,暂无其他子场景,无 Command2;cloudimg
场景,会针对不同云厂商有着不同的镜像定制及发布要求,因此Command 2必选,取值有aws
、azure
、hwcloud
等。Command3
Command3
是Command 1~2
组合场景下的“动作”,可选prepare
、build
、push
、publish
、check
等,具体Command 1~3
的可选组合请使用eulerpublisher --help
逐级查看Options
Options
是被执行命令的一组参数,每个不同的Command 1~3
组合会有不同的参数选择,使用eulerpublisher --help
查看。示例如下:
上述效果是向dockerhub(https://hub.docker.com)的openeuler/openeuler仓库发布由Dockerfile定制的tag为22.03-LTS-SP1的支持arm64、amd64多平台的openeuler容器镜像。
此命令将在AWS的
ap-southeast-2
区的AMI列表生成一个22.03-LTS-SP1
版本的aarch64
架构的openEuler镜像,其制作的原始镜像来源于openeuler
桶中。2. EulerPublisher容器镜像构建原理
背景
eulerpublisher
基于Docker CLI和Dockerfile实现定制Docker容器镜像的功能。在介绍eulerpublisher
实现容器镜像构建的原理之前,有必要先梳理一下有关的背景知识:1). 容器镜像
容器镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的配置参数。关于容器和容器镜像的关系,可以类比为程序设计中的类和实例,容器镜像是静态的类定义,容器是镜像运行时的实例。
2). Docker镜像分层
Docker镜像是由多个文件系统叠加而成。最底层是一个引导文件系统,即
bootfs
,第二层是root文件系统rootfs
,它位于bootfs
之上,其他的文件系统在rootfs
之上。在Docker镜像中,所有的文件系统是只读的,这也体现了Docker镜像的静态属性。当Docker启动一个容器时,会加载这些只读层并在这些只读层的上面增加一个读写层,该读写层一般也被称为容器层。这时如果修改正在运行的容器中已有的文件,那么这个文件将会从只读层复制到读写层。该文件的只读版本还在,只是被上面读写层的该文件的副本隐藏。当删除docker,或者重新启动时,之前的更改将会消失。
3). Dockerfile
Dockerfile是构建Docker镜像的“生产手册”,决定着Docker镜像的内容,以下是Dockerfile指令
指定构建的Docker镜像的基础镜像是scratch,即一个空白镜像,没有预装任何软件包或依赖项。
声明一个构建变量TARGETARCH,在构建过程中会提供该变量的值。
将根文件系统的压缩包(openEuler-docker-rootfs.$TARGETARCH.tar.xz)添加到Docker镜像的根目录(/)中。
设置系统时区为UTC、设置TMOUT=0、更新yum并清理缓存。
指定了在Docker镜像运行容器时要执行的默认命令为bash,即启动一个交互式的Bash shell会话。
需要注意的是,通过Dockerfile构建Docker镜像时,Dockerfile中的每一个写指令执行后都将会在最终镜像增加一层。因此,为了减少镜像的分层(又称为镜像裁剪),编写Dockerfile时尽可能一行命令执行多个写操作。如上述Dockerfile中
RUN ln -sf /usr/share/zoneinfo/UTC /etc/localtime && \ sed -i "s/TMOUT=300/TMOUT=0/g" /etc/bashrc
使用一行命令执行2个操作也是出于此目的。使用eulerpublisher默认Dockerfile构建的镜像分层(size不为0的)如下
4). docker buildx build
eulerpublisher
使用docker buildx build
命令构建多架构(linux/arm64, linux/amd64)的openEuler镜像,核心命令示例如下:该命令使用默认Dockerfile(见上文)构建openEuler镜像,由于多平台镜像构建结果无法在本地缓存,只能使用
--push
保存在openeuler/openeuler
仓库中。Eulerpublisher容器镜像构建
有了上述基础以后,
eulerpublisher
构建容器镜像的思路就很容易理解。1)按照Dockerfile的内容,
eulerpublisher
制作镜像前需要先获取openEuler-docker-rootfs.$TARGETARCH.tar.xz
。该步骤由prepare
功能实现,执行命令示例如下该命令从http://repo.openeuler.org/下载aarch64和x86_64的原始镜像,将主要文件重新压缩后得到
openEuler-docker-rootfs.amd64.tar.xz
和openEuler-docker-rootfs.arm64.tar.xz
两个文件。2)获取
openEuler-docker-rootfs.$TARGETARCH.tar.xz
之后,使用push
功能构建并保存镜像,命令示例如下该命令的核心步骤就是执行
docker buildx build
,构建的镜像将会保存在dockerhub的openeuler/openeuler
仓库,tag为22.03-LTS-SP1
。3. EulerPublisher云镜像构建原理
这部分描述eulerpublisher构建符合云商marketplace发布要求的云镜像的基本原理,按厂商不同分开说明
AWS
镜像发布要求
AWS Marketplace对发布的镜像规格存在一定约束:
为了满足上述约束,eulerpublisher提供如下两个脚本
aws_resize.sh
用于改变镜像大小和格式,并配置arm版本的ena.ko使能aws_install.sh
用于修改镜像默认配置,并安装预置软件包AMI构建原理
eulerpublisher构建AMI分为两个阶段:
1. prepare阶段
(a). 从repo.openeuler.org下载版本为
VERSION
、架构为ARCH
的原始qcow2镜像(b). (arm镜像)配置ena.ko使能
(c). 通过
aws_resize.sh
脚本resize该qcow2镜像并转换格式为RAW(d). 通过AWS CLI将处理后的RAW镜像upload到AWS S3存储桶
BUCKET
中以上操作均在本地完成,得到制作AMI的基础镜像。
2. build阶段
eulerpublisher通过packer在prepare的结果之上实现对AMI的定制,具体处理如下
(e). 使用packer启动
REGION
中存储桶BUCKET
的 “基础云镜像” 虚拟机实例(f). 在虚拟机中安装基础软件包,删除 root 密码、禁用password登录等。
(g). 最终制作的云镜像命名为openEuler-{VERSION}-{ARCH}-{DATETIME}-hvm
上述过程中需要准备好packer配置文件,packer配置文件的内容会由eulerpublisher进行填充。此外,若用户需要在最终镜像内预置软件包,需要提供
rpmlist
The text was updated successfully, but these errors were encountered: