云原生高级-Docker
一、Docker简介
1 Docker 基础概述
1.1 官方定义
Docker 是一款开源的应用容器引擎,基于 Go 语言开发,遵循 Apache 2.0 开源协议。其核心能力是将应用及其依赖、运行环境打包到一个可移植的容器镜像中,实现一次构建,到处运行(Build Once, Run Anywhere),彻底解决应用在不同环境下的部署一致性问题。
1.2 诞生背景与解决的核心痛点
Docker 的出现,本质是解决传统应用交付与运维的行业痛点:
- 环境一致性问题:开发、测试、生产环境的系统版本、依赖库、配置差异,导致“在我电脑上能跑,线上跑不起来”的行业顽疾;
- 资源利用率低:传统虚拟机需虚拟完整 Guest OS,占用大量磁盘、内存资源,启动慢,单台物理机可部署的服务数量有限;
- 交付效率低下:传统应用交付需人工配置环境、部署依赖,流程繁琐,易出错,无法适配 DevOps 持续集成/持续交付(CI/CD)的自动化需求;
- 隔离性不足:多应用部署在同一台服务器时,存在端口冲突、依赖版本冲突、资源抢占等问题,故障易扩散。
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 run、docker build),并将指令转发给 Docker Daemon 执行。
- 常见形式:命令行工具(CLI)、图形化工具、API 调用程序;
- 特性:客户端可与本地/远程的 Docker Daemon 通信,支持跨主机管理。
2.1.2 Docker Daemon(守护进程)
Docker Daemon 是运行在宿主机后台的服务进程,是 Docker 的核心大脑,核心职责:
- 监听并处理来自 Docker Client 的 API 请求;
- 管理宿主机上的镜像、容器、网络、数据卷等所有 Docker 资源;
- 与其他 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 核心工作流程(以容器启动为例)
- 用户通过 Docker Client 发送
docker run启动容器的指令; - Docker Client 将指令转换为 REST API 请求,发送给 Docker Daemon;
- Docker Daemon 先检查本地是否存在指定镜像:不存在则从配置的 Registry 仓库拉取镜像到本地;
- 镜像拉取完成后,Docker Daemon 基于镜像创建容器,调用 Linux 内核的 Namespace、Cgroups 机制,为容器创建隔离的运行环境、分配资源;
- 启动容器内的主进程,完成容器启动,并将结果返回给 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.0,latest为默认最新版本标签); - 分层存储:镜像并非单一文件,而是由多个镜像层叠加组成,是 Docker 镜像轻量、可复用的核心。
3.1.3 镜像分层与写时复制(COW)机制
Docker 镜像基于联合文件系统(UnionFS) 实现分层存储,核心规则如下:
- 每个镜像由多个只读层(Layer)组成,每一层对应 Dockerfile 中的一条构建指令;
- 下层为上层的基础,上层仅记录相对于下层的增量修改,不同镜像之间可共享相同的底层镜像层;
- 核心机制:写时复制(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.0、latest、alpine等多个标签的镜像。
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 的核心能力:
- 资源限制:严格限制进程组可使用的资源上限,包括 CPU、内存、磁盘 IO、网络带宽、最大进程数等,防止单个容器占用宿主机所有资源,保障宿主机与其他容器的稳定运行;
- 优先级控制:为不同容器设置资源使用优先级,高优先级的容器可获得更多的 CPU、内存资源;
- 资源审计:统计进程组的资源使用情况,如 CPU 时长、内存占用、IO 读写量等,用于监控与计费;
- 进程管控:支持进程组的批量挂起、恢复、冻结操作。
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 个核心状态,状态之间可通过指令进行转换:
- 创建状态(Created)
容器已通过镜像完成初始化,配置、资源、文件系统已就绪,但未启动,主进程未运行,不占用运行资源。 - 运行状态(Running)
容器已启动,主进程正常运行,Namespace、Cgroups 已生效,容器正常对外提供服务,处于全功能运行状态。 - 暂停状态(Paused)
容器内的所有进程被临时冻结,暂停执行,不释放已分配的资源,不终止进程,可随时恢复运行,适用于临时冻结容器状态的场景。 - 停止状态(Exited)
容器内的主进程已终止运行,Namespace 隔离环境已释放,仅保留容器的可写层数据与配置信息,可重新启动恢复为运行状态。 - 删除状态(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 核心设计理念
- 一次构建,到处运行:核心核心理念,通过镜像打包应用全量运行环境,彻底消除环境差异,实现应用跨环境的无缝交付;
- 基础设施即代码(IaC):通过 Dockerfile 实现镜像构建的代码化、版本化,可纳入 Git 等版本控制系统,实现可追溯、可重复、可自动化的镜像构建;
- 单进程原则:推荐一个容器仅运行一个主进程,职责单一,便于容器的生命周期管理、日志收集、故障排查,符合微服务架构的设计理念;
- 最小化原则:镜像构建遵循最小化原则,仅包含应用运行所需的最小依赖,减小镜像体积,提升分发速度,减少攻击面,提升安全性;
- 不可变基础设施:镜像构建完成后即为不可变的,环境变更需通过重新构建镜像实现,而非修改运行中的容器,保障环境的一致性与可重复性,避免配置漂移。
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 主源码仓库(Moby):https://github.com/moby/moby,适合高阶学习者研究 Docker 底层实现。
- Docker 官方示例仓库 awesome-compose:https://github.com/docker/awesome-compose,提供上百个开箱即用的 Docker Compose 实战配置,覆盖前后端、数据库、AI 应用等全场景,是实战学习的最佳模板。
- Docker Labs:官方交互式实验环境,无需本地安装,在线即可完成容器实操练习,适合零基础快速上手。
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 资源汇总仓库
awesome-docker
- 地址:https://github.com/veggiemonk/awesome-docker
- 亮点:Docker 领域最权威的开源资源汇总,累计超 7 万 Star,收录了上千个 Docker 相关的工具、教程、开源项目、最佳实践、社区资源,覆盖 Docker 全生态,是 Docker 学习的一站式导航。
docker-practice
- 地址:https://github.com/yeasy/docker_practice
- 亮点:《Docker —— 从入门到实践》的开源仓库,配套所有教程的代码、示例、环境配置,可直接下载实操,持续接受社区贡献,保持内容最新。
二、Docker实践
1 Docker安装
1.1 配置软件仓库
[!tip]
注意: 此处采用国内镜像站配置,系统为RHEL Linux
1 | [root@Docker ~]# cat > /etc/yum.repos.d/docker.repo << EOF |
1.2 安装与验证
1 | [root@Docker ~]# dnf makecache |
1.3 网络环境初始化
1 | # 启用 Docker 的 iptables 管理能力 |
1.4 配置国内镜像仓库
1 | [root@Docker ~]# cat > /etc/docker/daemon.json << EOF |
国内可用免费镜像源 (2026/3/16)
| 名称 | 镜像地址 |
|---|---|
| 毫秒镜像 | https://docker.1ms.run |
| 耗子面板 | https://hub.rat.dev |
| DaoCloud | http://docker.m.daocloud.io |
| CNIX Internal | https://docker.m.ixdev.cn |
| 轩辕镜像 | https://docker.xuanyuan.me |
2 Docker相关操作
2.1常用操作
镜像(images) 管理
1
2
3
4
5
6
7
8docker 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
10docker 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
4docker 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 | docker info # 查看 Docker 系统级信息(镜像 / 容器数量、存储驱动、网络配置等) |
2.4 容器生命周期
1 | docker info # 查看 Docker 系统级信息(镜像 / 容器数量、存储驱动、网络配置等) |
2.5 Docker Compose 常用命令
1 | docker compose up -d # 基于 docker-compose.yml 创建并启动所有服务(-d 后台运行) |
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 | 指定执行后续指令的用户 / UID | USER <用户名/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





