追求极简:追求极简:Docker镜像构建演化史镜像构建演化史
自从2013年dotCloud公司(现已改名为Docker Inc)发布Docker容器技术以来,到目前为止已经有四年多的时间了。这期间
Docker技术飞速发展,并催生出一个生机勃勃的、以轻量级容器技术为基础的庞大的容器平台生态圈。作为Docker三大核心
技术之一的镜像技术在Docker的快速发展之路上可谓功不可没:镜像让容器真正插上了翅膀,实现了容器自身的重用和标准
化传播,使得开发、交付、运维流水线上的各个角色真正围绕同一交付物,“test what you write, ship what you test”成为现
实。
对于已经接纳和使用Docker技术在日常开发工作中的开发者而言,构建Docker镜像已经是家常便饭。但如何更高效地构建以
及构建出Size更小的镜像却是很多Docker技术初学者心中常见的疑问,甚至是一些老手都未曾细致考量过的问题。本文将从
一个Docker用户角度来阐述Docker镜像构建的演化史,希望能起到一定的解惑作用。
1.镜像:继承中的创新镜像:继承中的创新
谈镜像构建之前,我们先来简要说一下镜像。
Docker技术从本质上说并不是一种新技术,而是将已有技术进行了更好地整合和包装。内核容器技术以一种完整形态最早出
现在Sun公司的Solaris操作系统上,Solaris是当时最先进的服务器操作系统。2005年Sun发布了Solaris Container技术,从此
开启了内核容器之门。
2008年,以Google公司开发人员为主导实现的Linux Container(即LXC)功能在被merge到Linux内核中。LXC是一种内核级虚
拟化技术,主要基于Namespaces和Cgroups技术,实现共享一个操作系统内核前提下的进程资源隔离,为进程提供独立的虚
拟执行环境,这样的一个虚拟的执行环境就是一个容器。本质上说,LXC容器与现在的Docker所提供容器是一样的。Docker
也是基于Namespaces和Cgroups技术之上实现的。但Docker的创新之处在于其基于Union File System技术定义了一套容器打
包规范,真正将容器中的应用及其运行的所有依赖都封装到一种特定格式的文件中去,而这种文件就被称为镜像(即
image),原理见下图(引自Docker官网):
图1:Docker镜像原理
镜像是容器的“序列化”标准,这一创新为容器的存储、重用和传输奠定了基础,并且容器镜像“坐上了巨轮”传播到世界每一个
角落,助力了容器技术的飞速发展。
与Solaris Container、LXC等早期内核容器技术不同,Docker还为开发者提供了开发者体验良好的工具集,这其中就包括了用
于镜像构建的Dockerfile以及一种用于编写Dockerfil的领域特定语言。采用Dockerfile方式构建成为镜像构建的标准方法,其可
重复、可自动化、可维护以及分层精确控制等特点是采用传统采用docker commit命令提交的镜像所不能比拟的。
2.“镜像是个筐镜像是个筐”:初学者的认知:初学者的认知
“镜像是个筐,什么都往里面装”- 这句俏皮话可能是大部分Docker初学者对镜像最初认知的真实写照。这里我们用一个例子来
生动地展示一下。?
我们现在将httpserver.go这个源文件编译为httpd程序并通过镜像发布。源文件的内容如下:
接下来,我们来编写用于构建目标镜像的Dockerfile: