Docker - 架构
对于 DevOps 和 SRE 团队来说,最困难的任务之一是弄清楚如何管理跨多个云和开发环境的应用程序依赖项和技术栈。要做到这一点,他们的流程通常包括无论应用程序运行在哪里,都保持其正常运行,通常无需大幅更改其代码。
Docker 帮助所有工程师更高效地工作并减少运营开销,使任何开发环境中的任何开发者都能创建健壮可靠的应用程序。Docker 是一个用于构建、运送和运行软件程序的开放平台。
Docker 允许您将应用程序与基础设施解耦,从而能够快速发布软件。Docker 允许您以与管理应用程序相同的方式管理基础设施。使用 Docker 的运送、测试和部署代码的方法,可以大幅缩短从生成代码到在生产环境中运行代码的时间。
Docker 使用客户端-服务器架构。Docker 客户端与 docker daemon 通信,后者负责创建、执行和分发 docker container 的繁重工作。Docker 客户端与 daemon 在同一主机上运行,或者我们可以远程连接 Docker 客户端和 daemon。Docker 客户端和 daemon 通过 UNIX socket 或网络上的 REST API 进行通信。
在本章中,让我们详细讨论 Docker 架构。
容器与虚拟机之间的区别
虚拟机 (VM) 的存在是为了完成如果直接在主机环境中执行会很危险的任务。VM 与系统的其余部分隔离,因此虚拟机内的软件无法干扰主机计算机。
虚拟机是一个计算机文件或软件,通常称为 guest,或在称为主机的计算环境中生成的镜像。
虚拟机可以像在独立计算机上一样执行应用程序和程序,这使其非常适合测试其他操作系统(如 beta 版本)、创建操作系统备份以及安装软件和应用程序。主机可以同时运行多个虚拟机。
虚拟机包含几个基本文件,包括日志文件、NVRAM 设置文件、虚拟磁盘文件和配置文件。
服务器虚拟化 是虚拟机极具价值的另一个领域。服务器虚拟化将物理服务器分割成多个独立的独特服务器,每个服务器可以独立运行其操作系统。每个虚拟机都有自己的虚拟硬件,包括 CPU、RAM、网络端口、硬盘和其他组件。
另一方面,Docker 是一个软件开发工具 和虚拟化技术,它允许您轻松创建、部署和管理使用 container 的程序。container 是一个轻量级的独立可执行软件包,包含运行应用程序所需的所有库、配置文件、依赖项和其他组件。
换句话说,无论程序在哪里运行或在哪台计算机上运行,它们都会以相同的方式执行,因为 container 为应用程序在其软件开发生命周期中提供了环境。
由于 container 是隔离的,它们提供了安全性,允许多个 container 在同一主机上并发运行。此外,container 是轻量级的,因为它们不需要 hypervisor 的额外负载。hypervisor 类似于 VMware 或 VirtualBox 的 guest 操作系统,但 container 直接在主机机器内核中运行。
我应该选择 Docker 还是虚拟机 (VM)?
将 Docker 与虚拟机进行比较是不公平的,因为它们的设计目的是不同的。Docker 无疑正在流行起来,但不能认为它是虚拟机的替代品。尽管 Docker 很受欢迎,但在某些情况下,虚拟机是更好的选择。
在生产环境中,虚拟机比 Docker 容器更受欢迎,因为它们运行自己的操作系统,对主机计算机没有威胁。然而,对于测试目的,Docker 是最佳选择,因为它提供了多个 OS 平台,用于软件或应用程序的全面测试。
此外,Docker 容器也使用 Docker engine 而不是像虚拟机那样的 hypervisor。由于不共享主机内核,使用 docker-engine 使容器紧凑、隔离、兼容、高性能且响应迅速。
Docker 容器开销很小,因为它们可以共享单个内核和应用程序库。组织主要采用混合方法,因为虚拟机和 Docker 容器之间的选择取决于交付的工作负载类型。
此外,只有少数数字业务组织将虚拟机作为首选,而是选择使用容器,因为部署耗时,而运行微服务是它面临的最大障碍之一。然而,一些企业更喜欢虚拟机而不是 Docker,主要那些希望为其基础设施提供企业级安全的企业。
Docker 架构的组件
Docker 架构的关键组件包括:Docker Engine、Docker Registries 和 Docker Objects(Images、Containers、Network、Storage)。
让我们逐一讨论它们,以更好地理解 Docker 架构的不同组件如何相互交互。
Docker Engine
Docker Engine 是 Docker 平台的基础,它负责处理容器生命周期的所有元素。它由三个基本组件组成:命令行接口、REST API 和守护进程(负责处理任务)。
Docker 守护进程,通常称为 'dockerd',持续监听 Docker API 请求。它用于执行所有繁重任务,例如创建和管理 Docker objects,如 containers、volumes、images 和 networks。一个 Docker 守护进程可以与同一主机或其他主机上的其他守护进程通信。例如,在 swarm 集群中,主机上的守护进程可以连接到其他节点上的守护进程来完成任务。
Docker API 允许应用程序控制 Docker Engine。它们可以使用它来查询 containers 或 images 的详细信息、管理或上传 images,以及执行诸如创建新 containers 等操作。此功能可以通过 HTTP 客户端 Web 服务实现。
Docker Registries
Docker registries 是存储设施或服务,用于按需存储和检索 images。例如,registries 由 Docker repositories 组成,这些 repositories 将所有 images 保存在一个地方。
公共 registries 的两个主要组件是 Docker Hub 和 Docker Cloud。私有 registries 在组织中也很流行。与这些存储区域交互的最常用命令是 docker push, docker pull 和 docker run。
Dockerhub 是官方的 Docker registry,包含多个官方 image repositories。一个 repository 是由 Docker tags 唯一标识的相似 Docker images 的集合。Dockerhub 为用户提供丰富的官方和供应商特定的 images,例如 Nginx、Apache、Python、Java、Mongo、Node、MySQL、Ubuntu、Fedora、Centos 等。
您也可以在 Dockerhub 上设置自己的私有 repository,并使用 Docker push 命令存储自定义 Docker images。Docker 允许您在本地机器上构建自己的私有 Docker registry。一旦使用 registry image 启动了一个 container,您就可以使用 Docker push 命令将 images 推送到此私有 registry。
Docker Objects
使用 Docker 时,您会创建和管理 images、containers、networks、volumes、plugins 等其他项目。本节对其中一些项目进行简要总结。
Docker Images
Image 是一个只读模板,包含构建 Docker container 的指令。在许多情况下,image 是基于另一个 image 构建的,仅有一些细微修改。例如,您可以创建一个基于 Ubuntu image 的 image,但包含 Apache Web 服务器、您的应用程序以及运行应用程序所需的配置信息。
您可以创建自己的 images,或使用他人创建并发布到 registry 中的 images。要构建 image,请使用具有简单语法的 Dockerfile 来定义生成和运行 image 所需的动作。Dockerfile 中的每个指令都会在 image 中生成一层。当您编辑 Dockerfile 并重新构建 image 时,只有更改的层会被重新构建。这就是为什么 images 与其他虚拟化方法相比如此轻量、小巧且快速的原因之一。
您可以使用 Docker build 命令从 Dockerfile 创建 Docker Image。
这里,“-t” 为 image 指定一个 tag。末尾的点指定构建上下文,即 Dockerfile 所在的位置,在本例中是当前目录。
$ docker build -t myimage .
Docker Containers
Container 是 image 的运行实例。您可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除 container。您可以将 container 链接到一个或多个 networks,为其附加 storage,甚至从其当前状态构建新 image。
Container 通常与其他 containers 和主机机有效地隔离。您可以控制 container 的 network、storage 和其他底层子系统与其他 containers 和主机机的隔离程度。
Container 由其 image 以及创建或启动时指定的任何配置参数定义。当 container 被删除时,除非持久化,否则其状态的任何更改都会消失。
Containers 在生成 image 时完全访问 Dockerfile 中定义的资源。此类配置包括 build context、network 连接、storage、CPU、memory、ports 等。例如,如果您想访问安装了 Java libraries 的 container,可以使用 Dockerhub 的 Java image 和 Docker run 命令启动与之关联的 container。
您可以使用 Docker run 命令创建 container。这里,-it 标志以交互模式启动 container 并为其关联一个伪 TTY。/bin/bash 指定 container 启动时运行的命令。这将允许您访问 container 的 bash。
$ docker run -i -t ubuntu /bin/bash
Docker Networking
Docker networking 是所有隔离 containers 之间通信的一种方式。Docker 中主要有四种 network drivers −
Bridge
这是无法与外部世界通信的 containers 的默认 network。当您的应用程序运行在独立 containers 上时使用此 network,这些 containers 连接在一个 network 中,仅允许它们相互通信,而不与外部世界通信。
Host
此 driver 使 Docker 与本地机器上的资源无缝协作。它使用机器的原生 network 功能,在不同端点的 Docker 应用程序之间启用低级 IP 隧道和数据链路层加密。
Overlay Network
这是一种软件定义的 networking 技术,用于使 containers 连接。要将其链接到外部主机,首先在一个主机上构建虚拟 bridge,然后是 overlay network。您还需要设置 overlay network 并允许从一侧到另一侧的访问。“none” driver 通常表示 network 未连接。
macvlan
macvlan driver 可用于为 containers 分配地址,并使它们表现得像物理设备一样。其区别在于它使用 MAC 地址而不是 IP 来指导 containers 之间的通信。当您希望 containers 看起来像物理设备时使用此 network,例如迁移 VM 时。
Docker Storage
有几种选项可以安全存储数据。例如,您可以将数据存储在 container 的可写层上并使用 storage drivers。此方法的缺点是,如果您关闭或停止 container,除非您将其保存到其他地方,否则将丢失数据。
在 Docker containers 中实现持久存储时,有四种 alternatives −
Data volumes
它们允许您建立持久存储、重命名 volumes、列出 volumes,并查看与 volume 关联的 container。Data volumes 放置在 container 的 copy-on-write 机制之外的数据存储上,例如 S3 或 Azure。
Volume Container
Volume Container 是一种替代解决方案,其中专用 container 托管一个 volume,然后可以将其挂载或符号链接到其他 containers。在此方法中,volume container 独立于 application container,从而可以跨多个 containers 共享。
Directory Mounts
第三种选项是将主机的本地目录挂载到 container 内。在早期情况下,volumes 必须位于 Docker volumes 文件夹中,而 directory mounts 可以来自主机上的任何目录。
Storage Plugins
Storage plugins 允许 Docker 连接到外部存储源。这些 plugins 通过将主机的驱动映射到外部源,使 Docker 与存储阵列或设备协作。一个例子是允许您使用 Docker 安装的 GlusterFS 存储并将其映射到易于访问的位置的 plugin。
结论
总结来说,Docker 改变了开发者和 IT 运维人员处理应用程序依赖和跨多个环境部署流程的方式。
Docker 的客户端-服务器架构有效地将应用程序与其底层基础设施解耦,简化了开发、发布和执行软件的过程。这种方法极大地减少了从代码开发到生产环境的过渡所需的时间和精力,提高了软件开发过程的敏捷性和可扩展性。
Docker 容器的轻量级特性与其隔离功能相结合,为应用程序执行创建了稳定且一致的环境,无论宿主系统如何。
最终,Docker 的全面架构包括 Docker Engine、镜像仓库、image、container、网络和存储等组件,为企业提供了维护高性能、可靠且安全的应用程序环境所需的工具。
虽然 Docker 和虚拟机有各种用途和特性,但 Docker 的容器化技术非常适合现代云原生应用和微服务架构。那些在 DevOps 流程中使用 Docker 的组织可以提高构建和部署软件的效率、灵活性和速度。
常见问题解答
Q 1. Docker 架构的关键组件是什么?
Docker 架构由多个关键组件组成。Docker Engine 包括 Docker daemon、REST API 和命令行界面 (CLI),它们协同工作来管理 container 的生命周期。Docker image 是只读模板,用于生成包含程序及其依赖的 container。
Container 是 image 的运行实例,作为应用程序的隔离环境。Docker registries(如 Docker Hub)用于存储和分发 image,使其易于获取。
Docker networking 使 container 能够相互连接并与其他系统连接,而存储解决方案如 volume 确保数据在 container 生命周期之外持久化。
Q 2. Docker 可以用于开发和生产环境吗?
是的,Docker 设计用于开发、测试和生产环境,确保应用程序在所有阶段具有一致的环境。Docker 使开发者能够创建隔离的 container 来复制生产环境,确保程序一致执行。
在测试期间,container 可用于建立可重复的测试环境,这加速了流程并减少了由环境差异引起的问题。Docker 的编排技术,如 Docker Swarm 和 Kubernetes,通过处理 container 部署、扩展和管理,提高了其生产就绪性。