Docker
部署方式的演进
软件开发早期,应用部署依赖全人工操作:开发者打包代码、拷贝至服务器,再手动安装依赖、配置环境并启动服务。核心问题是环境不一致,同一代码在不同服务器表现不同,系统管理员需反复调试版本与配置。
互联网规模扩大后,虚拟机技术(硬件级虚拟化)登场。它通过 Hypervisor 在物理机上创建多个隔离实例,每个实例都有独立操作系统、内存和磁盘,既提升了资源利用率,也强化了系统隔离安全性。但虚拟机的短板也很明显:启动慢、资源占用大,且每个实例都要承载完整 OS 的冗余开销,部署和迁移效率受限。

为精准解决虚拟机的资源浪费与启动低效问题,容器技术(操作系统级虚拟化)应运而生。与虚拟机模拟完整操作系统的思路不同,容器采用 "共享内核" 的轻量级架构,复用宿主机的操作系统内核,仅隔离进程、网络、文件、用户等资源。这种设计让容器具备了诸多核心优势:启动速度几乎瞬时完成,远快于虚拟机分钟级的启动耗时;体积仅几十 MB 到几百 MB,资源占用大幅降低,一台物理机可部署成百上千个容器,资源利用率进一步提升。容器的隔离性虽基于内核级实现,却能满足绝大多数应用的资源隔离需求,且支持快速扩容、缩容和迁移,完美适配互联网时代微服务架构和持续集成 / 持续部署的需求。

Docker简介
什么是 Docker
Docker 是一款开源的应用容器化引擎,基于 Go 语言开发,遵循 Apache 2.0 开源协议。Docker 能够将应用程序及其依赖项、运行时、系统库、配置文件等完整封装为轻量、可移植、自包含的容器,实现在兼容 Docker 的环境中稳定、一致地运行,从而实现应用与底层环境的解耦。
从 Docker 17.03 版本开始,官方发布体系正式区分为 CE(Community Edition,社区版) 与 EE(Enterprise Edition,企业版)。其中社区版面向个人开发者、中小型团队与非生产场景,提供核心容器功能并依赖社区支持;企业版则面向生产级业务场景,提供增强的安全性、企业级支持、集中化管理、合规性保障及集成等企业级功能。目前, Docker Desktop 与 Docker Engine Community 是最常见的桌面和服务器部署方式,广泛应用于开发和测试环境。
Docker的核心理念
Docker 的核心目标是 "Build, Ship, and Run Any App, Anywhere"(构建、分发、运行任意应用,在任意兼容环境)。通过标准化封装应用及其依赖环境,Docker 实现了"一次构建、多环境一致运行"。容器确保无论在开发、测试、生产等不同环境中,应用的运行环境都高度一致,极大缓解了"环境不一致"导致的部署问题。
Docker 的优势
Docker 基于 Linux 内核的容器技术(如 Namespace、Cgroup 和 UnionFS)构建,并将底层容器能力进行了标准化、工具化和生态化封装,从而降低了容器的使用和运维门槛。容器能够保证应用环境在兼容 Docker 的主机上始终一致,使得跨节点、跨服务器、跨云厂商的部署更加简洁高效。通过一次环境配置和镜像构建,应用可以在多台机器上快速复制部署,显著简化了运维和发布流程。
容器通过沙箱机制与内核隔离能力运行,保证进程、网络、文件系统、用户等维度的强隔离,极大减少了容器之间的相互干扰。与传统虚拟机不同,容器共享宿主机操作系统的内核,不需要模拟完整的硬件和独立的操作系统,因此性能开销极低、资源利用率高,尤其适合高密度部署和高并发场景。
Docker 也大大降低了微服务架构的落地成本。微服务架构将单体应用拆分为多个小型、职责单一、独立自治的服务,支持独立开发、部署、扩缩容。Docker 与微服务架构高度契合:
每个微服务可以封装为独立容器,确保服务间的强隔离与互不干扰。
不同的微服务可以采用不同的技术栈、语言版本与依赖库,只需兼容容器运行环境。
容器化的微服务可以通过 Docker Compose(单机编排)或 Kubernetes(集群编排)等工具进行统一管理。
Docker 生态体系
Docker 生态系统由容器 (Containers)、镜像 (Images) 和仓库 (Repositories) 三个核心要素组成,它们相互协作,共同实现了 Docker 的高效、可移植、灵活的容器化解决方案。
一、容器 (Containers)
容器是 Docker 生态系统的核心,它承载了实际运行的应用程序及其所需的运行环境。容器是基于镜像创建的运行时实例,具有以下特点:
- 隔离性:容器提供了进程、网络、文件系统等层面的强隔离,确保不同容器之间不会相互干扰。每个容器运行自己的进程和应用,避免了环境冲突,确保在不同环境中运行时的一致性。
- 轻量性:与虚拟机不同,容器共享宿主操作系统的内核,无需模拟完整的硬件和操作系统,启动速度快,资源开销低。
- 可移植性:容器可以在任何兼容 Docker 的主机上运行,无论是开发、测试还是生产环境,确保环境一致性。
容器的生命周期包括:初创建、运行、停止、暂停、删除。一个镜像可以创建多个容器,每个容器都是镜像的一个实例。
二、镜像 (Images)
镜像是容器的蓝图,是容器运行时的模板。它是一个只读的文件系统,包含了应用程序及其他所有运行时所需的依赖。镜像具有以下特点:
- 层次化:Docker 镜像采用分层文件系统,每一层代表镜像构建过程中的某个操作。这些层是只读的,并且可重用,优化了存储空间和构建效率。
- 可重用性:镜像一旦构建完成,就可以多次使用和分发。它使得应用程序和环境的部署变得标准化和可重复,用户通过相同的镜像来确保应用在不同场景中的一致性。
- 构建方式:镜像通常是通过 Dockerfile 来定义和构建,Dockerfile 是一系列指令,描述了如何从基础镜像开始,安装应用依赖,复制文件,配置环境变量等。
三、仓库 (Repositories)
仓库用于存储和管理 Docker 镜像,支持镜像的上传、下载和共享 Docker 镜像。仓库可以是公共的或私有的,具有以下特点:
- Docker Hub:Docker Hub 是官方提供的公共镜像仓库,提供大量的官方和社区发布的镜像。
- 私有仓库:用户可构建私有仓库用于存储定制镜像,确保安全性和可控性。Docker 支持使用 Docker Registry 搭建私有仓库。
- 镜像版本管理:仓库中的镜像支持多版本管理,通过标签(tag)区分版本。用户可以根据标签拉取不同版本的镜像,从而满足不同的部署需求。
Docker 核心架构组件
Docker 采用客户端 - 服务器(C/S)架构,搭配镜像分发仓库,以下是其核心组件的介绍。
一、Docker Client
Docker Client 是用户与 Docker 进行交互的工具,它是 Docker 的前端接口。通常,Docker Client 以命令行界面(CLI)的形式存在。Docker Client 本身并不直接执行容器或镜像的操作,它的主要任务是将用户的操作指令转换为标准化的 API 请求,并将这些请求发送到 Docker Daemon。接收到 Docker Daemon 的响应后,Docker Client 会将结果反馈给用户,通常是通过命令行界面或其他格式展示。
二、Docker Daemon
Docker Daemon(即 dockerd)是 Docker 的后台服务,负责管理 Docker 容器的生命周期。它监听来自 Docker Client 的请求,并根据请求执行相应的操作。Docker Daemon 是 Docker 的核心部分,几乎所有的 Docker 功能都由它提供。
三、Docker Registry
Docker Registry 是 Docker 镜像的存储和分发中心,允许存储和管理 Docker 镜像。它是一个集中式的镜像仓库,提供了镜像上传、下载、版本控制等功能。
Docker 官方提供了一个公有的镜像仓库,叫做 Docker Hub,地址为 https://hub.docker.com/,这是最常用的公共 Registry。除此之外,用户也可以创建私有的 Registry,以便存储自定义的镜像。
Docker 镜像下载流程
-
拉取镜像请求
当用户运行
docker pull <image>命令时,Docker Client 会将该命令解析为标准化的 REST API 请求,并将请求发送给本地或远程的 Docker Daemon,请求从指定镜像仓库下载镜像。镜像格式:完整格式为 [registry-host]/[repository]:[tag];其中:registry-host 是镜像所在的仓库地址(如果未指定,默认指向 Docker Hub);repository 是镜像的名称或路径,tag 用于指定镜像的标签,默认为 latest 标签。如果未指定 tag,Docker 默认会使用 latest 标签进行拉取。需要注意的是,latest 并不代表 "最新版",而是默认的标签。
-
查找镜像的元数据
在接收到拉取请求后,Docker Daemon 会根据用户指定的镜像名称向 Docker Registry 发起请求,查询该镜像的元数据。该元数据包括镜像的层(Layer)、标签(Tag)、ID 等信息。Docker Daemon 将镜像的元数据返回给客户端,进行后续的镜像层下载。
-
下载镜像层
镜像是由多个只读层(layers)构成的增量文件系统,每层对应镜像构建的一个操作,Docker 使用层级结构来优化镜像的存储和传输。
Docker Daemon 会检查本地缓存中是否已存在某些镜像层,如果某些镜像层已经存在,Docker 会跳过这些层的下载,直接复用本地已有的层。对本地缺失的层,且镜像层之间有依赖关系,Docker Daemon 会根据层的依赖关系,采用多线程并行下载的方式,从镜像仓库下载缺失的镜像层。
-
存储镜像到本地
下载的镜像层会被存储在 Docker 主机本地的镜像存储位置。
每个镜像层被存储为独立的文件。对于相同的镜像层,不同容器的镜像可以共享同一层,避免冗余存储。
当容器启动时,Docker 会将所有下载的镜像层合并成一个逻辑上的文件系统。这个文件系统是只读的,容器的所有写入操作都会被重定向到一个额外的可写层,这个层是容器的写时复制层。
-
完成镜像下载并准备运行
当所有镜像层下载完成后,Docker Daemon 会完成镜像的下载过程,并将镜像的元数据添加到本地的 Docker 镜像仓库中。此时,该镜像已经可以在本地系统中使用。用户可以使用 docker images 命令查看本地存储的镜像及其相关信息,Docker 会利用本地的镜像层构建容器的文件系统运行容器。
