文章目录
一、项目部署的问题
-
分布式系统中,依赖的组件非常多,依赖关系复杂,容易出现兼容性问题。
-
在数百上千台服务中重复部署,开发、测试、生产环境有差异,会遇到各种问题
大型项目组件较多,特别是微服务项目,各种各样的微服务,而且这些微服务还会依赖于各种各样的应用,例如前端肯定依赖于NodeJS,而我们的服务端还需要数据库MySQL、缓存系统Redis、异步通信MQ等,所有的这些应用将来都需要部署到服务器上,而大多数的服务器都会采用Linux操作系统,应用在安装到Linux操作系统前要做一些准备,因为这些应用都会有自己需要的依赖和函数库。不同组件之间部署时依赖和函数库往往会产生一些冲突,有可能同一个依赖,但是版本不同,如此复杂的依赖关系很容易就产生兼容。
而且你费了老半天劲终于把这些问题全部解决了,你会发现这只是一个开始,你搞定了开发环境,还有生产环境、预发布环境等等在等着你,最可怕的是,这些环境的Linux操作系统还有可能不同,这个环境下能使用的配置换到另外一个操作系统中可能就无法使用了。

所以在以前开发效率非常的低。
二、Docker解决依赖兼容问题
而Docker确巧妙的解决了这些问题,Docker是如何实现的呢?
既然我们刚才说了,每一个应用都有自己所需要的依赖、函数库,那为什么我们不把这些依赖和函数库一起打包呢?
Docker为了解决依赖的兼容问题的,采用了两个手段:
- 将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包,形成可移植镜像
- 将每个应用放到一个隔离容器去运行,使用沙箱机制,相互隔离

这样打包好的应用包中,既包含应用本身,也保护应用所需要的Libs、Deps,无需再操作系统上安装这些,自然就不存在不同应用之间的兼容问题了。
但是这样的解决方案是限于一种操作系统,比如说你打包,肯定会基于某种操作系统去打包,例如Ubuntu版本的操作系统,那它的依赖和函数库肯定也是Ubuntu版本的,如果把这个打包好的程序扔到CentOS上,肯定不能运行。并且开发、测试等环境会存在差异,操作系统版本也会有差异,怎么解决这些问题呢?
三、Docker解决操作系统环境差异
要解决不同操作系统环境差异问题,必须先了解操作系统结构。以一个Ubuntu操作系统为例,结构如下。
其实所有的Linux操作系统都可以分成两层,一层是大家共享的内核,不管是Ubuntu还是CentOS,它们的内核都是Linux,而区别是上层的系统应用不同。
-
计算机硬件:例如CPU、内存、磁盘等
-
系统内核:所有Linux发行版的内核都是Linux,例如CentOS、Ubuntu、Fedora等。内核可以与计算机硬件交互,对外提供内核指令,用于操作计算机硬件。
例如:调用CPU、读内存…而内核会把这些事情变成一个个指令,你调用这些指定,就可以操作计算机电脑硬件了,可惜的是,这些指令大多数比较简陋,如果要基于这些指令去开发应用,那可太麻烦了。所以说我们就有了系统应用。
-
系统应用:操作系统本身提供的应用、函数库。这些函数库是对内核指令的封装,形成函数,许多的函数变成了函数库,程序员使用这些函数库开发。
应用于计算机交互的流程如下:
1)应用调用操作系统应用(函数库)
2)系统函数库调用内核指令
3)内核指令调用计算机硬件
从而实现所需要的功能。
四、Ubuntu系统上的应用为什么不能在CentOS上执行?
Ubuntu和CentOSpringBoot都是基于Linux内核,无非是系统应用不同,即提供的函数库有差异:
此时,如果将一个Ubuntu版本的MySQL应用安装到CentOS系统,MySQL在调用Ubuntu函数库时,会发现找不到或者不匹配,就会报错了,这就是我们应用不能跨系统运行的原因。
针对这样的问题,Docker如何解决不同系统环境的问题?
五、Docker如何解决不同系统环境的问题?
- 既然每个应用都依赖于系统函数库,Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包
- Docker运行到不同操作系统时,直接基于打包的函数库,借助于操作系统的Linux内核来运行
- 整体流程:应用调用操作系统应用(函数库),系统函数库调用内核指令,内核指令调用计算机硬件,就不需要去管系统是什么了,因为它自己就有。
由此可见,Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,而不是上面的不同的系统应用。因此可以在任意Linux操作系统上运行,这样就实现了跨系统的问题。
如图:
六、总结:Docker是什么?
Docker是一个快速交付应用、运行应用的技术,具备下列优势:
- 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统
- 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
- 启动、移除都可以通过一行命令完成,方便快捷