最近一些天一直在折腾Docker的使用并且看了一些资料,抛开Docker的一些技术细节不说个人觉得这东西无论对个人开发者还是企业来说都是一个巨大的技术变革,值得个人开发者和企业注意到这个东西。这里随便谈谈个人对Docker的一些设计思路的认识。
传统我们对计算机系统的认知都是应用程序运行在操作系统上,系统的服务和资源对应用程序的运行提供支撑,这是我们最传统的应用程序的运行模式。后来服务器端和客户端的环境越来越复杂,不少应用程序需要系统做各种的配置以适用应用程序的需求,这些针对应用程序的配置可以统称为环境,就是说应用一定要运行在一定的环境中。而以往大量的问题就出现在这个环境问题中,不同的系统版本、不同的底层库和依赖库、不同的硬件、不同的配置文件选项,此类问题过去一直在困扰着开发者和运维人员。不说服务器环境的复杂,就说在客户端的应用,不同的浏览器的兼容问题,IE6不知道消耗了多少开发人员的精力。过往也有不少的技术出来在一定程度上解决此类问题,服务端的技术和客户端的技术都有,个人觉得这种问题在未来很长时间依旧会是个大问题,没有完全解决但是会在一定程度上减轻。
Docker技术的出现在服务器端可以说提供了一个前所未有的方案,可以解决非常多的环境问题而且对于性能的损失代价却非常少。在谈Docker之前先谈一下虚拟机和操作系统,虚拟机的实现方式非常多样但是核心思路就是在宿主操作系统上完全模拟cpu内存等硬件,在此之上完整运行另外一个操作系统,把程序完全运行在虚拟出来的操作系统中,这样虚拟系统的映像包含了应用程序运行所需要的全部环境和依赖,这却实是一个非常好的方案,但是这个方案最大的问题是资源的消耗实在太多了,cpu模拟指令速度不提,其中也有二进制翻译和虚拟化等技术进行加速,但是很多库的运行却要在系统中反复加载到不同的内存中,这种方案在生产环境的浪费基本上不可承受。再谈谈操作系统的最基本原理,操作系统最基本的工作原理就是把硬件等各种资源管理起来,对上层提供一些规范的系统接口。这些接口实际上在不同的系统升级过程中变化很小,这是为了保持应用程序的二进制兼容或是源代码级别的兼容性。我们的应用程序一般都是直接或是间接去调用系统的这一组接口去完成功能。现在思路转变一下,我们的应用程序依赖的东西或是这些接口或是依赖这些接口的一些中间层,实际上把这些东西全部打包在一起,再去调用系统的接口我们的程序肯定是能正常运行的。就是说我们把系统除了实现了系统调用的内核部分的功能全部剥离出去之后打包,让一个宿主系统提供全部这些服务。我们打包后的这个东西本身也会像是一个操作系统一定运行起来而且效率极高,因为这里面没有任何的中间层和模拟层,全部指令全是直接在宿主机器上运行的并且调用宿主的系统调用。
Docker本身的设计就是基于此隔离特性设计的,具体技术细节此处不谈,估计随着Linux与Docker之间的融合加深,Docker的特性还会得到不到的增强,目前Docker还是存在一些普遍的不灵活之处的问题的,不过在未来这些问题都可以解决。Docker官方提供了各种操作手册,在使用Docker融入到自己的开发任务中时本着怎样的思路和工作流呢?个人提供一点建议仅供参考。在使用中我把Docker看做是一个把应用打包的工具而不是把数据打包的工具,一个应用程序的完部功能基本由它本身的功能和输入给它的数据和它输出的数据决定,那么我就把应用除了输入和输出的部分打包起来成为镜像,在使用的时候把输入和输出都通过其它的方式配置进去,比如通过卷、变量、配置文件的方式。这样应用就被独立打包起来,在所在要使用到的地方直接拉取运行就可以了,自己关心的只是配置文件和应用产生的数据之类的问题,这可以解决巨大的维护成本并节约时间。
个人认为以后Docker的设计思想就是把应用打包成为一个无状态的函数,用户只需要关心函数的输入和输出就可以了,有各种服务商只关心提供标准的函数运行环境。这样大家各司其职,极大重塑软件行业的开发和运维模式。