在前面的学习中,我们掌握了微服务的服务注册与发现(nacos)、配置中心(nacos)、远程服务调用(feign)、网关(gateway),同时借助Idea编译工具多次完成本地服务启动、部署和验证。但是我们假想下面场景:
● 开发人员A写好的代码-->开发人员B的电脑上运行,B必须保证跟A一样的系统环境(JDK/MySQL等)
● 系统代码部署从DEV-->TEST-->PRE-->PROD,每个环节都必须保证一样的系统环境(同上)
● 分布式系统中依赖组件非常多,组件与组件之间的部署往往会产生一些冲突(端口/依赖/环境等)
这样的版本一致保证会耗费我们大量的时间和精力,同时万一有问题产生,我们也很难第一时间考虑到是因为版本不一致导致的问题。因此我们需要一套可以平滑切换的部署引擎,这就是本节我们学习的Docker。
1.认识Docker
1.1 什么是Docker
1-Docker解决依赖兼容
Docker为了解决依赖的兼容问题的,采用了两个手段:
● 【依赖打包】将应用的Libs(函数库)、Deps(依赖)、配置与应用一起打包
● 【部署隔离】将每个应用放到一个隔离容器去运行,避免互相干扰
此时打包好的应用包(不再是原来的jar包)既包含应用本身,也包含应用所需的Libs、Deps,无需在操作系统上安装,自然不存在应用间的兼容问题。
虽然解决了不同应用的兼容问题,但是开发、测试等多个环境,不同的操作系统版本之间也会有差异,这个不解决一样会面临开篇所说的问题,想了解这个必须先了解下操作系统的结构。
2-Docker解决操作系统环境差异
以一个ubuntu操作系统为例,如下:
其结构包括:
- 计算机硬件:如CPU、内存、磁盘等
- 系统内核:所有Linux发行版内核都是Linux,如CentOS/Ubuntu/Fedora等,内核与计算机硬件交互,对外提供内核指令,用于操作计算机硬件。
- 系统应用:操作系统本身提供的应用、函数库。这些函数是对内核指令的封装,使用更方便。
应用与计算机交互的流程大致如下: - 应用(外部应用如redis/web应用等)调用操作系统应用(函数库),实现各种功能
- 系统函数库是对内核指令集的封装,会调用内核指令
- 内核指令操作计算机硬件
如Ubuntu和CenOS虽然都是基于Linux内核,无非是系统应用不同,提供函数库有差异,如下:
但就是这种差异,当一个Ubuntu版本的MySQL尝试安装到CentOS系统时,MySQL还是调用的Ubuntu函数库,会出现找不到或者不匹配的情况,从而导致报错,即出现我们上面提到的系统环境差异导致的不兼容问题:
我们来看下Docker是如何处理这种环境间的差异的:
● Docker将应用程序与所需调用的系统(如Ubuntu)函数库一起打包
● Docker运行到不同操作系统时,直接基于打包的函数库,借助于操作系统Linux内核来运行
3-小结
Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?
● Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
● Docker应用运行在容器中,使用沙箱机制,相互隔离
Docker如何解决开发、测试、生产环境有差异的问题?
● Docker镜像中包含完整运行环境,包括系统函数库,仅依赖系统的Linux内核,因此可以在任意Linux操作系统上运行
Docker是一个快速交付应用、运行应用的技术,具备下列优势:
● 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统
● 运行时利用沙箱机制形成隔离容器,各个应用互不干扰
● 启动、移除都可以通过一行命令完成,方便快捷
1.2 Docker和虚拟机的区别
如果对虚拟机有了解的读者(也可以在一个操作系统中运行另一个操作系统,从而达到保护系统中的应用),那么Docker听起来也是这样的环境隔离,二者有什么区别?为什么现在主流是使用Docker呢?
虚拟机:在操作系统中模拟硬件设备,然后运行另一个操作系统,比如在 Windows 系统里面运行 Ubuntu 系统,这样就可以运行任意的Ubuntu应用了。
Docker:仅是封装函数库,并没有模拟完整的操作系统,即共享同一个底层硬件设备。
相较于传统虚拟机而言,二者主要区别如下:
特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个
总结如下:
● docker是一个系统进程;虚拟机是在操作系统中的操作系统
● docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般