自己构建Docker镜像的一些基本思考

  • 我们在自己创建Docker镜像的时候,经常在Dockerfile中添加以下语句:其中,FROM是指明我们自己的镜像是从一个什么样的镜像继承而来。我们可以在一个镜像的基础上,增加自己的程序、修改运行环境,运行自己定义的命令。
  • ubuntu:15.04表明这是使用了ubuntu:15.04的一个linux发行版本的基础镜像。
 FROM ubuntu:15.04

 RUN echo "Hello world" > /tmp/newfile

 

  • 我们从上面的例子可以看到,当需要自己构建一个镜像时,首先就需要去下载一个Minimal的操作系统镜像,这个操作系统镜像的文件系统中存放了我们需要的一些Linux下的管理工具,包括sh、ls、cp、mv、tar等以及应用程序运行依赖的一些包,我们自己的程序就可以在这个操作系统镜像的文件系统之上再一次封装,打包。

 

  • 当然除了从仓库下载操作系统镜像之外,我们也可以自己构建操作系统镜像。在Docker的世界中,存在一个scratch的空的基础镜像,它连最基本的文件系统都没有提供,ubuntu:15.04这样的linux发行版本镜像就是是基于scratch基础镜像构建而来的,以下就是一个ubuntu发行版镜像的典型的Dockerfile。它是以scratch空镜像为基础,添加了ubuntu-xenial-core-cloudimg-amd64-root.tar.gz这个文件系统构建而来。ADD命令会自动将tar包解压到docker镜像下。
FROM scratch
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /

# a few minor docker-specific tweaks
# see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap
RUN set -xe \
	\
# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L40-L48
	&& echo '#!/bin/sh' > /usr/sbin/policy-rc.d \
	&& echo 'exit 101' >> /usr/sbin/policy-rc.d \
	&& chmod +x /usr/sbin/policy-rc.d \
	\
# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L54-L56
	&& dpkg-divert --local --rename --add /sbin/initctl \
	&& cp -a /usr/sbin/policy-rc.d /sbin/initctl \
	&& sed -i 's/^exit.*/exit 0/' /sbin/initctl \
	\
# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L71-L78
	&& echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \
	\
# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L85-L105
	&& echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \
	&& echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \
	&& echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \
	\
# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L109-L115
	&& echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \
	\
# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L118-L130
	&& echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \
	\
# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L134-L151
	&& echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests

# delete all the apt list files since they're big and get stale quickly
RUN rm -rf /var/lib/apt/lists/*
# this forces "apt-get update" in dependent images, which is also good

# enable the universe
RUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list

# make systemd-detect-virt return "docker"
# See: https://github.com/systemd/systemd/blob/aa0c34279ee40bce2f9681b496922dedbadfca19/src/basic/virt.c#L434
RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container

# overwrite this with 'CMD []' in a dependent Dockerfile
CMD ["/bin/bash"]

 

我们当然也可以直接使用scratch空镜像来构建自己的镜像,例如,我们自己编译来一个可执行的c程序,hello,跟Dockerfile一起放在一个空目录下,执行docker build -t hello:v1,但是这样的一个镜像,没有最基本的Linux下的管理工具,包括sh、ls、cp、mv、tar等以及应用程序运行依赖的一些包,也就是说这样的一个镜像,对我们来说,没有多大的实用价值。

FROM scratch
ADD hello /
CMD ["/hello"]

更实用的方法,仍然是利用某个linux发行版本镜像作为我们的基础镜像,然后再在其上,添加我们自己的程序、运行环境。

 


Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是上文说到的UnionFS。在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。Docker在bootfs之上的一层是rootfs(根文件系统)。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

bootfs来自于宿主机,所有的docker镜像都会共用此部分,也就是共用内核。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值