在介绍完Docker的原理后,我们再回过头来看Docker的意义。
Docker的意义
事实上,Cgroups是2007年就被合并到Linux内核的功能。那个时候结合了Cgroups的资源管理能力+Linux Namespace的视图隔离能力的LXC(Linux Container)就已经产生了。
但LXC的视角还是操作系统和服务器,目标是打造一个相比虚拟机更轻量级的系统容器。
而Docker从理念上就截然不同,将目标中心转到了应用。
不要小看这个理念上的差异。以应用为中心意味着两件事情的彻底改变:
构建和部署
测试环境和生产环境的构建和部署都是以应用为粒度的。而一个操作系统上可能部署着不同测试阶段的应用。不可能那么凑巧让上面所有的应用恰好同一周期完毕,然后将整个操作系统从测试搬到生产。这个不符合正常的开发测试流程。
而Docker直接将一个应用运行所需的完整环境,即整个操作系统的文件系统也打包了进去。只要这个应用的Docker镜像测试完成,就可以单独发布上生产。还可以利用现有的构建工具来辅助,例如Jenkins/Ansible等。遇到性能瓶颈需要横向扩展时,也可以针对单应用迅速部署启动。在性能压力消除后也可以快速回收。
在Docker之前,也已经有Cloud Foundry等PaaS项目开始以应用为中心。但相比做完一个镜像就可以随处运行的Docker,它们的便利性和适应性差了不少。
版本化和共享
制作一个操作系统容器是一件私有的事情。你制作的操作系统容器一般只会使用在你自己的团队,顶多扩展到全公司内部。别人看不到你是具体怎么做的系统容器,不清楚你是否在里面埋了雷。借我十个胆子也不敢用。
而Docker在容器镜像的制作上引入了“层(Layer)”的概念。这种基于“层”的实现借鉴了Git的思想,使容器的创建变得透明。每个人都可以审查应用容器在原始操作系统的容器上做了哪些修改。
类似在Github上开源代码,当每个人和每个公司都可以参与到全世界的应用容器分发过程中时,Docker的爆发也在情理之中了。
Docker对于开发人员的意义
曾经我也觉得Docker是运维的事情。对开发来说,吃鸡蛋难道还要管鸡蛋是怎么下的么?但在现在微服务化趋势越来越明显的现在,使用Docker也会带来开发上的很大优势:
之前我们开发和SIT测试环境的基础组件和微服务基本是公用的。这会带来一系列问题:
- A为了某个开发中的特性改动了数据库某个字段,导致其他开发和测试环境直接崩溃
- A始终收不到消息队列中的消息,最后发现是B本地启动的应用把消息给消费掉了
- CI/CD被触发导致X应用自动重新部署,但A开发中的功能依赖于X应用,于是只能等自动部署完毕后才能继续开发
而Docker可以使公用的中间件/数据库/微服务在本地按需启动。每个人独享自己的开发环境,不再受到其他开发人员和测试环境的影响。
此外Docker也进一步降低了生产部署的风险和时间。“我本地运行正常啊”这样的问题出现的概率会降低。也可以将上线的时间进一步压缩(虽然我们现在的一键部署脚本基本也可以一分钟内完成打包发布了),使开发同学能按时回家吃饭。
Docker也大大降低了尝试新技术和新软件的成本。
我现在手头虚拟机资源还算相对充沛,如果想搭个jenkins,gitlab或区块链玩玩,申请几台新的虚机就行。但当初我也饱尝过没有机器可供随便玩的受限感。即使好不容易搞到一台虚机,还要研究个半天怎么安装。安装的时候谨慎再谨慎,就怕不小心装错了搞坏了操作系统,还要陪着笑麻烦运维删掉虚机重装。
而现在大部分技术都提供了镜像,本地一句docker run命令,就可以直接开始体验了。玩坏了删除容器重新来一遍。完全没有任何心理负担。
即使只是对个人接个项目赚赚外快,Docker也带来不少便利。当你本地开发调试完,需要部署到客户本地。选项一是跑到客户现场,或远程到客户内网,手动装一堆环境依赖,可能还会遇到信息安全的限制。选项二是让客户自己运行pull + run两个命令,分分钟部署好。怎么选择毫无悬念。
参考资料
极客时间的这篇专栏非常之推荐,讲得非常通俗易懂循序渐进,绝对值回票价。看到第10章搭建kubeadm的时候可能会卡一下,不过结合实际环境操作演练一下就可以跨过去了。
深入剖析Kubernetes