在工作中,我们掌握了微服务的服务注册与发现(nacos)、配置中心(nacos)、远程服务调用(feign)、网关(gateway),同时借助Idea编译工具多次完成本地服务启动、部署和验证。但是我们假想下面场景:
- 开发人员A写好的代码-->开发人员小王的电脑上运行,小周必须保证跟小王一样的系统环境(JDK/MySQL等)
- 系统代码部署从DEV-->TEST-->PRE-->PROD,每个环节都必须保证一样的系统环境(同上)
- 分布式系统中依赖组件非常多,组件与组件之间的部署往往会产生一些冲突(端口/依赖/环境等)
保证版本一致会耗费我们大量的时间和精力,同时万一有问题产生,我们也很难第一时间考虑到是因为版本不一致导致的问题。因此我们需要一套可以平滑切换的部署引擎,这就是本节我们学习的Docker。
1.什么是Docker
Docker 是一个开源的容器化平台,用于打包、分发和运行应用程序。它基于 Linux 容器(LXC)技术,并提供了简单且易用的工具和接口,使得开发人员可以轻松地创建和管理容器。
在 Docker 中,应用程序及其所有依赖项被组织为一个独立的容器。容器是基于镜像创建的运行实例,它具有独立的文件系统、进程空间和网络接口。每个容器都可以在任何支持 Docker 的环境中运行,包括开发机、测试环境和生产服务器。可以解决一下问题:
- 解决依赖兼容问题
- 解决操作系统差异问题
1.1. 解决依赖兼容问题
思考:Docker是如何解决依赖兼容问题?
主要通过一下两种方式解决:
- 将应用的Libs(函数库),Deps(依赖)、配置和应用打包在一起
- 将每一个应用运行在相互隔离的容器中运行,避免相互干扰。 打包方式如下图:
- 使用上面方式进行打包好的应用(java应用程序就不再是原来的jar包),里面不仅包含了应用本身,还包含了应用所需要的Libs、Deps,这样就不再需要在操作系统上安装Libs和Deps,那么自然就不存在应用兼容问题。
思考:上面说的解决了应用的冲突问题,但是我们的开发、测试和正式环境还是会存在差异(也就是操作系统可能会存在差异,那么我们如何解决)?
1.2. 解决操作系统环境差异
要解决这个问题,我们就需要先了解操作系统结构,结构如下:
- 硬件: CPU、内存、磁盘等
- 操作系统内核: 所有的Linux发行版内核都是Linux,但是发行版是基于Linux内核版进行扩展的,由各个Linux厂商开发、维护,例如有CentOS、Ubuntu、Fedora等,Linux内核的作用可以理解为是和计算机硬件进行交互。
- 系统应用: 操作系统自身提供的应用和函数库。这些函数库是对内核指令的封装(不同版本的操作系统函数库不太一样),方便开发人员使用。
- 应用程序: 就是我们开发好的那些程序,例如:电商应用、Mysql、Nginx等等
linux从入门到精通介绍过,忘记的小伙伴可以自行查看一下。
通过上面操作系统的介绍,我们已经知道Ubuntu和CentOS都是基于Linux内核,但是系统应用不同,提供的函数库有差异,如果将Mysql(Ubuntu版本)应用安装到CentOS上,那么他要调用的是Ubuntu函数库时,就会报错,原因就是匹配不到对应的函数库。
思考:Docker如何解决不同操作系统环境问题?
Docker解决不同系统环境的问题
- 1.Docker将用户程序与所需要调用的系统(比如Ubuntu)函数库一起打包
- 2.Docker运行到不同操作系统时,直接基于打包的库函数,借助于操作系统的Linux内核来运行
细心的小伙伴可能已经发现了,Docker和虚拟机很相似,那么Docker和虚拟机有什么区别?
2. Docker和虚拟机区别
想要了解两者之间的区别,我们还需要看一下他们的具体定义:
- 虚拟机(Virtual Machine):是可以在一台电脑上通过软件的方式模拟出来若干台计算机,可以实现一台电脑“同时”运行几个操作系统,相互独立进行工作。同时,这几个操作系统之间还可以进行互联,形成一个虚拟网络。比如:可以在Windows系统上运行CentOS系统/
- Docker: 是一个开源的应用容器引擎,他仅仅封装Libs(函数库),没有模拟完整的操作系统,共享同一个底层硬件设备。 相较于传统虚拟机而言,二者主要区别如下:
特性 | Docker | 虚拟机 |
性能 | 接近原生 | 性能较差 |
硬盘占用 | 一般为 MB | 一般为GB |
启动 | 秒级 | 分钟级 |
3. Docker架构
3.1. Docker核心概念
镜像
- 镜像(Image):镜像是一个只读模板,包含了运行应用程序所需的所有文件系统、依赖库、应用程序代码等内容。除此之外镜像还包含配置参数(环境变量、用户等),但是不包含任何的动态数据,镜像构建后不会改变,可以类比为Java中的类
Docker 镜像采用分层构建的方式来实现高效的镜像管理和存储。镜像分层构建通过将一个完整的镜像拆分为多个只读的文件系统层(Layer),每个层都包含了特定的文件和目录变更。
以下是镜像分层构建的主要原理和优势:
- 原理:每个镜像层都是一个只读的文件系统,可以包含文件、目录、依赖库、运行时环境等。 每个层都包含了与前一层的差异,这种差异是通过文件系统的快照和增量存储来实现的。 当多个镜像共享相同的层时,这些层可以在磁盘上进行共享,节省存储空间每个层都包含了与前一层的差异,这种差异是通过文件系统的快照和增量存储来实现的。 容器在运行时会在所有层之上创建一个可写层,用于保存容器运行时的变更和数据。
- 优势:
- 高效的存储管理:由于层的共享,镜像只需要存储不同的层和差异,更加节省存储空间。
- 快速的镜像构建和传输:当构建镜像时,只需构建变化的层,而不是完整的镜像,加速了构建过程。同时,镜像的传输也更快,因为只需要传输变化的层。
- 灵活的镜像定制:通过添加、删除或修改特定层,可以定制和修改现有的镜像,而不必重新构建整个镜像。
- 更好的缓存和复用:Docker 引擎可以缓存每个层,并在构建时进行重复使用。当多个镜像共享相同的层时,这些层可以被多次复用,从而提高了构建和部署的效率。 通过镜像分层构建,Docker 提供了一种高效、可靠且可定制的方式来管理和交付应用程序。开发人员可以利用已有的层和镜像,减少构建时间和存储空间,同时也使得镜像的更新和维护更加方便。
容器(Container)
- 容器(Container):容器是基于镜像创建的运行实例,它具有独立的文件系统、进程空间和网络接口。容器可以被快速启动、停止、删除和复制。
容器和镜像的联系和区别:
镜像,就是把一个应用在硬盘上的文件、及其运行环境、部分系统函数库文件一起打包形成的文件包。这个文件包是只读的。容器,就是将这些文件中编写的程序、函数加载到内存中允许,形成进程,只不过要隔离起来。因此一个镜像可以启动多次,形成多个容器进程。
仓库(Registry)
仓库是用来存储和共享镜像的地方。
镜像构建完成后,可以很容易在当前宿主机运行,但是想要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样一个服务。 一个Docker Registry可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常一个仓库会包含一个软件的不同版本镜像,标签用于区分版本,如不给出标签,默认latest作为标签。 Docker Registry公开服务 开发给用户使用、允许用户管理镜像的Registry服务,可避免重复劳动,如Redis/Nginx等
- 官方的Docker镜像的托管平台:Docker Hub。
- 国内代理的DcokerHub公开服务:网易云镜像服务、DaoCloud 镜像市场、阿里云镜像库 等。
Docker Registry私有服务
公司内部使用、迭代的镜像Registry服务,需要用户自己完成代码打包、镜像上传。
总结:
通过本文的介绍,相信小伙伴已经对Docker有了更深入的了解,并且意识到它在现代软件开发和部署中的重要性和广泛应用。作为一种轻量级的容器化平台,Docker可以帮助开发人员简化环境配置、提高部署效率和资源利用率,并促进团队协作和持续交付。在未来的软件开发过程中,不妨尝试使用Docker来优化您的工作流程,提升开发体验和项目质量。
标签:容器,操作系统,探索,构建,镜像,Docker,函数库 From: https://blog.51cto.com/maguobin/7960455