Docker零基础入门——0.概念篇

本文旨在将docker的基本概念做一个详细说明,暂不涉及具体的安装和操作,那些会在后续的博文中说明。因为之前在这里看过不少关于docker的博客,自己后来也研究使用了一小段时间,决定以自己复习的方式将学习到的和使用到的知识点做一个回顾以及总结,分享给大家,部分内容及图片节选于其他博客,因为都是概念性内容,集多家之长,再稍作举例总结,文末会表明出处,以上。

1.从容器和虚拟机的概念引出Docker

首先我们得区分清楚两个概念
容器虚拟机

我们用的传统虚拟机如 VMware , VisualBox 之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统

而容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。

容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器可以帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。容器还赋予我们对资源更多的精细化控制能力,让我们的基础设施效率更高。通过下面这幅图我们可以很直观的反映出这两者的区别所在。

容器和虚拟机的区别
图左是我们的容器,图右是我们传统的虚拟机,两者第一个共同点就是server(host)也就是我们的宿主机,另外一个共同点是Hypervisor,他是一种运行在基础物理服务器和操作系统之间的中间软件层,可允许多个操作系统和应用共享硬件。因为这两者都是虚拟化技术所以都需要Hypervisor。图再往上走,出现了第一个不同点,也就是上文所说的每台虚拟机都需要有自己的操作系统,而容器是和宿主机共享硬件资源及操作系统,也就是只有一个操作系统就够了,容器都建立在宿主机的操作系统上,第二个不同点就是Docker Engine了,他其实就是docker,我们通过他来控制我们的容器,因为容器是没有独立的操作系统的。

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

而 Linux 容器是 Linux 发展出了另一种虚拟化技术,简单来讲, Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离,相当于是在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker ,就不用担心环境问题。

总体来说, Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

2.Docker相比于传统虚拟机的优缺点

  • docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,启动快速属于秒级别。而虚拟机通常需要几分钟去启动。
  • docker 需要的资源更少, docker 在操作系统级别进行虚拟化, 所以docker直接和内核交互,几乎没有性能损耗,性能优于通过Hypervisor 层与内核层的虚拟化,无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比传统虚拟机技术,同样的硬件环境,往往可以运行更多数量的应用,对系统的利用率非常高。
  • 与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔离。
  • 安全性: docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击。
  • 可管理性: docker 的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如 VMware vCenter提供完备的虚拟机管理能力。
  • 高可用和可恢复性: docker对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制,VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性。
  • 快速创建、删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
  • 交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。 Docker 在 Dockerfile中记录了容器构建过程,可在集群中实现快速分发和快速部署,Docker是build once,run everywhere. 使用Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile 来进行镜像构建,并结合持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(ContinuousDelivery/Deployment) 系统进行自动部署。

我们可以从下面这张表格很清楚地看到容器相比于传统虚拟机的特性和优势所在:
容器相比于传统虚拟机的特性和优势

3.Docker基本概念之镜像:Image

镜像是 Docker 运行容器的基础,可以说没有镜像就没有容器,我们从docker官方的注册中心直接获取到的就是镜像,镜像概念在docker中的地位可见一斑。

那么镜像到底是什么呢?

Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。所以镜像是可以复用的,一个镜像可以创建无数个容器,容器的使用和删除也对镜像也没有影响,可以将镜像理解为一个模板,类似java你写了一个person类,用这个类可以new出无数个对象,对象的修改删除,最后对这个person类都没有影响。

镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,下面的这张图能够帮助读者理解镜像的定义。这图我非常喜欢,隔壁博客顺来的,学完之后越发感觉非常形象。
镜像Image
从左边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker 内部的实现细节,并且能够在主机的文件系统上访问到。统一文件系统 (union file system) 技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式。

我补充一点,为什么会有多个只读层,打个比方, 我今天写了个javaweb代码的bug,是要往数据库插入数据的,测试顶不住跑路了,走之前告诉我,给我提供了一个环境,让我自己去测试,那这个容器环境需要什么呢,首先,最底层是一个数据库mysql,往上一层是我们的java运行环境,再往上一层是tomcat,这么三层可以合成一个镜像,对我们来说就是一个javaweb测试镜像。

由于镜像的概念比较基础,这里再补充一个概念,这个概念也在图中表示出来了,那就是多个只读层的构建方式,分层存储

因为镜像包含操作系统完整的root 文件系统,其体积往往是庞大的,因此在Docker设计时,就充分利用Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

分层存储的特征还使得镜像的复用、定制变的更为容易。可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

4.Docker基本概念之容器:Container

容器是docker运行的基本单位,容器的运行基于一个镜像image。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。

用上边person类的例子来说明,容器就是person类new出来的一个具体实例。并且我们都知道实例中的属性值是可以修改的,已知镜像是只读层,那么容器呢?
容器在docker中的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。如下图,也很形象
容器Container
容器的启动运行可以理解为启动了一个被隔离的进程,进程中是一个小型的虚拟机,启动后容器才会开始动态的瓜分宿主机的磁盘,内存资源。

5.Docker基本概念之仓库:Repository

Docker Repository(仓库)是集中存放镜像文件的场所。镜像构建完成后,可以在你的机器上很便捷的通过命令构建运行出一个容器,但是当你想把你机器上的镜像分享给其他人,或者你想获取其他人构建的镜像,那么docker官网构建了一个世界级的平台托管仓库,就是我们的Docker Hub,你可以从上边拉取或者分享上传你的镜像,这个仓库的概念就是字面的含义,就好像软件包上传下载站,有各种软件的不同版本被上传供用户下载

另外再引出一个概念:
Docker Registry (仓库注册服务器)
Registry注册Repository仓库,这俩单词我第一次还真看错了,,,好像是有一点像。。。吧。。。

Docker Registry是一个集中的存储、分发镜像的服务,一个 Docker Registry 中可以包含多个仓库 (Repository) ,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们以以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签.。

可以这么理解,以docker hub举例,docker hub托管服务,旗下有很多仓库,比方说有tomcat的仓库,有mysql的仓库,当你想把你自己做的tomcat的镜像上传时,就需要先通过Docker Registry 仓库注册服务器注册,当然这一步是隐式的,类似你把货交给了仓库管理员,管理员有一个货物名单,他会在自己的小本本上记载仓库中的货物,上传时还牵扯到一个概念就是镜像标签 (Tag),也就是版本,这个就类似于tomcat:7.5,tomcat:8.0,这种样子,便于管理,这些都确认完就可以入库了。

仓库又可以分为两种形式:

  • public(公有仓库)
  • private(私有仓库)

这两个概念通俗易懂,Docker Registry 公有仓库是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。

除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry的镜像,直接使用此镜像构建容器就可以作为私有 Registry 服务。当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

6.Docker的结构模式

Docker 使用 C/S 结构,即客户端/服务器体系结构。

Docker 守护进程(Daemon)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。如下图右 Docker Daemon
Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟Docker 守护进程交互。如下图左Docker Client
Docker C/S结构
Docker 守护进程一般在宿主主机后台运行,等待接收来自客户端的消息,Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟Docker 守护进程交互。我们之前在Win10的命令行power shell便是最主要的客户端:
Docker 守护进程


Docker 客户端和服务端可以运行在一台机器上,Docker也为我们提供了Remote API来操作Docker的守护进程,意味着我们可以通过自己的程序来控制Docker的运行,也可以通过 RESTful 、 stock 或网络接口与远程 Docker 服务端进行通信:
在这里插入图片描述


至于Docker的客户端与守护进程之间的通信,其连接方式为socket连接。主要有三种socket连接方式:

  • unix:///var/run/docker.sock
  • tcp://host:port
  • fd://socketfd
    socket


    最后总结一下Docker的结构:
    图1 模拟我们自己在机器上安装docker学习的模型

左侧client为我们的docker客户端,可以理解为win10系统的power shell 黑窗口,可以输入命令行,图中间是我们的服务端,我们自己安装docker的话,服务端也是安装在我们自己机器上的,后台守护监听进程deamon来接受客户端请求,请求也分几类,有和外部交互的,比方说想要从注册中心仓库获取镜像,deamon就会解析我们的命令,去仓库获取,也有在内部执行的,比如说镜像获取之后我们使用命令依靠镜像来启动一个容器,这个步骤就是在服务端内部进行的。
Docker结构1
再补充一个
图2 模拟多客户端,多服务端和多注册仓库端的模型
Docker结构2


以上便是我们Docker的基本概念,在后边博文中我们将继续学习,docker的安装和使用。
欲知后事如何,且听下回分解。

因为主要是概念性内容,本文内容部分节选自下边两个博客,也是非常不错的博客,在此推荐。

这可能是最为详细的Docker入门吐血总结

Docker——入门实战

猜你喜欢

转载自blog.csdn.net/cjl836735455/article/details/106227714