作者:vitovzhong,腾讯 TEG 应用开发工程师
容器的实质是进程,与宿主机上的其他进程是共用一个内核,但与直接在宿主机执行的进程不同,容器进程运行在属于自己的独立的命名空间。命名空间隔离了进程间的资源,使得 a,b 进程可以看到 S 资源,而 c 进程看不到。
1. 演进
对于统一开发、测试、生产环境的渴望,要远远早于 docker 的出现。我们先来了解一下在 docker 之前出现过哪些解决方案。
1.1 vagrant
Vagarant 是笔者最早接触到的一个解决环境配置不统一的技术方案。它使用 Ruby 语言编写,由 HashCorp 公司在 2010 年 1 月发布。Vagrant 的底层是虚拟机,最开始选用的是 virtualbox。一个个已经配置好的虚拟机被称作 box。用户可自由在虚拟机内部的安装依赖库和软件服务,并将 box 发布。通过简单的命令,就能够拉取 box,将环境搭建起来。
// 拉取一个ubuntu12.04的box
$ vagrant init hashicorp/precise32
// 运行该虚拟机
$ vagrant up
// 查看当前本地都有哪些box
$ vagrant box list
如果需要运行多个服务,也可以通过编写 vagrantfile,将相互依赖的服务一起运行,颇有如今 docker-compose 的味道。
config.vm.define("web") do |web|web.vm.box = "apache"
end
config.vm.define("db") do |db|db.vm.box = "mysql”
end

1.2 LXC (LinuX Container)

在 2008 年,Linux 2.6.24 将 cgroups 特性合入了主干。Linux Container 是 Canonical 公司基于 namespace 和 cgroups 等技术,瞄准容器世界而开发的一个项目,目标就是要创造出运行在 Linux 系统中,并且隔离性良好的容器环境。当然它最早也就见于 Ubuntu 操作系统上。
2013 年,在 PyCon 大会上 Docker 正式面世。当时的 Docker 是在 Ubuntu 12.04 上开发实现的,只是基于 LXC 之上的一个工具,屏蔽掉了 LXC 的使用细节(类似于 vagrant 屏蔽了底层虚拟机),让用户可以一句 docker run 命令行便创建出自己的容器环境。
2. 技术发展
容器技术是操作系统层面的虚拟化技术,可以概括为使用 Linux 内核的 cgroup,namespace 等技术,对进程进行的封装隔离。早在 Docker 之前,Linux 就已经提供了今天的 Docker 所使用的那些基础技术。Docker 一夜之间火爆全球,但技术上的积累并不是瞬间完成的。我们摘取其中几个关键技术节点进行介绍。

2.1 Chroot
软件主要分为系统软件和应用软件,而容器中运行的程序并非系统软件。容器中的进程实质上是运行在宿主机上,与宿主机上的其他进程共用一个内核。而每个应用软件运行都需要有必要的环境,包括一些 lib 库依赖之类的。所以,为了避免不同应用程序的 lib 库依赖冲突,很自然地我们会想是否可以把他们进行隔离,让他们看到的库是不一样的。基于这个朴素的想法,1979 年, chroot 系统调用首次问世。来举个例子感受一下。在 devcloud 上申请的云主机,现在我的 home 目录下准备好了一个 alpine 系统的 rootfs,如下:

在该目录下执行:
chroot rootfs/ /bin/bash
然后将/etc/os-release 打印出来,就看到是”Alpine Linux”