技术点滴 · 2024年3月30日 0

Docker 架构简介

自从搭建好了自己的 NAS 系统,为了充分利用 N6005 的能力,开始尝试使用各种不同的 docker 映像来扩展 NAS 的功能。原本我对 docker 还存在一定的怀疑态度,担心在性能,兼容性等方面可能存在问题。自从开始使用以后,发现 docker 真的是很香,现在我的 NAS 上已经运行了超过20个 docker container,从媒体服务器,到个人网站,甚至标准的 Ubuntu 运行环境,都部署在 docker 上,体验各种不同的新功能的同时,不会对宿主机的环境造成大的影响。接下来的一系列文章中,我将介绍一下 docker 的基本知识,分享我尝试过的一些有趣的 docker 映像,希望也能帮助到有需要的同学。

Docker 容器与虚拟机

让我们首先对容器和虚拟机进行比较。

虚拟机与容器

Docker容器 (Container)

容器本质上是可移植且完全打包的计算环境,在与主机系统完全隔离的情况下运行。容器将运行应用程序所需的所有内容打包在一起,包括独立软件单元中的代码、系统库、依赖项和配置设置。

由于容器捆绑了应用程序平稳运行所需的所有基本组件,因此软件应用程序可以在任何计算平台上移动和运行,而不会出现不一致或错误。这种标准化是 Docker 的最大优势之一。

与虚拟机不同,容器不会虚拟化硬件资源。相反,它们运行在抽象资源的容器运行时平台之上。在 Docker 中,事实上的容器运行时平台是 Docker Engine。

容器比虚拟机更轻且更快。如此迅速的原因在于容器共享主机的操作系统内核,从而无需为每个容器使用单独的操作系统。

虚拟机

虚拟化技术使用虚拟机管理程序,这是一种创建虚拟化或抽象层的应用程序,可模拟可用的硬件资源,包括 RAM、CPU、USB 端口、NICS 等。这使得来宾或虚拟机可以使用它们。

虚拟机是隔离并独立于主机系统运行的虚拟化操作系统实例。它们模拟主机的硬件组件,例如 CPU、RAM、网络接口和存储等等。

由于虚拟机使用与主机相同的资源,因此这可能会导致高资源开销,从而影响性能。

虚拟机比容器大得多,因为它们包含操作系统并且通常以千兆字节为单位。这也可以追溯到高资源利用率。容器要小得多,占用的存储空间低至几兆字节。

容器的好处

容器和虚拟机都提供了与主机系统的一定程度的隔离,这两种技术很容易混淆。然而,差异归结为:

虚拟化是关于抽象主机系统上的硬件资源,而容器化是关于抽象操作系统内核并在隔离单元内运行具有所有基本组件的应用程序。

也就是说,容器化是构建和部署应用程序时的首选解决方案,原因如下:

可移植性——容器体积小、重量轻,可以轻松无缝地部署在任何平台上。

简单部署– 由于容器包含应用程序运行所需的所有内容,因此部署它们变得很容易,因为软件将在任何计算环境上以相同的方式运行。

速度– 与通常需要几分钟启动的虚拟机相比,容器通常需要几秒钟才能启动。虽然启动时间可能会根据应用程序的大小而有所不同,但容器的启动时间只占虚拟机启动时间的一小部分。

资源优化——由于容器内存占用较小,并且不抽象硬件资源,因此它们更经济,资源开销也较低。这有助于开发人员有效地优化服务器资源。

现在让我们换个话题来探索 Docker 的架构。

Docker架构

Docker 架构采用客户端-服务器设计。 Docker 客户端通过 REST API 与 Docker 守护进程通信,守护进程根据用户发出的命令管理容器。 REST API 负责客户端和守护进程之间的通信。

让我们深入了解一下Docker的架构;它如何在隔离的容器中运行应用程序以及它如何在幕后工作。

Docker架构

Docker引擎 (Engine)

Docker Engine本质上是安装在主机上的Docker。当您在系统上安装 Docker 时,您将安装以下关键组件:Docker 守护程序 ( Daemon )、Docker REST API 以及通过 REST API 与 Docker 守护程序交互的 Docker CLI。

让我们仔细看看每个组件。

Docker 守护进程– 这是一个管理 Docker 对象(例如映像/image、容器/container、存储卷/volume和网络/network)的后台进程。它不断监听 API 请求并处理它们。

Docker REST API – 这是应用程序用来与 Docker 守护进程对话并提供指令的 API 接口。

Docker CLI – 这是一个用于与 Docker 守护进程交互的命令行界面。它可以帮助您执行运行、停止和终止容器和映像等任务。它使用 REST API 与 Docker 守护进程交互。

Docker CLI 是一个客户端工具,不一定必须与其他组件位于同一主机上。它可以位于远程系统(例如笔记本电脑)上,并且仍然与远程 Docker 引擎通信。

要使用 Docker CLI 与远程 Docker 引擎进行通信,请传递标志,-H后跟远程主机的 IP 地址和端口号,如以下语法所示:

docker -H=remote-host-ip:port-number

例如,要在IP为10.10.2.1的远程Docker引擎上运行Apache容器,请运行以下命令:

docker -H=10.10.2.1:2375 run httpd

Docker客户端

Docker 客户端是一个网关或命令行界面 (CLI),允许您通过命令和 REST API 与 Docker 守护进程交互。这是用户与 Docker 引擎交互的主要方式。

客户端允许您从注册表中提取容器映像,并通过发出运行、停止和终止容器等命令来管理它们。

Docker客户端发出的常见命令包括:

docker pull
docker run 
docker build
docker stop
docker rm

Docker 对象

现在让我们关注 Docker 的对象。

映像 ( Image )

Docker 映像是容器的构建块。 Docker 映像是一个不可变或只读模板,为 Docker 容器提供指令。它包含应用程序运行所需的库、依赖项、源代码和其他文件。映像包含提供有关映像的更多信息的元数据。

Docker 映像是用 YAML 构建的,用于存储和传送应用程序。映像可用于构建容器或进行修改以将其他元素包含到当前配置中。映像可以在团队之间共享,也可以作为文件托管在组织的私有注册表或公共注册表(例如Docker Hub)上。

容器 ( Container )

docker 容器是应用程序的轻量级、独立的可执行包。它包含运行应用程序所需的所有内容:源代码、库、依赖项、运行时、系统工具和设置。

容器是使用 Docker 映像使用docker run命令构建的。考虑在 Docker 主机上运行Nginx容器的基本场景,如下所示:

docker run nginx

如果 Nginx 映像不在您的系统本地,Docker 将从 Docker 注册表中提取该映像。拉取映像后,将从该映像创建一个新的 Docker Nginx 容器,并将在您的环境中可用。

由于容器是基于映像构建的,因此它可以访问映像定义的底层资源。此外,您还可以根据当前容器的状态创建新映像。

由于容器本质上是轻量级的,因此可以在几秒钟内以较低的资源开销创建它们。这是容器比虚拟机更具优势的领域之一。

网络 ( Network )

Docker 网络是一个子系统,其中 Docker 容器与同一主机或不同主机上的其他容器(包括面向互联网的主机)连接。

Docker 中的网络是通过网络驱动程序实现的。 Docker中有五个主要的网络驱动程序:

Bridge:这是容器的默认网络驱动程序。如果您没有显式指定驱动程序,Docker 容器将默认在此网络中启动。当应用程序在需要相互通信的独立容器中运行时,使用桥接网络,同时提供与不同网络上的其他容器的隔离。

Host:这是消除 Docker 容器和主机系统之间隔离层的驱动程序。当您想要在与主机子网相同的网络上启动容器时,可以使用它。

Overlay:此驱动程序与Docker Swarm集群一起使用。它支持在单独的 Docker 主机上运行的集群服务或容器的通信。

Macvlan:当您想要为容器分配 MAC 地址以使它们看起来像物理设备时,可以使用此驱动程序。

None:此驱动程序禁用所有网络服务。

存储卷 ( Volume )

存储在容器中的数据是短暂的,一旦容器终止,数据就不再存在。 Docker 提供以下选项来确保持久存储:

数据卷:这些是用于持久保存容器生成和使用的数据的首选存储系统。数据卷本质上是安装在 Docker 容器上的文件系统,用于存储运行容器生成的数据。它们位于容器外部的主机系统上。

卷容器:另一种解决方案是使用一个专用容器来托管卷,然后将其用作其他容器的安装空间。这是同时在多个容器之间共享数据的一种方式。当将数据从其他容器备份到中央卷时,此方法非常理想。

目录挂载:对于数据卷和卷容器,数据存储在/var/lib/docker/volumes完全由 Docker 管理的文件系统中。对于目录挂载,数据可以存储在主机系统上的任何目录中,并在构建时将它们挂载到容器中。

存储插件:插件扩展了 Docker 的功能。存储插件提供了一种连接到外部存储设备的方法。它们将存储从主机系统映射到外部存储阵列或物理设备。

Docker 注册表 ( Registry )

Docker 注册表是托管各种类型容器映像的存储库。 Docker 映像是用 YAML 语言构建的,有多种形式——从操作系统、Web 服务器映像到Python和 Go 等编程语言的基础映像。

注册表被组织成存储库,其中每个存储库存储特定映像的所有版本。图像可能有多个版本,可以使用其名称标签进行识别。

Docker Hub是 Docker 的公共注册表。它托管公共和私人存储库。公共存储库可供所有人访问。私有的仅限制存储库创建者的访问。

Docker Hub 还支持官方存储库,其中包含经过验证的不带有任何用户名的容器映像。此类容器映像的示例包括 Nginx、Ubuntu、Redis、Node、RabbitMQ 和 Python。

默认情况下,Docker Engine 与 Docker Hub 的公共注册表进行交互。任何docker pull命令都会从 Docker Hub 注册表中提取容器映像。如果您有足够的访问权限,您还可以将自己的映像推送到注册表。

总结

Docker 是当今 DevOps 中广泛使用的工具。它帮助开发人员快速无缝地构建、发布和交付应用程序。有关 Docker 架构的更多信息,请访问Docker 文档页面