使用Docker镜像构建RPM包

简介: 本文讲的是使用Docker镜像构建RPM包,【编者的话】RPM(Red Hat Package Manager)是用于 Linux 分发版的最常见的软件包管理器。因为它允许分发已编译的软件,所以用户只用一个命令就可以安装软件。
本文讲的是使用Docker镜像构建RPM包, 【编者的话】RPM(Red Hat Package Manager)是用于 Linux 分发版的最常见的软件包管理器。因为它允许分发已编译的软件,所以用户只用一个命令就可以安装软件。而RPM包的构建相当繁琐,并且对环境的要求比较高,本文作者介绍了如何借助Docker来构建可以适用多个平台的RPM包。

在一个内部项目中,我一直在思考如何通过非CI工具/流程生成RPM包,我想手动生成RPM包,这样我可以测试它们是否能正常安装,并用于正常的 冒烟测试 (译者注:冒烟测试就是在每日构建完成后,对系统的基本功能进行简单的测试。这种测试强调功能的覆盖率,而不对功能的正确性进行验证)。

在我们的CI流程中,Docker算是个全能手,所以我也在想能否将Docker镜像和RPM结合起来。理想的情况下,让RPM与Docker集成, 这样,创建RPM包的过程其实就是在构建一个Docker镜像。基本上,RPM包的%prep部分的构建可以在一个特殊的Docker镜像中快速完成,然后将生成的RPM包返回给主机。

这种方式的的优点在于,你的RPM包是在一个相对封闭且可再生的环境中构建的,所以你可以快速的为CentOS、Fedora、RHEL等其它系统构建RPM包。

我相信还有其它的一些变通方法也可以完成这样的工作,比如chroot之类的。但如果在RPM中内建这种打包机制(通过chroot/Docker或者别的容器技术抽象而来的系统来完成打包工作)的话,我想会更好。

由于我的项目还没有完成,所以我只是对我的想法进行了验证:简单构建一个包含依赖的镜像。

这是一个使用 PBR 生成版本的Python项目。 首先我在build目录中生成一个tarball,然后得到生成的版本号,紧接着修改spec文件中的版本号,然后开始用新的tar包和spec文件构建镜像。最后运行镜像,并挂载卷(Volume)到本地目录。当运行容器中的start.sh脚本之后,镜像就运行起来了。

start.sh相当简单。 它构建好RPM包后,以root身份把它拷贝到卷目录下, 还可以从主机上将它拷贝到output目录。我没有将它拷贝或者说更新到类似swift之类的对象存储系统,因为我还要在CI中使用它,所以就使用本地文件拷贝了。

在SPECS/project.spec以及 SOURCES/* 是标准RPM包需要的spec文件,源文件和patch文件。需要做的唯一一件事是定义%define_version宏,并在spec文件中使用它。下面是我的一些脚本。

主脚本 build.sh 。 可以从CI中运行。
#!/bin/bash
set -exf
PROJECT=myproject

CURDIR=$(dirname $(readlink -f $0))
TOPDIR=$(git rev-parse --show-topklevel 2>/dev/null)

rm -rf ${CURDIR}/.build/rpm
mkdir -p ${CURDIR}/.build/rpm/{BUILD,SRPMS,SPECS,RPMS/noarch}
cp -r ${CURDIR}/SOURCES ${CURDIR}/.build/rpm

pushd ${TOPDIR} >/dev/null
python setup.py sdist --dist-dir ${CURDIR}/.build/rpm/SOURCES/
SALADIER_VERSION=$(sed -n '/^Version/ { s/.* //; p}' ${PROJECT}.egg-info/PKG-INFO)
popd >/dev/null

sed -e "s/%define _version.*/%define _version ${SALADIER_VERSION}/" ${CURDIR}/SPECS/${MYROJECT}.spec > \
        ${CURDIR}/.build/rpm/SPECS/${MYPROJECT}.spec

docker build -t chmouel/buildrpm ${CURDIR}
docker run -v $CURDIR/.build:/data -it chmouel/buildrpm

if [[ -n ${ARTIFACT_DIR} ]];then
    rm -rf ${ARTIFACT_DIR}/rpm
    cp -a ${CURDIR}/.build/output ${ARTIFACT_DIR}/rpm
fi

DockerFile,为Docker 缓存做了一些优化:
FROM fedora:21
MAINTAINER Chmouel Boudjnah <chmouel@enovance.com>

RUN yum -y groupinstall 'Development Tools'
RUN yum -y install fedora-packager
RUN yum -y install yum-utils

RUN yum -y install sudo
RUN sed -i.bak -n -e '/^Defaults.*requiretty/ { s/^/# /;};/^%wheel.*ALL$/ { s/^/# / ;} ;/^#.*wheel.*NOPASSWD/ { s/^#[ ]*//;};p' /etc/sudoers

RUN yum install -y https://rdo.fedorapeople.org/rdo-release.rpm

# This is an optimisation for caching, since using the auto generated one will
# make docker always run the builddep steps since new file
ADD SPECS/project.spec /tmp/
RUN yum-builddep -y /tmp/project.spec

ADD bin/start.sh /start.sh

RUN useradd -s /bin/bash -G adm,wheel,systemd-journal -m rpm

WORKDIR /home/rpm
CMD /start.sh

ADD .build/rpm/ /home/rpm/rpmbuild/
RUN chown -R rpm: /home/rpm

USER rpm

以及从容器中运行的 start.sh脚本
#!/bin/bash
# script run inside the container
rpmbuild -ba rpmbuild/SPECS/project.spec || exit 1

[[ -d /data ]] || exit 0

sudo rm -rf /data/output
sudo cp -a rpmbuild/RPMS/noarch /data/output

脚本可能无法直接在你的环境中使用,但至少能让你了解这个idea。

原文链接: Building RPM with Docker images (翻译:何林冲 审校:李颖杰)

原文发布时间为:2015-01-13 
本文作者:何林冲
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:使用Docker镜像构建RPM包
目录
相关文章
|
4天前
|
存储 安全 持续交付
【Docker 专栏】Docker 镜像的版本控制与管理
【5月更文挑战第9天】本文探讨了Docker镜像版本控制与管理的重要性,包括可重复性、回滚能力、协作开发和持续集成。常用方法有标签、构建参数和版本控制系统。管理策略涉及定期清理、分层管理和镜像仓库。语义化标签、环境变量和配置文件在版本控制中有应用。版本系统与Docker结合能跟踪历史和促进协作。注意点包括优化镜像大小、确保安全性和兼容性。案例分析和未来趋势展示了持续发展的镜像管理技术,为Docker应用的稳定与进步保驾护航。
【Docker 专栏】Docker 镜像的版本控制与管理
|
23小时前
|
存储 安全 开发者
如何删除 Docker 镜像、容器和卷?
【5月更文挑战第11天】
8 2
如何删除 Docker 镜像、容器和卷?
|
4天前
|
运维 安全 Docker
【Docker 专栏】Docker 镜像安全扫描与漏洞修复
【5月更文挑战第9天】Docker技术在软件开发和部署中带来便利,但其镜像安全问题不容忽视。本文探讨了Docker镜像安全扫描与漏洞修复,强调了镜像安全对应用和系统的重要性。文中介绍了静态和动态扫描方法,列举了软件漏洞、配置漏洞和恶意软件等常见安全问题,并提到了Clair和Trivy等扫描工具。修复策略包括更新软件、调整配置和重建镜像。此外,加强安全意识、规范镜像制作流程和定期扫描是管理建议。未来,将持续面对新的安全挑战,需持续研究和完善安全技术。
【Docker 专栏】Docker 镜像安全扫描与漏洞修复
|
4天前
|
运维 安全 Linux
深入理解Docker自定义网络:构建高效的容器网络环境
深入理解Docker自定义网络:构建高效的容器网络环境
|
4天前
|
Java Linux 数据安全/隐私保护
Docker自定义JDK镜像并拉取至阿里云镜像仓库全攻略
Docker自定义JDK镜像并拉取至阿里云镜像仓库全攻略
|
4天前
|
存储 弹性计算 运维
Docker数据集与自定义镜像:构建高效容器的关键要素
Docker数据集与自定义镜像:构建高效容器的关键要素
|
5天前
|
算法 计算机视觉 Docker
Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境
Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境
Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境
|
5天前
|
存储 缓存 运维
【Docker 专栏】Docker 镜像的分层存储与缓存机制
【5月更文挑战第8天】Docker 镜像采用分层存储,减少空间占用并提升构建效率。每个镜像由多个层组成,共享基础层(如 Ubuntu)和应用层。缓存机制加速构建和运行,通过检查已有层来避免重复操作。有效管理缓存,如清理无用缓存和控制大小,可优化性能。分层和缓存带来资源高效利用、快速构建和灵活管理,但也面临缓存失效和层管理挑战。理解这一机制对开发者和运维至关重要。
【Docker 专栏】Docker 镜像的分层存储与缓存机制
|
5天前
|
开发框架 安全 网络安全
【Docker 专栏】Docker 多平台应用构建与部署
【5月更文挑战第8天】Docker作为一种关键的容器化技术,简化了多平台应用的构建与部署。它提供一致的运行环境,确保应用在不同平台无缝运行;通过分层构建机制加速镜像创建,提升开发效率。Docker的可移植性、高效部署及资源利用率是其主要优势。流程包括开发环境准备、构建镜像、测试验证及部署。然而,面临操作系统差异、网络安全和资源限制等挑战,需注意安全、版本管理和性能优化。Docker在多平台场景的应用将持续发挥价值。
【Docker 专栏】Docker 多平台应用构建与部署
|
5天前
|
数据库 Docker 容器
【Docker 专栏】使用 Dockerfile 自动化构建 Docker 镜像
【5月更文挑战第8天】Dockerfile是构建Docker镜像的关键,它包含一系列指令,用于描述应用运行环境及所需软件包。通过自动化构建,能提高效率、保证可重复性并提升灵活性。确定基础镜像、安装依赖、设置环境后,执行Dockerfile生成镜像,用于应用程序部署。虽然需要熟悉Docker技术和应用细节,但其带来的益处使其成为现代软件开发和部署的重要工具。
【Docker 专栏】使用 Dockerfile 自动化构建 Docker 镜像