随着云原生时代的来临,云以及分布式计算已经是时下最受欢迎的技术之一了。其中 Docker 作为最知名的容器平台,到底有着怎样的魅力来让其无人不知无人不晓?废话不多说,让我们开始逐层掀开容器技术的神秘面纱吧!
Docker从传统 IT 到 IaaS 到 PaaS 的能力变迁
让时间回到 2013 年,在该时候,虚拟机和云服务已经很流行了。主流用户的常见做法,就是在云平台(比如腾讯云、AWS、OpenStack 等),像管理物理服务器一样用脚本来做管理和部署应用。
这样的做法一直存在本地环境和线上环境不一致导致部署出现问题的风险,所以各家云平台的思路都是去模拟出更加接近本地服务器的环境,来给用户提供更好的上云体验。所以开源的 PaaS 项目提供“应用托管”的能力,就是解决该问题的一个最佳方案。
在众多开源 PaaS 项目中,最热门的 Cloud Foundry 基本上已经吸引了所有云厂商的目光,开启了以开源 PaaS 为核心构建平台层服务能力的变革。
大家可能并不是很熟悉 Cloud Foundry,简单地说,Cloud Foundry 所做的就是提供一个 "cf push" 命令行工具,让大家能够对一些主流语言的代码进行打包上传和分发。然后 Cloud Foundry 通过调用操作系统的 CGroups 和 Linux Namespace,单独为每一个应用创建一个隔离的沙盒环境,然后在其中启动这些应用的进程。
Cloud Foundry 的最核心命令 cf push 的业务流程图
所以当时 Cloud Foundry 最核心的能力,就是提供隔离的运行环境,也就是“容器”了。
当时的 PaaS 风潮参与者,dotCloud 是最不起眼的公司之一
同期,有一家名叫 dotCloud 的公司,因为它的主打产品跟 Cloud Foundry 社区是脱节的,所以长期以来都无人问津。终于,dotCloud 公司决定开源自己的容器项目 Docker。
但很可惜在当时并没有人关注 dotCloud 的该决定,因为“容器”该概念从来就不是什么新鲜的东西,也不是 Docker 公司发明的。哪怕是在当时最热门的 PaaS 项目 Cloud Foundry 里,容器也只是其最底层,最没人关注的那一部分。
而 Docker 项目,实际上和 Cloud Foundry 的容器并没有太大的不同,所以在 Docker 发布后不久,Cloud Foundry 的首席产品经理 James Bayer 就在社区里做了一次详细对比,告诉用户 Docker 实际上只是一个同样使用 Cgroups 和 Namespace 实现的“沙盒”而已,没有什么特别的黑科技,也不需要特别关注。
然而,几个月后,James Bayer 就被打脸了。Docker 只用了短短几个月,就让所有 PaaS 社区都出局了。事实上,Docker 项目确实和 Cloud Foundry 的容器在大部分功能和实现原理上并没有什么区别,但仅有的一个不一样的功能,成了 Docker 项目的制胜关键。
该功能就是 Docker 镜像。
当时主流的 PaaS 项目,如 Cloud Foundry,都通过提供一套应用打包功能,帮助用户大规模部署到集群。但就是该打包功能,需要用户为每个应用做大量的配置工作和调试工作,才能让本地能供正确运行的应用,在集群里也能正确运行。
而 Docker 镜像,恰好解决了该根本性的问题。Docker 镜像的本质,就是一个压缩包,但和 PaaS 的应用打包相比,该压缩包里则是多了完整的运行环境依赖内容,比如操作系统的所有文件和目录。只要用户拿着该压缩包,便可以通过某些技术手段在任何地方创建一个沙盒来运行用户的应用了,因为其做到了本地环境和云端环境高度的一致,再加上 Docker 充满趣味性的推广,比如 “1 分钟部署一个 WordPress 网站”、“3 分钟部署一个 Nginx 集群”等,最终通过与开发者的亲密关系,加上解决了打包的根本性难题,从而一举登天。
Linux Namespace,Linux Cgroups ,rootfs我们前面已经介绍了 Docker 的发展,那么,回归到技术本身,容器到底是什么呢?这里可以先下一个定义:
一个“容器”,实际上是一个由 Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。
Linux Namespace 和 Linux Cgroups,提供了运行时的隔离和资源的授予。
rootfs,也就是镜像,提供了容器的运行内容。
比如对于如下 Dockerfile:
# 使用官方提供的 Python 开发镜像作为基础镜像 FROM python:3.8-slim-buster # 将工作目录切换为 /app WORKDIR /app # 拷贝应用依赖描述文件到工作目录 COPY requirements.txt requirements.txt # 使用 pip 命令安装应用以及其所需的依赖 RUN pip3 install -r requirements.txt # 拷贝应用文件到工作目录 COPY . . # 设置容器进程为 "python3 app.py",也是该 Python 应用的启动命令 CMD [ "python3", "app.py"]