一、Docker简介

1 Docker 基础概述

1.1 官方定义

Docker 是一款开源的应用容器引擎,基于 Go 语言开发,遵循 Apache 2.0 开源协议。其核心能力是将应用及其依赖、运行环境打包到一个可移植的容器镜像中,实现一次构建,到处运行(Build Once, Run Anywhere),彻底解决应用在不同环境下的部署一致性问题。

1.2 诞生背景与解决的核心痛点

Docker 的出现,本质是解决传统应用交付与运维的行业痛点:

  1. 环境一致性问题:开发、测试、生产环境的系统版本、依赖库、配置差异,导致“在我电脑上能跑,线上跑不起来”的行业顽疾;
  2. 资源利用率低:传统虚拟机需虚拟完整 Guest OS,占用大量磁盘、内存资源,启动慢,单台物理机可部署的服务数量有限;
  3. 交付效率低下:传统应用交付需人工配置环境、部署依赖,流程繁琐,易出错,无法适配 DevOps 持续集成/持续交付(CI/CD)的自动化需求;
  4. 隔离性不足:多应用部署在同一台服务器时,存在端口冲突、依赖版本冲突、资源抢占等问题,故障易扩散。

1.3 核心优势

  • 环境一致性:打包应用全量运行环境,从根本上消除环境差异带来的部署问题;
  • 极致轻量:共享宿主机操作系统内核,无需虚拟完整 Guest OS,磁盘占用仅 MB 级,远小于虚拟机的 GB 级;
  • 秒级启动:容器本质是宿主机上的隔离进程,无需系统引导,启动速度可达毫秒/秒级,远超虚拟机的分钟级启动;
  • 强隔离性:基于 Linux 内核原生机制实现进程、网络、文件系统、资源的全面隔离,应用之间互不干扰;
  • 资源高效利用:单台物理机可部署数十甚至上百个容器,资源利用率较传统虚拟机提升 3-10 倍;
  • 极致可移植性:容器镜像可在任意安装了 Docker 引擎的 x86/ARM 架构服务器、PC、云主机上运行,无兼容性问题;
  • DevOps 原生支持:镜像构建可完全代码化(Dockerfile),无缝对接 CI/CD 流水线,实现开发、测试、部署全流程自动化;
  • 版本化管理:镜像支持版本标签、版本回滚,可追溯镜像的构建历史,实现应用交付的全生命周期管控;
  • 丰富生态:Docker Hub 官方仓库提供数十万开源应用的官方镜像,开箱即用,大幅降低应用部署门槛。

1.4 三层服务模式

1. IaaS(基础设施即服务)

Infrastructure as a Service

  • 给你提供:服务器、存储、网络、虚拟机等底层硬件资源。
  • 你自己管:操作系统、中间件、运行环境、数据、应用。
  • 例子:阿里云 ECS、腾讯云 CVM、AWS EC2、华为云 ECS。
  • 一句话:租机房和服务器,你自己装系统、搭环境。

2. PaaS(平台即服务)

Platform as a Service

  • 给你提供:操作系统、运行环境、数据库、中间件、开发工具
  • 你只管:写代码、部署应用、管理业务逻辑。
  • 例子:阿里云 RDS(数据库)、腾讯云 Serverless、Google App Engine、Docker 容器服务
  • 一句话:租一个现成平台,你只负责开发和上线应用。

3. SaaS(软件即服务)

Software as a Service

  • 给你提供:完整可用的软件,直接在浏览器 / APP 里用。
  • 你啥都不用管:不用运维、不用装环境、不用维护服务器。
  • 例子:微信、钉钉、企业微信、阿里云邮箱、飞书、各种在线办公软件。
  • 一句话:直接用软件,不用关心背后怎么运行。

[!tip]

  • IaaS = 租一块空地 + 建材 → 你自己盖房子、装修、住人
  • PaaS = 租一套毛坯 / 简装房 → 你只负责装修、布置、住人
  • SaaS = 租一套精装酒店 → 拎包直接住

2 Docker 核心架构(C/S 客户端-服务端架构)

Docker 采用标准的 C/S(Client-Server)架构,分为客户端、服务端两大核心模块,通过 REST API 进行通信,实现容器的全生命周期管理。

2.1 核心组件

2.1.1 Docker Client(客户端)

Docker 客户端是用户与 Docker 引擎交互的入口,核心职责是接收用户指令(如 docker rundocker build),并将指令转发给 Docker Daemon 执行。

  • 常见形式:命令行工具(CLI)、图形化工具、API 调用程序;
  • 特性:客户端可与本地/远程的 Docker Daemon 通信,支持跨主机管理。

2.1.2 Docker Daemon(守护进程)

Docker Daemon 是运行在宿主机后台的服务进程,是 Docker 的核心大脑,核心职责:

  1. 监听并处理来自 Docker Client 的 API 请求;
  2. 管理宿主机上的镜像、容器、网络、数据卷等所有 Docker 资源;
  3. 与其他 Docker Daemon 通信,实现集群化管理。

2.1.3 Docker Registry(镜像仓库)

镜像仓库是 Docker 镜像的集中存储与分发服务,是实现镜像跨环境、跨主机复用的核心载体。

  • 核心功能:提供镜像的拉取(pull)、推送(push)、存储、版本管理能力;
  • 分类:
    • 公共仓库:Docker Hub(官方默认仓库)、阿里云容器镜像服务、腾讯云容器镜像服务等;
    • 私有仓库:企业内部自建的仓库,如 Harbor、Docker 官方 Registry 镜像,用于存储企业内部业务镜像,保障数据安全。

2.1.4 Docker Host(宿主机)

指安装了 Docker 引擎、运行 Docker Daemon 的物理机/虚拟机,是容器运行的底层环境,所有容器均共享宿主机的操作系统内核。

2.2 核心工作流程(以容器启动为例)

  1. 用户通过 Docker Client 发送 docker run 启动容器的指令;
  2. Docker Client 将指令转换为 REST API 请求,发送给 Docker Daemon;
  3. Docker Daemon 先检查本地是否存在指定镜像:不存在则从配置的 Registry 仓库拉取镜像到本地;
  4. 镜像拉取完成后,Docker Daemon 基于镜像创建容器,调用 Linux 内核的 Namespace、Cgroups 机制,为容器创建隔离的运行环境、分配资源;
  5. 启动容器内的主进程,完成容器启动,并将结果返回给 Docker Client。

3 Docker 三大核心概念

镜像(Image)、容器(Container)、仓库(Repository)是 Docker 体系的三大基石,所有 Docker 操作均围绕这三个核心概念展开。

3.1 镜像(Image)

3.1.1 核心定义

Docker 镜像是只读的静态模板,包含了运行一个应用所需的所有内容:应用代码、运行时环境、依赖库、环境变量、配置文件、启动脚本等。
镜像不包含任何动态数据,其内容在构建之后不会被改变,是容器运行的基础。

3.1.2 核心特性

  • 只读性:镜像构建完成后,所有层均为只读状态,无法直接修改;若需修改,只能通过 Dockerfile 重新构建,生成新的镜像层;
  • 唯一标识:每个镜像通过 64 位的 SHA256 哈希值作为唯一 ID,可通过标签(Tag)进行版本管理(如 nginx:1.27.0latest 为默认最新版本标签);
  • 分层存储:镜像并非单一文件,而是由多个镜像层叠加组成,是 Docker 镜像轻量、可复用的核心。

3.1.3 镜像分层与写时复制(COW)机制

Docker 镜像基于联合文件系统(UnionFS) 实现分层存储,核心规则如下:

  1. 每个镜像由多个只读层(Layer)组成,每一层对应 Dockerfile 中的一条构建指令;
  2. 下层为上层的基础,上层仅记录相对于下层的增量修改,不同镜像之间可共享相同的底层镜像层;
  3. 核心机制:写时复制(Copy-On-Write, COW)
    • 所有镜像层共享复用,只有当需要修改镜像中的文件时,才会将该文件从底层只读层复制到顶层的可写层(容器层)进行修改,底层只读层始终保持不变;
    • 优势:极大减少镜像的磁盘占用(多个镜像共享基础层)、加快镜像分发与容器启动速度,同时保证基础镜像的完整性。

3.2 容器(Container)

3.2.1 核心定义

容器是镜像的运行实例,是一个独立、隔离、可运行的沙箱环境,是 Docker 的最小执行单元。
从文件系统视角,容器 = 镜像的所有只读层 + 一个容器专属的可写层;从操作系统视角,容器是一个基于 Linux 内核 Namespace、Cgroups 实现的隔离进程组。

3.2.2 核心特性

  • 可读写性:容器启动时,会在镜像只读层的顶部创建一个专属的可写层,容器运行过程中所有的文件修改、数据写入、日志生成,均存储在该可写层中,不会影响底层镜像;
  • 强隔离性:每个容器拥有独立的 Namespace,实现进程、网络、文件系统、用户、主机名等维度的全面隔离,容器之间、容器与宿主机之间互不干扰;
  • 资源可控:通过 Cgroups 严格限制容器的 CPU、内存、磁盘 IO、网络带宽等资源使用,防止资源抢占;
  • 生命周期独立:容器拥有自己的完整生命周期,与镜像解耦,同一镜像可启动多个相互独立的容器实例;
  • 临时性:容器的可写层生命周期与容器绑定,容器被删除时,对应的可写层会被一同销毁,数据永久丢失(除非通过数据卷实现持久化)。

3.2.3 镜像与容器的核心区别

维度镜像(Image)容器(Container)
本质只读静态模板,应用的“源代码”动态运行实例,应用的“进程”
存储特性分层只读,构建后不可修改只读镜像层 + 专属可写层,运行时可读写
生命周期持久化,构建后永久存在,除非手动删除临时,随启动/停止/删除而改变生命周期
关系容器的基础,一个镜像可创建无数容器镜像的执行体,容器的修改不会反向影响镜像
类比面向对象中的“类(Class)”面向对象中的“实例(Instance)”

3.3 仓库(Repository)

3.3.1 核心定义

仓库是集中存储同一应用不同版本镜像的集合,是镜像分发、共享、版本管理的核心载体。
需注意区分两个易混淆概念:

  • Registry:镜像仓库服务,是提供镜像存储、拉取、推送的服务端程序,一个 Registry 可包含多个 Repository;
  • Repository:具体的镜像仓库,用于存储同一应用的不同标签(Tag)镜像,例如 nginx 仓库中包含 1.27.0latestalpine 等多个标签的镜像。

3.3.2 仓库分类

  • 按访问权限分类:
    • 公开仓库:所有人可访问、拉取镜像,如 Docker Hub 官方镜像、国内云厂商公开镜像仓库;
    • 私有仓库:仅授权用户可访问,用于企业内部业务镜像的存储与管理,避免核心代码泄露。
  • 按镜像来源分类:
    • 官方镜像:Docker 官方维护的镜像,如 nginx、mysql、python 等,安全、稳定、经过严格测试,是生产环境首选;
    • 第三方镜像:个人/机构发布的镜像,可直接使用,需注意安全风险;
    • 自定义镜像:用户基于 Dockerfile 自行构建的业务镜像。

4 Docker 底层核心技术支撑

Docker 并非全新的技术创新,而是基于 Linux 内核多年沉淀的原生技术进行封装与优化,核心底层技术为三大件:Namespace、Cgroups、UnionFS

4.1 Namespace(命名空间):资源隔离

Namespace 是 Linux 内核提供的全局资源隔离机制,其核心作用是:将 Linux 的全局系统资源进行封装,使得不同 Namespace 中的进程拥有独立的资源视图,一个 Namespace 中的进程无法看到、访问其他 Namespace 中的资源,是 Docker 实现容器隔离的核心基石。

Docker 主要使用 Linux 内核的 6 大类 Namespace,实现容器的全维度隔离:

Namespace 类型隔离的核心资源核心作用
PID Namespace进程 ID隔离进程号,每个容器拥有独立的 PID 空间,容器内的 1 号进程为容器主进程,与宿主机、其他容器的 PID 完全隔离,无法感知外部进程
NET Namespace网络栈隔离网络资源,每个容器拥有独立的网卡、IP 地址、路由表、端口空间、防火墙规则,实现容器网络的完全隔离,避免端口冲突
MNT Namespace文件系统挂载点隔离文件系统视图,每个容器拥有独立的根文件系统,只能看到自身挂载的目录与文件,无法访问宿主机和其他容器的文件系统
UTS Namespace主机名与域名隔离主机标识,每个容器可设置独立的 hostname 和域名,不影响宿主机与其他容器
IPC Namespace进程间通信隔离信号量、消息队列、共享内存等进程间通信机制,只有处于同一 Namespace 的进程才能进行跨进程通信
User Namespace用户与用户组隔离用户权限,容器内的 root 用户仅在容器内拥有管理员权限,与宿主机的 root 用户解耦,大幅降低容器权限溢出的安全风险

4.2 Cgroups(控制组):资源限制

Cgroups(Control Groups)是 Linux 内核提供的进程组资源管控机制,与 Namespace 互补:Namespace 解决了“容器看不到外部资源”的隔离问题,Cgroups 解决了“容器最多能用多少资源”的限制问题,是 Docker 实现容器资源管控的核心。

Cgroups 的核心能力:

  1. 资源限制:严格限制进程组可使用的资源上限,包括 CPU、内存、磁盘 IO、网络带宽、最大进程数等,防止单个容器占用宿主机所有资源,保障宿主机与其他容器的稳定运行;
  2. 优先级控制:为不同容器设置资源使用优先级,高优先级的容器可获得更多的 CPU、内存资源;
  3. 资源审计:统计进程组的资源使用情况,如 CPU 时长、内存占用、IO 读写量等,用于监控与计费;
  4. 进程管控:支持进程组的批量挂起、恢复、冻结操作。

4.3 UnionFS(联合文件系统):分层存储

UnionFS 是一种为 Linux 设计的轻量级联合挂载文件系统,其核心能力是:将多个不同的目录(分支)联合挂载到同一个目录下,对外呈现一个统一的文件系统视图,是 Docker 镜像分层存储与写时复制机制的底层实现。

Docker 主流的存储驱动为 overlay2(生产环境官方推荐),其基于 UnionFS 实现,分为三类层级:

  • lowerdir:对应镜像的只读层,可多个,共享复用,永远不会被修改;
  • upperdir:对应容器的可写层,所有文件修改、新增、删除均在此层完成;
  • merged:联合挂载后的统一视图,用户看到的最终文件系统,整合了 lowerdir 和 upperdir 的所有内容。

4.4 补充安全机制

除三大核心技术外,Docker 还通过 Linux 内核的安全机制增强容器的安全性:

  • Capabilities:拆分 Linux root 用户的全量权限,为容器仅分配运行所需的最小权限,避免容器拥有宿主机 root 全量权限;
  • SELinux/AppArmor:强制访问控制(MAC)机制,为容器设置精细化的文件访问、进程执行权限规则,限制容器的攻击面;
  • Seccomp:系统调用过滤,限制容器可调用的 Linux 内核系统调用,减少内核漏洞被利用的风险。

5 容器完整生命周期

Docker 容器拥有完整的生命周期,共分为 6 个核心状态,状态之间可通过指令进行转换:

  1. 创建状态(Created)
    容器已通过镜像完成初始化,配置、资源、文件系统已就绪,但未启动,主进程未运行,不占用运行资源。
  2. 运行状态(Running)
    容器已启动,主进程正常运行,Namespace、Cgroups 已生效,容器正常对外提供服务,处于全功能运行状态。
  3. 暂停状态(Paused)
    容器内的所有进程被临时冻结,暂停执行,不释放已分配的资源,不终止进程,可随时恢复运行,适用于临时冻结容器状态的场景。
  4. 停止状态(Exited)
    容器内的主进程已终止运行,Namespace 隔离环境已释放,仅保留容器的可写层数据与配置信息,可重新启动恢复为运行状态。
  5. 删除状态(Deleted)
    容器被彻底删除,对应的可写层、配置、日志等所有数据被永久销毁,资源完全释放,无法恢复。

补充生命周期特殊状态:

  • 重启状态(Restarting):容器正在重启过程中,主进程终止后按重启策略重新启动;
  • 异常状态(Dead):容器发生严重错误,无法正常启动、停止、重启,需手动清理修复。

6 Docker 网络模型

Docker 基于 Linux 内核的 Network Namespace、虚拟网卡、网桥、iptables 等技术,实现了完整的网络模型,为容器提供了灵活的网络隔离与互通能力。

Docker 网络的核心是网络驱动(Network Driver),不同驱动对应不同的网络模式,实现不同的网络隔离级别与互通能力,Docker 提供 5 种原生默认网络驱动:

6.1 核心网络驱动与模式

网络模式核心驱动核心原理隔离级别性能适用场景
bridge(桥接模式)bridge 驱动Docker 守护进程默认创建 docker0 虚拟网桥,所有容器默认连接到该网桥,容器通过网桥实现与宿主机、其他容器、外网的通信,需通过端口映射将容器端口暴露到宿主机中等,容器之间网络隔离,通过网桥互通中等单机单节点部署,绝大多数默认场景,是 Docker 默认网络模式
host(主机模式)host 驱动容器与宿主机共享同一个 Network Namespace,容器直接使用宿主机的 IP 地址、网卡、端口空间,无网络隔离无网络隔离最高,无网络转发损耗对网络性能要求极高的场景,如数据库、高并发服务,需注意端口冲突风险
none(无网络模式)null 驱动容器拥有独立的 Network Namespace,但不创建任何网卡、IP 地址、路由规则,仅保留 lo 回环接口,完全无法与外部网络通信最高,完全网络隔离无网络能力极致安全的离线场景,如加密计算、数据处理、无需网络的批处理任务
container(容器共享模式)无专属驱动多个容器共享同一个 Network Namespace,共享同一个 IP 地址、网络栈、端口空间,容器之间可通过 lo 回环接口通信低,共享网络的容器之间无隔离边车(Sidecar)模式,如日志采集、监控代理、流量代理,与主业务容器共享网络
overlay(覆盖网络模式)overlay 驱动基于 VXLAN 隧道技术,实现跨宿主机的容器二层网络互通,不同宿主机上的容器可处于同一个虚拟子网,直接互通中等,跨主机容器网络隔离中等,有隧道封装损耗Docker Swarm 集群、跨主机容器编排场景,多节点集群部署

7 Docker 数据持久化机制

容器的可写层是临时的,容器删除时可写层数据会永久丢失,无法满足数据库、日志、业务文件等需要长期保存的数据的存储需求。Docker 提供了三种原生数据持久化方案,核心原理是将宿主机的文件系统目录挂载到容器中,实现数据的持久化存储,生命周期与容器解耦。

7.1 三种持久化方案对比

持久化方案核心定义生命周期可移植性灵活性官方推荐度适用场景
数据卷(Volumes)Docker 守护进程管理的宿主机目录,完全脱离容器文件系统,对容器完全透明独立于容器,容器删除,数据卷不会被销毁,可手动管理最高,不依赖宿主机目录结构,跨主机、跨环境兼容中等,仅能管理 Docker 指定的目录最高,官方首选方案绝大多数生产环境持久化场景,如数据库数据存储、应用配置、日志持久化、多容器数据共享
绑定挂载(Bind Mounts)将宿主机上的任意文件/目录直接挂载到容器中,宿主机与容器可双向读写与宿主机目录绑定,与容器生命周期无关低,强依赖宿主机的目录结构与权限,跨环境兼容性差最高,可挂载宿主机任意目录,完全可控中等,非生产环境首选开发环境,需将宿主机代码、配置实时同步到容器的场景;需宿主机与容器共享配置文件的场景
tmpfs 挂载(tmpfs Mounts)将容器的目录挂载到宿主机的内存中,数据完全存储在内存,不会写入磁盘与容器绑定,容器停止,数据立即丢失无,仅在当前宿主机当前容器生效低,仅内存存储不推荐用于持久化敏感临时数据存储,如密钥、会话信息;高并发临时文件读写,无需持久化的场景

核心原则:生产环境优先使用 Volumes 数据卷实现持久化,避免使用绑定挂载,防止因宿主机目录权限、结构差异导致的兼容性问题。

8 Docker 容器与传统虚拟机的核心对比

对比维度Docker 容器传统虚拟机(VM)
虚拟化层级操作系统级虚拟化,共享宿主机内核硬件级虚拟化,基于 Hypervisor 虚拟完整硬件
系统依赖仅需宿主机 Linux/Windows 内核,无需 Guest OS需在虚拟硬件上安装完整的 Guest OS(如 CentOS、Ubuntu)
启动速度秒级/毫秒级,仅需启动容器主进程分钟级,需完成完整的系统引导、内核启动、服务初始化
资源占用极小,磁盘占用 MB 级,内存占用远低于虚拟机极大,磁盘占用 GB 级,需为虚拟机预分配固定内存、CPU 资源
资源利用率极高,单台物理机可部署数十上百个容器,资源按需分配低,单台物理机仅能部署数个虚拟机,资源预分配,利用率低
隔离性基于内核 Namespace 实现进程级隔离,安全边界清晰完全硬件隔离,隔离级别最高,安全性更强
可移植性极强,一次构建,跨环境、跨架构运行,无兼容性问题差,虚拟机镜像强依赖硬件架构与 Hypervisor,跨平台迁移难度大
性能损耗极低,几乎无性能损耗,接近原生宿主机性能中等,硬件虚拟化与 Guest OS 带来一定的性能损耗
管理成本低,单条命令即可完成容器的创建、启动、删除,自动化能力强高,需人工管理虚拟机的系统安装、配置、补丁、运维,自动化难度大

9 Docker 核心设计理念

  1. 一次构建,到处运行:核心核心理念,通过镜像打包应用全量运行环境,彻底消除环境差异,实现应用跨环境的无缝交付;
  2. 基础设施即代码(IaC):通过 Dockerfile 实现镜像构建的代码化、版本化,可纳入 Git 等版本控制系统,实现可追溯、可重复、可自动化的镜像构建;
  3. 单进程原则:推荐一个容器仅运行一个主进程,职责单一,便于容器的生命周期管理、日志收集、故障排查,符合微服务架构的设计理念;
  4. 最小化原则:镜像构建遵循最小化原则,仅包含应用运行所需的最小依赖,减小镜像体积,提升分发速度,减少攻击面,提升安全性;
  5. 不可变基础设施:镜像构建完成后即为不可变的,环境变更需通过重新构建镜像实现,而非修改运行中的容器,保障环境的一致性与可重复性,避免配置漂移。

10 学习资源推荐

10.1 官方

Docker 官方文档

  • 地址:https://docs.docker.com/
  • 核心亮点:覆盖从安装、基础命令、Dockerfile、Compose、网络、存储到安全、底层原理的全体系内容,提供交互式入门教程、最佳实践、CLI/API 完整参考手册,实时同步最新版本特性,支持中文切换Docker。
  • 核心板块推荐:Get started(零基础入门)、Guides(场景化教程)、Dockerfile 最佳实践、Docker Compose 手册。

Docker Hub 官方镜像仓库

  • 地址:https://hub.docker.com
  • 核心亮点:全球最大的容器镜像仓库,提供数十万官方认证镜像(Nginx、MySQL、Python 等),是学习镜像构建、镜像分层、生产级镜像规范的最佳参考,所有镜像均可直接拉取实操。

Docker 官方实验室与开源仓库

Docker 官方博客

  • 地址:https://www.docker.com/blog/
  • 核心亮点:同步 Docker 最新版本更新、行业最佳实践、安全漏洞修复、云原生容器技术趋势,是跟进 Docker 技术发展的核心渠道。

10.2 教程

《Docker —— 从入门到实践》

  • 地址:https://yeasy.gitbook.io/docker_practice/
  • 核心亮点:国内最经典、最受欢迎的 Docker 开源中文教程,累计数百万学习者阅读。内容从基础概念、环境安装、常用命令,到进阶的镜像构建、网络、存储、安全,再到 K8s 对接,全程配套实操案例,完全开源免费,持续更新,适配最新 Docker 版本,是零基础入门的不二之选。

阮一峰 Docker 入门教程

  • 地址:https://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html
  • 核心亮点:全网传播最广的 Docker 零基础科普文,用极简的语言、生活化的类比讲透 Docker 核心原理和核心操作,无晦涩术语,1 小时就能快速理解 Docker 的核心逻辑,适合纯新手建立基础认知。

Java 全栈知识体系 - Docker 专栏

  • 地址:https://pdai.tech/md/devops/docker/docker-00-overview.html
  • 核心亮点:体系化极强,从基础到进阶、底层原理、安全、集群实践全覆盖,内容严谨,配套代码示例,适合开发 / 运维人员系统学习,同时可衔接后续云原生、K8s 学习。

DockerInfo 中文文档站

  • 地址:http://www.dockerinfo.net/document
  • 核心亮点:官方文档的中文补充站点,提供中文翻译版的命令手册、常见问题、安装教程,适合英文基础薄弱的学习者查阅。

10.3 资源汇总仓库

  1. awesome-docker

    • 地址:https://github.com/veggiemonk/awesome-docker
    • 亮点:Docker 领域最权威的开源资源汇总,累计超 7 万 Star,收录了上千个 Docker 相关的工具、教程、开源项目、最佳实践、社区资源,覆盖 Docker 全生态,是 Docker 学习的一站式导航。
  2. docker-practice

    • 地址:https://github.com/yeasy/docker_practice
    • 亮点:《Docker —— 从入门到实践》的开源仓库,配套所有教程的代码、示例、环境配置,可直接下载实操,持续接受社区贡献,保持内容最新。

二、Docker实践

1 Docker安装

1.1 配置软件仓库

[!tip]

注意: 此处采用国内镜像站配置,系统为RHEL Linux

1
2
3
4
5
6
7
[root@Docker ~]# cat > /etc/yum.repos.d/docker.repo << EOF
[Docker]
name = docker-ce
baseurl = https://mirrors.aliyun.com/docker-ce/linux/rhel/9.6/x86_64/stable/
gpgcheck = 0
enable = 1
EOF

1.2 安装与验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@Docker ~]# dnf makecache
正在更新 Subscription Management 软件仓库。
docker-ce 104 kB/s | 46 kB 00:00
epel 36 kB/s | 4.0 kB 00:00
AppStream 3.1 MB/s | 3.2 kB 00:00
BaseOS 2.7 MB/s | 2.7 kB 00:00
元数据缓存已建立。

[root@Docker ~]# dnf search docker

[root@Docker ~]# dnf install docker-ce -y

[root@Docker ~]# docker -v
Docker version 29.3.0, build 5927d80

1.3 网络环境初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 启用 Docker 的 iptables 管理能力
[root@Docker ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true

# 配置桥接网络内核模块开机自启
[root@Docker ~]# echo br_netfilter > /etc/modules-load.d/docker_mod.conf

# 立即加载桥接网络内核模块
[root@Docker ~]# modprobe -a br_netfilter

# 配置 Docker 必需的内核网络参数
[root@Docker ~]# cat > /etc/sysctl.d/docker.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

# 重载 systemd 配置
[root@Docker ~]# systemctl daemon-reload

# 加载内核参数
[root@Docker ~]# sysctl --system
[root@Docker ~]# systemctl enable --now docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.

1.4 配置国内镜像仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@Docker ~]# cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": [
"https://docker.xuanyuan.me"
]
}
EOF

[root@Docker ~]# systemctl daemon-reload
[root@Docker ~]# systemctl restart docker

# 验证仓库
[root@Docker ~]# docker info

国内可用免费镜像源 (2026/3/16)

名称镜像地址
毫秒镜像https://docker.1ms.run
耗子面板https://hub.rat.dev
DaoCloudhttp://docker.m.daocloud.io
CNIX Internalhttps://docker.m.ixdev.cn
轩辕镜像https://docker.xuanyuan.me

2 Docker相关操作

2.1常用操作

  • 镜像(images) 管理

    1
    2
    3
    4
    5
    6
    7
    8
    docker pull <镜像名>:<标签>  					 # 从仓库拉取镜像到本地, 标签默认为latest
    docker images / docker image ls # 列出本地所有镜像
    docker rmi <镜像名/镜像ID> # 删除本地镜像 (需先删除对应容器)
    docker build -t <镜像名>:<标签> <Dockerfile路径> # 基于 Dockerfile 构建镜像
    docker tag <原镜像> <新镜像名>:<标签> # 为镜像打标签(常用于推送到私有仓库)
    docker push <镜像名>:<标签> # 将镜像推送到仓库
    docker save <镜像名> -o <文件名>.tar # 将镜像导出为 tar 包
    docker load -i <文件名>.tar # 从 tar 包导入镜像
  • **容器(**Container)管理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    docker run <参数> <镜像名>	 					 # 创建并启动容器
    docker ps # 列出正在运行的容器
    docker ps -a # 列出所有容器(包括已停止的)
    docker stop <容器ID/容器名> # 停止运行中的容器
    docker start <容器ID/容器名> # 启动已停止的容器
    docker restart <容器ID/容器名> # 重启容器
    docker rm <容器ID/容器名> # 删除已停止的容器(加 -f 强制删除运行中的容器)
    docker exec -it <容器ID/容器名> <命令> # 进入容器内部执行命令(如开启 shell)
    docker logs <容器ID/容器名> # 查看容器日志
    docker cp <本地路径> <容器ID/容器名>:<容器路径> # 在本地和容器之间复制文件
    • 参数

      参数作用
      -d后台(detached)运行容器,返回容器 ID
      --name <容器名>为容器指定自定义名称
      -p <宿主机端口>:<容器端口>端口映射(将宿主机端口映射到容器端口)
      -v <宿主机路径>:<容器路径>数据卷挂载(持久化数据,或共享配置文件)
      -e <环境变量名>=<值>设置容器内的环境变量
      --restart=always容器退出时自动重启(生产环境常用)
      -it交互式运行(通常配合 /bin/bash 进入容器)
      --rm容器停止后自动删除(适合临时测试)

2.2 数据卷与网络管理

  • 数据卷(Volume)

    1
    2
    3
    4
    docker volume create <卷名>	# 创建数据卷
    docker volume ls # 列出所有数据卷
    docker volume rm <卷名> # 删除数据卷
    docker volume inspect <卷名> # 查看数据卷详细信息(包括宿主机挂载路径)
  • 网络(Network)

    1
    2
    3
    4
    5
    6
    命令	作用	示例
    docker network ls # 列出所有 Docker 网络
    docker network create <网络名> # 创建自定义网络(默认 bridge 模式)
    docker network connect <网络名> <容器名> # 将容器连接到指定网络
    docker network disconnect <网络名> <容器名> # 断开容器与网络的连接
    docker network rm <网络名> # 删除网络

2.3 系统信息与监控

1
2
3
4
5
6
7
docker info				  	   # 查看 Docker 系统级信息(镜像 / 容器数量、存储驱动、网络配置等)	
docker search <镜像名> # 搜索镜像全部版本
docker version # 查看 Docker 客户端和服务端版本信息
docker inspect <容器/镜像名> # 查看容器 / 镜像的详细元数据(JSON 格式,包括 IP、挂载、配置等)
docker stats # 实时查看容器的资源使用情况(CPU、内存、网络 IO 等)
docker top <容器ID/容器名> # 查看容器内运行的进程
docker history <镜像名:标签> # 查看镜像历史

2.4 容器生命周期

1
2
3
4
5
docker info					   # 查看 Docker 系统级信息(镜像 / 容器数量、存储驱动、网络配置等)
docker version # 查看 Docker 客户端和服务端版本信息
docker inspect <容器/镜像名> # 查看容器 / 镜像的详细元数据(JSON 格式,包括 IP、挂载、配置等)
docker stats # 实时查看容器的资源使用情况(CPU、内存、网络 IO 等)
docker top <容器ID/容器名> # 查看容器内运行的进程

2.5 Docker Compose 常用命令

1
2
3
4
5
6
docker compose up -d			   # 基于 docker-compose.yml 创建并启动所有服务(-d 后台运行)
docker compose down # 停止并删除所有服务、网络、数据卷(加 -v 同时删除数据卷)
docker compose ps # 列出当前 Compose 项目的所有容器
docker compose logs <服务名> # 查看指定服务的日志
docker compose exec <服务名> <命令> # 在指定服务的容器中执行命令
docker compose build # 重新构建 Compose 中定义的镜像

3 Dockerfile文件构建

Dockerfile 是用来构建 Docker 镜像的文本文件,里面包含了一系列指令(参数),Docker 会按顺序执行这些指令来生成镜像。

参数以及作用表

指令名称核心作用常用语法关键注意事项
FROM指定构建镜像的基础镜像(必选)FROM <镜像名>:<标签> FROM scratch(空镜像)1. 必须是第一条非注释指令 2. 标签建议指定具体版本(如 python:3.9),避免用 latest
WORKDIR设置构建 / 容器运行时的默认工作目录WORKDIR <绝对路径>1. 目录不存在会自动创建 2. 优先用绝对路径,避免相对路径混乱
COPY从主机复制文件 / 目录到镜像COPY <源路径> <目标路径>1. 源路径相对 Dockerfile 所在目录 2. 目标路径不存在会自动创建
ADD增强版复制(支持解压压缩包 / 下载 URL)ADD <源路径> <目标路径>1. 日常优先用 COPY(更清晰) 2. 仅需解压压缩包时用 ADD
RUN构建镜像时执行命令(如安装依赖)RUN <shell命令>(常用) RUN ["可执行文件", "参数1"]1. 多命令用 && 合并,减少镜像层 2. 执行后清理无用文件(如 apt 缓存)
CMD容器启动时默认执行的命令CMD <shell命令> CMD ["可执行文件", "参数1"](推荐)1. 一个 Dockerfile 仅最后一个生效 2. 启动容器时手动指定命令会覆盖它
ENTRYPOINT容器启动的入口命令(不可被覆盖)ENTRYPOINT ["可执行文件", "参数1"](推荐)1. 常与 CMD 配合(CMD 作为默认参数) 2. 需覆盖时加 --entrypoint 参数
ENV设置环境变量(构建 / 运行时均有效)ENV <变量名>=<值> ENV <变量名> <值>1. 后续指令用 $变量名 引用 2. 容器运行时可通过 -e 覆盖
EXPOSE声明容器监听的端口(仅提示,不映射)EXPOSE <端口1> [<端口2>/<协议>]1. 真正映射需加 docker run -p 主机端口:容器端口 2. 可声明 TCP/UDP(如 80/udp
VOLUME定义数据卷(持久化容器数据)VOLUME ["<路径1>", "<路径2>"]1. 数据卷独立于容器生命周期 2. 启动时可通过 -v 挂载自定义目录
USER指定执行后续指令的用户 / UIDUSER <用户名/UID>1. 优先用非 root 用户,提升安全性 2. 需 root 权限时可临时切换
LABEL添加镜像元数据(如作者、版本)LABEL <key1>=<value1> <key2>=<value2>可通过 docker inspect 镜像名 查看标签信息
ARG定义构建参数(仅构建阶段有效)ARG <参数名>[=<默认值>]1. 构建时用 --build-arg 覆盖默认值 2. 容器运行时无法访问
ONBUILD触发指令(子镜像构建时执行)ONBUILD <其他指令>仅当当前镜像作为基础镜像时生效,用于镜像模板
HEALTHCHECK检查容器健康状态HEALTHCHECK --interval=30s CMD <检查命令>1. --interval 为检查间隔 2. 检查失败返回非 0 会标记容器不健康

核心优先级FROM 是必选基础,RUN/COPY/ADD 负责构建,CMD/ENTRYPOINT 负责运行,这 6 个是日常最常用的指令;

优化原则:用 RUN && 合并命令、清理无用文件、使用非 root 用户,可减小镜像体积并提升安全性;

参数区别ENV 是运行时变量,ARG 是构建时变量,EXPOSE 仅声明端口不映射,需注意使用场景差异。

4 搭建私有仓库

4.1 搭建Registry仓库

  • 下载镜像

    1
    [root@Docker1 ~]# docker pull registry
  • 开启Registry

    1
    docker run  -d -p 5000:5000 --restart=always --name registry registry:latest
  • 验证

    1
    2
    3
    4
    [root@Docker1 ~]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    abbbbb4c08fb registry:latest "/entrypoint.sh /etc…" 3 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp registry webserver
    [root@Docker1 ~]#
  • 上传镜像到仓库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 打标签
    [root@Docker1 ~]# docker tag busybox:latest 172.25.254.10:5000/busybox:latest
    # Docker上传默认使用https, 所以需要配置认证文件
    [root@Docker1 ~]# docker push 172.25.254.10:5000/busybox:latest
    The push refers to repository [172.25.254.10:5000/busybox]
    61dfb50712f5: Unavailable
    failed to do request: Head "https://172.25.254.10:5000/v2/busybox/blobs/sha256:af3f0f48a24edb84e94aff6f44f5d089203453719d3b2328486d311e61db9b09": http: server gave HTTP response to HTTPS client

    # 配置非加密端口
    [root@Docker1 ~]# vim /etc/docker/daemon.json

    {
    "insecure-registries" : ["http://172.25.254.10:5000"]
    }

    [root@docker ~]# systemctl restart docker

    # 重新上传
    [root@Docker1 ~]# docker push 172.25.254.10:5000/busybox:latest

    [root@Docker1 ~]# curl 172.25.254.10:5000/v2/_catalog
    {"repositories":["busybox"]}

4.2 为Registry提加密传输

  • 生成认证key和证书

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [root@Docker1 ~]# mkdir certs

    [root@Docker1 ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/hua.xyz.key -addext "subjectAltName = DNS:reg.hua.xyz" -x509 -days 365 -out certs/hua.xyz.crt
    -----
    Country Name (2 letter code) [XX]:CN
    State or Province Name (full name) []:Hunan
    Locality Name (eg, city) [Default City]:Hengyang
    Organization Name (eg, company) [Default Company Ltd]:docker
    Organizational Unit Name (eg, section) []:registry
    Common Name (eg, your name or your server's hostname) []:reg.hua.xyz
    Email Address []:

    [root@Docker1 ~]# vim /etc/hosts
    172.25.254.10 Docker1 reg.hua.xyz
  • 查看证书信息

    1
    [root@Docker1 ~]# openssl x509 -in certs/hua.xyz.crt -noout -text
  • 启动registry仓库

    1
    2
    3
    4
    5
    6
    7
    [root@docker ~]# docker run -d -p 443:443 --restart=always --name registry \
    -v /opt/registry:/var/lib/registry \
    -v /root/certs:/certs \
    -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/hua.xyz.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/hua.xyz.key registry
    f05870cc1536ff35b04e533efb840e879496fbd441391fa1e13f4e883fdd76e3
  • 测试

    1
    2
    3
    4
    5
    6
    7
    [root@Docker1 ~]# docker tag busybox:latest  reg.hua.xyz/busybox:latest

    # 出现这种情况是因为 docker客户端没有key和证书
    [root@Docker1 ~]# docker push reg.hua.xyz/busybox:latest
    The push refers to repository [172.25.254.10:5000/busybox]
    61dfb50712f5: Unavailable
    failed to do request: Head "https://reg.hua.xyz/busybox/v2/busybox/blobs/sha256:61dfb50712f5ff92c880813210257a42169ff0937896ae95dab763582cc380e2": dial tcp 172.25.254.10:5000: connect: connection refused
  • 为客户端建立证书

    1
    2
    3
    [root@docker docker]# mkdir /etc/docker/certs.d/reg.hua.xyz/ -p
    [root@docker docker]# cp /root/certs/hua.xyz.crt /etc/docker/certs.d/reg.hua.xyz/ca.crt
    [root@docker docker]# systemctl restart docker
  • 再次测试

    1
    2
    3
    4
    [root@Docker1 ~]# docker push reg.hua.xyz/busybox:latest

    [root@Docker1 ~]# curl -k https://reg.hua.xyz/v2/_catalog
    {"repositories":["busybox"]}

4.3 为Registry建立登录认证

  • 前置准备

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #安装建立认证文件的工具包
    [root@Docker1 ~]## dnf install httpd-tools -y

    #建立认证文件
    [root@Docker1 ~]# mkdir auth
    [root@Docker1 ~]# htpasswd -Bc auth/htpasswd hua #-B 强制使用最安全加密方式,默认用md5加密
    New password:
    Re-type new password:
    Adding password for user timinglee
  • 添加认证到registry容器中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #添加认证到registry容器中	
    [root@docker1 ~]# docker run -d -p 443:443 --restart=always --name registry \
    -v /opt/registry:/var/lib/registry \
    -v /root/certs:/certs \
    -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
    -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/hua.xyz.crt \
    -e REGISTRY_HTTP_TLS_KEY=/certs/hua.xyz.key \
    -v /root/auth:/auth \
    -e "REGISTRY_AUTH=htpasswd" \
    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
    -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
    registry


    [root@Docker1 ~]# curl -k https://reg.hua.xyz/v2/_catalog -u hua:hua
    {"repositories":["busybox"]}


    #登陆测试
    [root@Docker1 ~]# docker login reg.hua.xyz
    Username: hua
    Password:

    WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/go/credential-store/

    Login Succeeded
  • 测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #未登陆情况下上传镜像
    [root@Docker1 ~]# docker push reg.hua.xyz/busybox
    Using default tag: latest
    The push refers to repository [reg.hua.xyz/busybox]
    61dfb50712f5: Unavailable
    push access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials


    #未登陆情况下也不能下载
    [root@Docker1 ~]# docker pull reg.hua.xyz/busybox
    Using default tag: latest
    Error response from daemon: failed to resolve reference "reg.hua.xyz/busybox:latest": pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials