1.摘要

在这篇文章中,我将介绍一下为什么需要虚拟化的环境。

然后我将介绍耳熟能详的虚拟化技术:虚拟机,并大致的介绍一下虚拟机的原理,希望能够让你知道虚拟机的优劣。

在之后,针对虚拟机存在的问题,引出Docker是怎么提高性能的。

最后,我将简单的介绍一下Docker中比较重要的三个概念,镜像、容器、和仓库。

2.介绍

在学习Docker之前,我们需要知道Docker可以干什么,有哪些优点。

直接看看官方文档的介绍:

Developing apps today requires so much more than writing code. Multiple languages, frameworks, architectures, and discontinuous interfaces between tools for each lifecycle stage creates enormous complexity. Docker simplifies and accelerates your workflow, while giving developers the freedom to innovate with their choice of tools, application stacks, and deployment environments for each project.

现在写个项目,装个环境都可能需要很长的一段时间。如果你需要在新的机器上部署项目,尤其是当你需要在很多台机器上部署项目的时候,会显得更加的麻烦。

不仅如此,在装好了环境之后,也有可能因为你和同事之间的某些依赖版本不一致,导致可能会发生”刚刚在我电脑上还能用“的问题。

而使用Docker的话,就不需要担心环境方面的问题了,使用Docker可以构建一个一致的环境,并且可以”一次构建,多次使用“。也就是说,在你配置好一次环境之后,你可以将你构建的这个环境用在各种不同的地方。

Docker是一个虚拟环境容器,可以将你的开发环境、代码、配置文件等一并打包到这个容器中,并发布和应用到任意平台中。在这里你可能会觉得”容器“这个词比较难理解,那么你可以暂时的理解为这是一个虚拟机。

为了实现我们上面说的”一次构建,多次使用“,我们只需要把那些环境都安装在这个虚拟机里面,然后把这个虚拟机拷贝很多份,就能在不同的地方使用了。

3.虚拟机

但是上面那么说其实是不太严谨的,或者说是不对的。

但是我认为在学习一个新的东西之前,如果能够跟一个旧的事物作对比,其实是对我们的学习特别有帮助的。

思考一下Docker与虚拟机有哪些异同。

相同点:

  • 可以启动一个系统镜像
  • 各个”系统“之间是相互隔离的,包括网络,文件等
  • 两者都像是在运行虚拟的操作系统

不同点:

  • Docker的启动更快
  • Docker占用的资源更小
  • 虚拟机可以运行不同平台的操作系统,比如在Windows上可以模拟Android

那么在这里,我想先简单的介绍一下虚拟的的实现方式,但是因为我对这方面没有深入的研究,所以如果有哪些地方说的不对,请不吝指教!

其实虚拟机分为两类,一种是构建于操作系统之上的应用软件,比如VM Workstations,又或者是各种安卓模拟器等;另一种是直接的虚拟机管理系统。

我们主要说说应用软件类型的虚拟机,在早期,这类虚拟机是完全用模拟电路的形式来实现的。因为我们知道计算机硬件的组成,归根结底就是各种门电路,所以在早期虚拟机就通过模拟数字电路,来模拟出一套计算机所需的硬件。然后在这个硬件之上,安装所需要的操作系统。

这样的实现方式很容易理解,但是我们同样也能够推测,这样的实现方式效率很低。

所以在这之后,出现了一种新的虚拟机实现方式,如果虚拟机运行的操作系统,他需要的硬件架构跟宿主机(原来的机器)是一样的,那么也就不需要去模拟这个电路了,可以直接”借用“宿主机的电路来输入输出。这样做的话,虚拟机的效率就变高了。

此外,如果虚拟机需要运行的目标操作系统,所需要的指令集跟宿主机是不一致的,比如宿主机上安装了一个Windows,这是x86架构的,而如果我想要运行Android,这是Arm架构的,那么就没办法借用宿主机上的硬件进行输入输出了,所以就需要一个模拟器,也就是我们说的”安卓模拟器“。

介绍完这些,你大概知道了虚拟机的实现方式了,但是就算是同种架构,一样的指令集,可以借用宿主机的硬件,这样虚拟化出来的操作系统还是会显得比较慢。你想,安装一个Windows,就要十几G的硬盘空间了,就算什么都不干,也要占用两三G的内存,这些资源加起来,一台机器,最多模拟几台虚拟机。为了实现环境的隔离,在资源占用上消耗了这么多,实在是不值得。

4.Docker

所以,就有了Docker。

Docker解决了为了分割环境需要很大资源代价的这个问题。

你想,我们最开始的需求只是希望能有个独立的环境,在这个环境里面有独立的文件系统、网络系统、进程系统等等。所以其实我们不需要耗费这么大的功夫去模拟一个操作系统出来,我们只需要想办法限制每个进程能够访问的资源,分配好这些资源,让进程”以为“自己运行在一个独立的操作系统中,就可以了。我们所有的进程都是基于当前的操作系统,无论是启动,还是运行,速度都会很快。并且,也没有额外运行一个或多个操作系统的资源损耗。

所以,为了区别于硬件层面的虚拟机,就有了操作系统层虚拟化这种技术,也称为:容器。

然后我想再介绍一下Docker中很重要的两个概念:镜像容器

镜像就是模板,你可以理解为我们把环境配置好后,保存起来作为构建容器的模板,有点像面相对象中”类“的概念。

容器是Docker运行的实体,你可以理解为一个个”虚拟的操作系统“,这个容器是根据镜像构建出来的,比如你构建了一个包含了jdk,mysql,redis的镜像,那么只要根据这个镜像,你可以创建出很多个一模一样的容器。这里有点像面相对象中”对象“的概念。

然后我还想介绍一下仓库这个概念,你可以理解为,仓库里面存储了很多的镜像。为什么需要这么做呢,我认为一个是为了方便,另一个是为了复用。方便,是因为我们之前提到了”一次构建,多次使用“这个概念。我们只需要把配置好的环境打包成一个镜像,那么只需要把这个镜像拷贝出来,就可以在任何地方进行构建了。那么仓库就是像GitHub一样,我们可以把打包好的镜像push上去,在需要的机器上再pull下来,减少了运输成本。

另外一点,复用,是因为在很多时候,大家都是需要构建一样的环境了,比如某个版本的Redis,某个版本的MySQL,某个版本的JDK等等,那么有了仓库的话,我们就不需要再构建一次了,只需要使用别人构建过的就可以了。

如果我们把容器理解为运行在当前操作系统中的进程的话,只不过这个进程能够访问的资源是有限的,会让这个进程误以为”自己运行在了独立的操作系统中“,那么我们就能够理解这句话了:

Docker容器没有自己的Kernel,他使用的Kernel版本,跟镜像无关,宿主机有关。

这个问题其实蛮有趣的,原文在这里

但是当初我还有个问题,我们在Docker的仓库中,有看到CentOS的镜像,也有看到Ubuntu的镜像。但是我们上面又说,容器用的是宿主机上的Kernel版本,而不是镜像的。那如果我在CentOS上运行了一个Ubuntu的镜像,该怎么解释呢?

原因是这样的,我们说的内核(Kernel),指的是Linux的核心,比如他的内存管理,文件管理等等,但是说的Ubuntu、CentOS这些,指的是Linux的发行版,这些发行版,都是基于Linux制作的,只不过在不同的发行版中,添加了不同的工具。比如在CentOS中,用的是yum包管理工具,在Ubuntu中,用的是apt包管理工具。

所以,他们的内核,其实还是Linux的内核。

写在最后

嗨,好久不见。

谢谢你能看到这里!

这篇文章主要是起到一个入门的作用,希望能够让你对Docker有一个初步的认识。

当然了,因为作者学识有限,在这篇文章中很多地方的讲解都是不到位的,如果有哪里讲得不到位,讲得不对,希望你能不吝指教,谢谢你!

在后面的文章中,我会给你介绍一下namespace这个概念,让你大概的知道容器到底是怎么实现的。

但是关于Docker的那些操作,不一定会写一篇文章。因为我觉得这方面优秀的文章已经很多了,官方文档也很详细。

《Docker入门》系列的文章目前的规划是大概会有两到三篇,定位是偏向于了解Docker及一点点的原理,实用性应该不会特别强。

再次感谢你能看到这里!

PS:如果有其他的问题,也可以在公众号找到我,欢迎来找我玩~

版权声明:本文为hongjijun原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/hongjijun/p/13201337.html