docker打包rpm
在完成了docker代码的编写和测试之后,如何发布docker程序?在centos上,一般使用RPM包进行打包。本文主要
如何打包一个RPM
RPM主要包括两种,一种是以二进制代码发布,一种是以源码发布。我们这里docker主要采用二进制代码发布。
RPM至少需要两个部分:
- spec文件。用以说明该rpm包的版本信息、依赖、所包含的文件、打包的流程等
- 源文件。
有了这些。使用rpmbuild工具就可以一键打包了。这里的关键就是编写spec文件。
docker的RPM包应该包括什么
要编写spec文件。要知道docker的RPM包应该包含什么。
依赖
以一个下载好的rpm包,可以查看其依赖。
[root@xxx ~]# rpm -qpR docker-io-1.3.2-2.el6.x86_64.rpm
/bin/sh
/bin/sh
/bin/sh
/bin/sh
/bin/sh
/bin/sh
bridge-utils
chkconfig
chkconfig
config(docker-io) = 1.3.2-2.el6
device-mapper-libs >= 1.02.90-1
initscripts
libc.so.6()(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libcgroup
libdevmapper.so.1.02()(64bit)
libdevmapper.so.1.02(Base)(64bit)
libpthread.so.0()(64bit)
libpthread.so.0(GLIBC_2.2.5)(64bit)
libsqlite3.so.0()(64bit)
lxc
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(VersionedDependencies) <= 3.0.3-1
rtld(GNU_HASH)
xz
rpmlib(PayloadIsXz) <= 5.2-1
包含的文件
同样,以一个下载的rpm包来查看。
[root@xxx ~]# rpm -qpl docker-io-1.3.0-1.el6.x86_64.rpm
/etc/rc.d/init.d/docker
/etc/sysconfig/docker
/etc/sysconfig/docker-storage
/etc/udev/rules.d/80-docker.rules
/usr/bin/docker
/usr/libexec/docker
/usr/libexec/docker/dockerinit
/usr/share/bash-completion/completions/docker
/usr/share/doc/docker-io-1.3.0
/usr/share/doc/docker-io-1.3.0/AUTHORS
/usr/share/doc/docker-io-1.3.0/CHANGELOG.md
/usr/share/doc/docker-io-1.3.0/CONTRIBUTING.md
/usr/share/doc/docker-io-1.3.0/LICENSE
/usr/share/doc/docker-io-1.3.0/LICENSE-vim-syntax
/usr/share/doc/docker-io-1.3.0/MAINTAINERS
/usr/share/doc/docker-io-1.3.0/NOTICE
/usr/share/doc/docker-io-1.3.0/README-vim-syntax.md
/usr/share/doc/docker-io-1.3.0/README.md
/usr/share/man/man1/docker-attach.1.gz
/usr/share/man/man1/docker-build.1.gz
/usr/share/man/man1/docker-commit.1.gz
/usr/share/man/man1/docker-cp.1.gz
/usr/share/man/man1/docker-create.1.gz
/usr/share/man/man1/docker-diff.1.gz
/usr/share/man/man1/docker-events.1.gz
/usr/share/man/man1/docker-exec.1.gz
/usr/share/man/man1/docker-export.1.gz
/usr/share/man/man1/docker-history.1.gz
/usr/share/man/man1/docker-images.1.gz
/usr/share/man/man1/docker-import.1.gz
/usr/share/man/man1/docker-info.1.gz
/usr/share/man/man1/docker-inspect.1.gz
/usr/share/man/man1/docker-kill.1.gz
/usr/share/man/man1/docker-load.1.gz
/usr/share/man/man1/docker-login.1.gz
/usr/share/man/man1/docker-logout.1.gz
/usr/share/man/man1/docker-logs.1.gz
/usr/share/man/man1/docker-pause.1.gz
/usr/share/man/man1/docker-port.1.gz
/usr/share/man/man1/docker-ps.1.gz
/usr/share/man/man1/docker-pull.1.gz
/usr/share/man/man1/docker-push.1.gz
/usr/share/man/man1/docker-restart.1.gz
/usr/share/man/man1/docker-rm.1.gz
/usr/share/man/man1/docker-rmi.1.gz
/usr/share/man/man1/docker-run.1.gz
/usr/share/man/man1/docker-save.1.gz
/usr/share/man/man1/docker-search.1.gz
/usr/share/man/man1/docker-start.1.gz
/usr/share/man/man1/docker-stop.1.gz
/usr/share/man/man1/docker-tag.1.gz
/usr/share/man/man1/docker-top.1.gz
/usr/share/man/man1/docker-unpause.1.gz
/usr/share/man/man1/docker-version.1.gz
/usr/share/man/man1/docker-wait.1.gz
/usr/share/man/man1/docker.1.gz
/usr/share/man/man5/Dockerfile.5.gz
/usr/share/vim/vimfiles/doc/dockerfile.txt
/usr/share/vim/vimfiles/ftdetect/dockerfile.vim
/usr/share/vim/vimfiles/syntax/dockerfile.vim
/usr/share/zsh/site-functions/_docker
/var/lib/docker
可以看到其实里面包含的荣还是很丰富的,不仅仅是docker的二进制代码,还有很多工具。比如自动补全配置,man的相关命令解释,vim的配置,以及init.d的脚本等。
docker编译环境
docker提供了一个比较好的方法,就是在run一个容器进行编译。
docker编译出来的二进制代码有两种方式。一种是通过make binary,编译出来的可执行文件,只有一个docker可执行文件。另一种是通过make dynbinary,编译出需要动态链接库的可执行文件。
前者的好处是不需要动态链接,相当于all in one。但是在实际中,一般都是通过后者。当动态链接函数库升级时,不必跟随重新编译docker代码。
但是默认的Dockerfile是FROM Ubunt14.04。编译出来的动态链接库会依赖于glibc2.14以上版本。而centos6默认的glibc是2.12。因此需要重新搭建一个docker的编译环境。重写的Dockerfile如下:
FROM centos:centos6
RUN yum install -y tar git hg rpmdevtools gcc glibc-static device-mapper-devel
RUN rpm -ivh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
RUN yum install -y pandoc golang go-md2man
RUN mkdir -p /go
这个编译环境的唯一缺点是不能够编译btrfs的驱动。btrfs的驱动需要在centos7以上才能编译运行(centos6的btrfs-progs-devel始终找不到)。但是一般centos下是使用dm作为存储驱动,也足够使用了。
编写SPEC文件
自己编译SPEC文件较为繁琐,其实可以直接参考github上的两个项目已经编写的SPEC文件
他们的SPEC中在build时,需要安装golang的若干包,实际这些包都在docker/vendor文件夹中有了,不需要单独安装(安装也可以,可以使用最新的包。但是注意版本一致)。
定制的一键打包centos6下的docker包
至于如何打包centos6下的docker RPM包,主要参考了docker-rpm-el6项目,做了一个自动化的Makefile。
项目开源在 github 上。有兴趣的可以使用,如果有用,帮忙star一下。
具体使用方法就是将整个项目docker-rpm-centos6放置在docker源码的hack文件夹中。
然后cd hack/docker-rpm-centos6。直接运行make就可以了