diff --git a/01_introduction/1.1_quickstart.md b/01_introduction/1.1_quickstart.md
index 426d392..95dec38 100644
--- a/01_introduction/1.1_quickstart.md
+++ b/01_introduction/1.1_quickstart.md
@@ -2,7 +2,7 @@
本节将通过一个简单的 Web 应用例子,带你快速体验 Docker 的核心流程:构建镜像、运行容器。
-### 1。准备代码
+### 1.1.1 。准备代码
创建一个名为 `hello-docker` 的文件夹,并在其中创建一个 `index.html` 文件:
@@ -10,7 +10,7 @@
Hello, Docker!
```
-### 2。编写 Dockerfile
+### 1.1.2 。编写 Dockerfile
在同级目录下创建一个名为 `Dockerfile` (无后缀) 的文件:
@@ -19,7 +19,7 @@ FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
```
-### 3。构建镜像
+### 1.1.3 。构建镜像
打开终端,进入该目录,执行构建命令:
@@ -31,7 +31,7 @@ $ docker build -t my-hello-world .
* `-t my-hello-world`:给镜像起个名字 (标签)
* `.`:指定上下文路径为当前目录
-### 4。运行容器
+### 1.1.4 。运行容器
使用刚才构建的镜像启动一个容器:
@@ -43,11 +43,11 @@ $ docker run -d -p 8080:80 my-hello-world
* `-d`:后台运行
* `-p 8080:80`:将宿主机的 8080 端口映射到容器的 80 端口
-### 5。访问测试
+### 1.1.5 。访问测试
打开浏览器访问 [http://localhost:8080](http://localhost:8080),你应该能看到 “Hello,Docker!”。
-### 6。清理
+### 1.1.6 。清理
停止并删除容器:
diff --git a/01_introduction/1.2_what.md b/01_introduction/1.2_what.md
index e4c9c1b..322b212 100644
--- a/01_introduction/1.2_what.md
+++ b/01_introduction/1.2_what.md
@@ -2,7 +2,7 @@
Docker 是彻底改变了软件开发和交付方式的革命性技术。本节将从核心概念、与传统虚拟机的对比、技术基础以及历史生态等多个维度,带你深入理解什么是 Docker。
-### 一句话理解 Docker
+### 1.2.1 一句话理解 Docker
> **Docker 是一种轻量级的虚拟化技术,它让应用程序及其依赖环境可以被打包成一个标准化的单元,在任何地方都能一致地运行。** 如果用一个生活中的类比:**Docker 之于软件,就像集装箱之于货物**。
@@ -10,7 +10,7 @@ Docker 是彻底改变了软件开发和交付方式的革命性技术。本节
Docker 做的事情类似:无论你的应用是用 Python、Java、Node.js 还是其他语言写的,无论它需要什么样的依赖库和环境,一旦被打包成 Docker 镜像,就可以用同样的方式在任何支持 Docker 的机器上运行。
-### Docker 的核心价值
+### 1.2.2 Docker 的核心价值
笔者认为,Docker 解决的是软件开发中最古老的问题之一:**“在我机器上明明能跑啊!”**
@@ -42,7 +42,7 @@ flowchart LR
A === "=" === C
```
-### Docker vs 虚拟机
+### 1.2.3 Docker vs 虚拟机
很多人第一次接触 Docker 时会问:**“这不就是虚拟机吗?”** 答案是:**不是,而且差别很大。**
@@ -72,7 +72,7 @@ flowchart LR
> 笔者经常用这个类比来解释:虚拟机像是每个应用都住在一栋独立的房子里 (有自己的地基、水电系统),而容器像是大家住在同一栋公寓楼里的不同房间 (共享地基和水电系统,但各自独立)。
-### Docker 的技术基础
+### 1.2.4 Docker 的技术基础
Docker 使用 [Go 语言](https://golang.google.cn/)开发,基于 Linux 内核的以下技术:
@@ -112,7 +112,7 @@ flowchart LR
> `containerd` 是一个守护程序,它管理容器生命周期,提供了在一个节点上执行容器和管理镜像的最小功能集。
-### Docker 的历史与生态
+### 1.2.5 Docker 的历史与生态
**Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,于 [2013 年 3 月以 Apache 2.0 授权协议开源](https://en.wikipedia.org/wiki/Docker_(software))。
diff --git a/01_introduction/1.3_why.md b/01_introduction/1.3_why.md
index 5932671..abd2b9d 100644
--- a/01_introduction/1.3_why.md
+++ b/01_introduction/1.3_why.md
@@ -2,7 +2,7 @@
在回答 “为什么用 Docker” 之前,笔者想先问一个问题:**你有没有经历过这些场景?**
-### 没有 Docker 的世界
+### 1.3.1 没有 Docker 的世界
在 Docker 出现之前,软件开发和运维面临着诸多棘手的问题。我们先来看看以下三个典型的痛点场景。
@@ -50,7 +50,7 @@
所有人:😱
```
-### Docker 如何解决这些问题
+### 1.3.2 Docker 如何解决这些问题
Docker 的出现为上述问题提供了完美的解决方案。它通过 “一次构建,到处运行” 的核心理念,从根本上改变了软件交付的方式。
@@ -75,7 +75,7 @@ flowchart TD
img3 --> res3["完全一致"]
```
-### Docker 的核心优势
+### 1.3.3 Docker 的核心优势
除了解决上述痛点,Docker 还拥有诸多显著的技术优势,包括环境一致性、秒级启动、高效的资源利用等。
@@ -204,7 +204,7 @@ flowchart TD
end
```
-### Docker 不适合的场景
+### 1.3.4 Docker 不适合的场景
笔者认为,技术选型要客观。Docker 并非银弹,以下场景可能不太适合:
@@ -224,7 +224,7 @@ flowchart TD
Docker 主要面向服务端应用。桌面 GUI 应用的容器化虽然可行,但通常得不偿失。
-### 与传统虚拟机的对比总结
+### 1.3.5 与传统虚拟机的对比总结
相关信息如下表:
diff --git a/01_introduction/summary.md b/01_introduction/summary.md
index e4a2741..4a00678 100644
--- a/01_introduction/summary.md
+++ b/01_introduction/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 1.4 本章小结
- Docker 是一种轻量级虚拟化技术,核心价值是 **环境一致性**
- 与虚拟机相比,Docker 更轻量、更快速、资源利用率更高
diff --git a/02_basic_concept/2.1_image.md b/02_basic_concept/2.1_image.md
index d0e523a..6d71285 100644
--- a/02_basic_concept/2.1_image.md
+++ b/02_basic_concept/2.1_image.md
@@ -2,11 +2,11 @@
Docker 镜像作为容器运行的基石,其设计理念和实现机制至关重要。本节将深入探讨镜像的本质、与操作系统的关系、内容构成以及核心的分层存储机制。
-### 一句话理解镜像
+### 2.1.1 一句话理解镜像
> **Docker 镜像是一个只读的模板,包含了运行应用所需的一切:代码、运行时、库、环境变量和配置文件。** 如果用一个类比:**镜像就像是一张光盘或 ISO 文件**。你可以用同一张光盘在不同电脑上安装系统,而光盘本身不会被修改。同样,一个镜像可以创建多个容器,而镜像本身保持不变。
-### 镜像与操作系统的关系
+### 2.1.2 镜像与操作系统的关系
我们都知道,操作系统分为 **内核** 和 **用户空间**:
@@ -29,7 +29,7 @@ flowchart TD
例如,官方镜像 `ubuntu:24.04` 包含了一套完整的 Ubuntu 24.04 最小系统的 root 文件系统——但 **不包含 Linux 内核** (因为容器共享宿主机的内核)。
-### 镜像包含什么?
+### 2.1.3 镜像包含什么?
Docker 镜像是一个特殊的文件系统,包含:
@@ -44,7 +44,7 @@ Docker 镜像是一个特殊的文件系统,包含:
- ✅ 镜像 **不包含** 动态数据
- ✅ 镜像构建后 **内容不会改变**
-### 分层存储:镜像的核心设计
+### 2.1.4 分层存储:镜像的核心设计
镜像的分层存储机制是 Docker 最具创新性的特性之一。通过 Union FS 技术,Docker 能够高效地构建和管理镜像。
@@ -156,7 +156,7 @@ a6bd71f48f68 2 weeks ago CMD ["nginx" "-g" "daemon off;"] 0B
...
```
-### 镜像的标识
+### 2.1.5 镜像的标识
Docker 镜像有多种标识方式:
@@ -202,7 +202,7 @@ nginx latest sha256:6db391d1c0cfb30588ba0bf72ea999404f2764184d8b8d10d89e8
> 💡 笔者建议:在生产环境使用镜像摘要而非标签,因为标签可以被覆盖,但摘要是不可变的。
-### 镜像的来源
+### 2.1.6 镜像的来源
Docker 镜像可以通过以下方式获取:
diff --git a/02_basic_concept/2.2_container.md b/02_basic_concept/2.2_container.md
index f547ba4..cb87181 100644
--- a/02_basic_concept/2.2_container.md
+++ b/02_basic_concept/2.2_container.md
@@ -2,7 +2,7 @@
容器是 Docker 技术的核心,是应用实际运行的载体。本节将从容器的本质、与虚拟机的区别、存储层机制以及生命周期管理等方面,全面解析 Docker 容器。
-### 一句话理解容器
+### 2.2.1 一句话理解容器
> **容器是镜像的运行实例。如果把镜像比作程序,那么容器就是进程。** 用面向对象编程的术语来说:**镜像是类 (Class),容器是对象 (Instance)**。
@@ -10,7 +10,7 @@
- 每个容器相互独立,互不影响
- 容器可以被创建、启动、停止、删除、暂停
-### 容器的本质
+### 2.2.2 容器的本质
> 💡 **笔者认为,理解这一点是理解 Docker 的关键****容器的本质是一个特殊的进程。**
@@ -29,7 +29,7 @@ flowchart TD
这种隔离是通过 Linux 内核的 **Namespace** 技术实现的。
-### 容器 vs 虚拟机:核心区别
+### 2.2.3 容器 vs 虚拟机:核心区别
很多初学者会混淆容器和虚拟机。笔者用一张图来说明:
@@ -72,7 +72,7 @@ flowchart TD
| **性能损耗** | 几乎为零 | 5-20% |
| **内核** | 共享宿主机内核 | 各自独立内核 |
-### 容器的存储层
+### 2.2.4 容器的存储层
理解容器的存储层机制对于数据的持久化和镜像的优化至关重要。本节将介绍容器的可写层以及 Copy-on-Write 机制。
@@ -144,7 +144,7 @@ $ docker run -v /host/path:/container/path nginx
这些位置的读写 **会跳过容器存储层**,直接写入宿主机,性能更好,也不会随容器删除而丢失。
-### 容器的生命周期
+### 2.2.5 容器的生命周期
掌握容器的生命周期对于管理和调试 Docker 应用非常重要。如图 2-1 所示,容器会经历从创建到删除的完整状态流转。
@@ -200,7 +200,7 @@ $ docker rm abc123 # 删除已停止的容器
$ docker rm -f abc123 # 强制删除运行中的容器
```
-### 容器与进程的关系
+### 2.2.6 容器与进程的关系
> **核心概念**:容器的生命周期 = 主进程 (PID 1) 的生命周期
@@ -225,7 +225,7 @@ $ docker run nginx
详细解释请参考[后台运行](../05_container/5.2_daemon.md)章节。
-### 容器的隔离性
+### 2.2.7 容器的隔离性
Docker 容器通过以下 Namespace 实现隔离:
diff --git a/02_basic_concept/2.3_repository.md b/02_basic_concept/2.3_repository.md
index f3f065c..c2e5f65 100644
--- a/02_basic_concept/2.3_repository.md
+++ b/02_basic_concept/2.3_repository.md
@@ -2,13 +2,13 @@
Docker Registry 是镜像分发和管理的核心组件。本节将介绍 Registry 的基本概念、公共和私有服务的选择,以及镜像的安全管理。
-### 一句话理解 Registry
+### 2.3.1 一句话理解 Registry
> **Docker Registry 是存储和分发 Docker 镜像的服务,类似于代码的 GitHub 或包管理的 npm。**
镜像构建完成后,可以在当前机器上运行。但如果需要在其他服务器上使用这个镜像,就需要一个集中的存储和分发服务——这就是 Docker Registry。
-### 核心概念
+### 2.3.2 核心概念
要熟练使用 Docker Registry,首先需要理清它与仓库 (Repository)、标签 (Tag) 之间的关系。
@@ -88,7 +88,7 @@ gcr.io/google-containers/pause:3.6
> 💡 **笔者提示**:如果不指定 Registry 地址,默认使用 Docker Hub。如果不指定标签,默认使用 `latest`。
-### 公共 Registry 服务
+### 2.3.3 公共 Registry 服务
公共 Registry 服务为开发者提供了便捷的镜像获取途径。其中最著名的是 Docker Hub。
@@ -126,7 +126,7 @@ $ docker push username/myapp:v1.0
| **阿里云容器镜像服务** | registry.cn-*.aliyuncs.com | 国内访问快 |
| **腾讯云容器镜像服务** | ccr.ccs.tencentyun.com | 国内访问快 |
-### 镜像加速器
+### 2.3.4 镜像加速器
由于网络原因,在国内直接访问 Docker Hub 可能会很慢。可以配置 **镜像加速器** (Registry Mirror) 来加速下载。配置示例如下:
@@ -143,7 +143,7 @@ $ docker push username/myapp:v1.0
> ⚠️ **笔者提醒**:镜像加速器的可用性经常变化,使用前建议先测试是否可用。
-### 私有 Registry
+### 2.3.5 私有 Registry
出于安全和隐私的考虑,企业往往需要搭建自己的私有 Registry。以下是几种常见的搭建方案。
@@ -182,7 +182,7 @@ $ docker pull localhost:5000/myapp:v1.0
- 中大型团队:推荐 Harbor,功能完善且开源免费
- 已使用云服务:直接用云厂商的 Registry 服务更省心
-### 镜像的推送和拉取
+### 2.3.6 镜像的推送和拉取
掌握镜像的推送 (Push) 和拉取 (Pull) 是使用 Docker Registry 的基本功。
@@ -235,7 +235,7 @@ $ docker push registry.example.com/myteam/myapp:v1.0
$ docker logout
```
-### 镜像的安全性
+### 2.3.7 镜像的安全性
在使用公共镜像或维护私有镜像时,安全性是不容忽视的重要环节。
diff --git a/02_basic_concept/summary.md b/02_basic_concept/summary.md
index a381c74..6e4912c 100644
--- a/02_basic_concept/summary.md
+++ b/02_basic_concept/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 2.4 本章小结
相关信息如下表:
@@ -11,7 +11,7 @@
理解了镜像,接下来让我们学习[容器](2.2_container.md)——镜像的运行实例。
-### 延伸阅读
+### 2.4.1 延伸阅读
- [获取镜像](../04_image/4.1_pull.md):从 Registry 下载镜像
- [使用 Dockerfile 定制镜像](../04_image/4.5_build.md):创建自己的镜像
@@ -28,7 +28,7 @@
理解了镜像和容器,接下来让我们学习[仓库](2.3_repository.md)——存储和分发镜像的服务。
-### 延伸阅读
+### 2.4.2 延伸阅读
- [启动容器](../05_container/5.1_run.md):详细的容器启动选项
- [后台运行](../05_container/5.2_daemon.md):理解容器为什么会 “立即退出”
@@ -45,7 +45,7 @@
现在你已经了解了 Docker 的三个核心概念:[镜像](2.1_image.md)、[容器](2.2_container.md)和仓库。接下来,让我们开始[安装 Docker](../03_install/README.md),动手实践!
-### 延伸阅读
+### 2.4.3 延伸阅读
- [Docker Hub](../06_repository/6.1_dockerhub.md):Docker Hub 的详细使用
- [私有仓库](../06_repository/6.2_registry.md):搭建私有 Registry
diff --git a/03_install/3.10_experimental.md b/03_install/3.10_experimental.md
index b03eab7..af00b7c 100644
--- a/03_install/3.10_experimental.md
+++ b/03_install/3.10_experimental.md
@@ -2,13 +2,13 @@
一些 docker 命令或功能仅当 **实验特性** 开启时才能使用,请按照以下方法进行设置。
-### Docker CLI 的实验特性
+### 3.10.1 Docker CLI 的实验特性
CLI 的实验特性通常包含仍在开发中的新功能。幸运的是,在较新版本中这些特性已经更加易用。
从 `v20.10` 版本开始,Docker CLI 所有实验特性的命令均默认开启,无需再进行配置或设置系统环境变量。
-### 开启 dockerd 的实验特性
+### 3.10.2 开启 dockerd 的实验特性
编辑 `/etc/docker/daemon.json`,新增如下条目
diff --git a/03_install/3.1_ubuntu.md b/03_install/3.1_ubuntu.md
index a1ddc34..a89cad1 100644
--- a/03_install/3.1_ubuntu.md
+++ b/03_install/3.1_ubuntu.md
@@ -4,7 +4,7 @@ Ubuntu 是 Docker 最常用的运行环境之一。本节将介绍如何在 Ubun
>警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker。
-### 准备工作
+### 3.1.1 准备工作
在开始安装之前,我们需要确认系统版本是否满足要求,并清理可能存在的旧版本。
@@ -37,7 +37,7 @@ do
done
```
-### 使用 APT 安装
+### 3.1.2 使用 APT 安装
由于 `apt` 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。
@@ -100,7 +100,7 @@ $ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io
```
-### 使用脚本自动安装
+### 3.1.3 使用脚本自动安装
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装:
@@ -117,7 +117,7 @@ $ sudo sh get-docker.sh --mirror Aliyun
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定 (stable) 版本安装在系统中。
-### 启动 Docker
+### 3.1.4 启动 Docker
运行以下命令:
@@ -126,7 +126,7 @@ $ sudo systemctl enable docker
$ sudo systemctl start docker
```
-### 建立 docker 用户组
+### 3.1.5 建立 docker 用户组
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
@@ -144,7 +144,7 @@ $ sudo usermod -aG docker $USER
退出当前终端并重新登录,进行如下测试。
-### 测试 Docker 是否安装正确
+### 3.1.6 测试 Docker 是否安装正确
运行以下命令:
@@ -181,10 +181,10 @@ For more examples and ideas, visit:
若能正常输出以上信息,则说明安装成功。
-### 镜像加速
+### 3.1.7 镜像加速
如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。
-### 参考文档
+### 3.1.8 参考文档
* [Docker 官方 Ubuntu 安装文档](https://docs.docker.com/engine/install/ubuntu/)
diff --git a/03_install/3.2_debian.md b/03_install/3.2_debian.md
index 0d3f773..b22844e 100644
--- a/03_install/3.2_debian.md
+++ b/03_install/3.2_debian.md
@@ -4,7 +4,7 @@ Debian 以其稳定性著称,是 Docker 的理想宿主系统。本节将指
>警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker。
-### 准备工作
+### 3.2.1 准备工作
安装前请仔细检查 Debian 版本支持情况,并卸载旧版本以避免冲突。
@@ -26,7 +26,7 @@ $ sudo apt-get remove docker \
docker.io
```
-### 使用 APT 安装
+### 3.2.2 使用 APT 安装
由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改。因此,我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。
@@ -91,7 +91,7 @@ $ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
```
-### 使用脚本自动安装
+### 3.2.3 使用脚本自动安装
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Debian 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装:
@@ -108,7 +108,7 @@ $ sudo sh get-docker.sh --mirror Aliyun
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定 (stable) 版本安装在系统中。
-### 启动 Docker
+### 3.2.4 启动 Docker
运行以下命令:
@@ -117,7 +117,7 @@ $ sudo systemctl enable docker
$ sudo systemctl start docker
```
-### 建立 docker 用户组
+### 3.2.5 建立 docker 用户组
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
@@ -135,7 +135,7 @@ $ sudo usermod -aG docker $USER
退出当前终端并重新登录,进行如下测试。
-### 测试 Docker 是否安装正确
+### 3.2.6 测试 Docker 是否安装正确
运行以下命令:
@@ -172,10 +172,10 @@ For more examples and ideas, visit:
若能正常输出以上信息,则说明安装成功。
-### 镜像加速
+### 3.2.7 镜像加速
如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。
-### 参考文档
+### 3.2.8 参考文档
* [Docker 官方 Debian 安装文档](https://docs.docker.com/engine/install/debian/)
diff --git a/03_install/3.3_fedora.md b/03_install/3.3_fedora.md
index 9b7f641..31abb35 100644
--- a/03_install/3.3_fedora.md
+++ b/03_install/3.3_fedora.md
@@ -4,7 +4,7 @@ Fedora 作为技术前沿的 Linux 发行版,对 Docker 有着良好的支持
>警告:切勿在没有配置 Docker dnf 源的情况下直接使用 dnf 命令安装 Docker。
-### 准备工作
+### 3.3.1 准备工作
确保你的 Fedora 版本在支持列表中,并清理旧版本。
@@ -33,7 +33,7 @@ $ sudo dnf remove docker \
docker-engine
```
-### 使用 dnf 安装
+### 3.3.2 使用 dnf 安装
使用 dnf 包管理器安装是推荐的方式,便于后续的更行和管理。
@@ -99,7 +99,7 @@ docker-ce.x86_64 18.06.1.ce-3.fc28 docker-ce-stable
$ sudo dnf -y install docker-ce-18.06.1.ce
```
-### 使用脚本自动安装
+### 3.3.3 使用脚本自动安装
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Fedora 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装:
@@ -116,7 +116,7 @@ $ sudo sh get-docker.sh --mirror Aliyun
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 最新稳定 (stable) 版本安装在系统中。
-### 启动 Docker
+### 3.3.4 启动 Docker
运行以下命令:
@@ -125,7 +125,7 @@ $ sudo systemctl enable docker
$ sudo systemctl start docker
```
-### 建立 docker 用户组
+### 3.3.5 建立 docker 用户组
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
@@ -143,7 +143,7 @@ $ sudo usermod -aG docker $USER
退出当前终端并重新登录,进行如下测试。
-### 测试 Docker 是否安装正确
+### 3.3.6 测试 Docker 是否安装正确
运行以下命令:
@@ -180,10 +180,10 @@ For more examples and ideas, visit:
若能正常输出以上信息,则说明安装成功。
-### 镜像加速
+### 3.3.7 镜像加速
如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。
-### 参考文档
+### 3.3.8 参考文档
* [Docker 官方 Fedora 安装文档](https://docs.docker.com/engine/install/fedora/)。
diff --git a/03_install/3.4_centos.md b/03_install/3.4_centos.md
index 42cb937..3d66a13 100644
--- a/03_install/3.4_centos.md
+++ b/03_install/3.4_centos.md
@@ -4,7 +4,7 @@ CentOS (及其替代品 Rocky Linux、AlmaLinux) 是企业级服务器常用的
>警告:切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker。
-### 准备工作
+### 3.4.1 准备工作
安装前请确认系统版本和内核版本满足 Docker 的运行要求。
@@ -35,7 +35,7 @@ $ sudo yum remove docker \
containerd.io
```
-### 使用 yum 安装
+### 3.4.2 使用 yum 安装
使用 yum/dnf 安装是管理 Docker 生命周期的标准方式。
@@ -84,7 +84,7 @@ $ sudo dnf config-manager --set-enabled docker-ce-test
$ sudo dnf install docker-ce docker-ce-cli containerd.io
```
-### CentOS8 额外设置
+### 3.4.3 CentOS8 额外设置
CentOS 8/Stream 默认使用 `nftables`。Docker 在新版本中已提供 `nftables` 实验支持,但在一些环境下仍可能遇到兼容性问题。若你遇到容器网络异常,可以先切换回 `iptables` 后端:
@@ -104,7 +104,7 @@ $ firewall-cmd --permanent --zone=trusted --add-interface=docker0
$ firewall-cmd --reload
```
-### 使用脚本自动安装
+### 3.4.4 使用脚本自动安装
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装:
@@ -121,7 +121,7 @@ $ sudo sh get-docker.sh --mirror Aliyun
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定 (stable) 版本安装在系统中。
-### 启动 Docker
+### 3.4.5 启动 Docker
运行以下命令:
@@ -130,7 +130,7 @@ $ sudo systemctl enable docker
$ sudo systemctl start docker
```
-### 建立 docker 用户组
+### 3.4.6 建立 docker 用户组
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
@@ -148,7 +148,7 @@ $ sudo usermod -aG docker $USER
退出当前终端并重新登录,进行如下测试。
-### 测试 Docker 是否安装正确
+### 3.4.7 测试 Docker 是否安装正确
运行以下命令:
@@ -185,11 +185,11 @@ For more examples and ideas, visit:
若能正常输出以上信息,则说明安装成功。
-### 镜像加速
+### 3.4.8 镜像加速
如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。
-### 添加内核参数
+### 3.4.9 添加内核参数
如果在 CentOS 使用 Docker 看到下面的这些警告信息:
@@ -213,7 +213,7 @@ EOF
$ sudo sysctl -p
```
-### 参考文档
+### 3.4.10 参考文档
* [Docker 官方 CentOS 安装文档](https://docs.docker.com/engine/install/centos/)。
* https://firewalld.org/2018/07/nftables-backend
diff --git a/03_install/3.5_raspberry-pi.md b/03_install/3.5_raspberry-pi.md
index 2234d72..317b004 100644
--- a/03_install/3.5_raspberry-pi.md
+++ b/03_install/3.5_raspberry-pi.md
@@ -4,7 +4,7 @@
>警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker。
-### 系统要求
+### 3.5.1 系统要求
Docker 对 ARM 架构有着良好的支持。
@@ -18,7 +18,7 @@ Docker 支持以下版本的 [Raspberry Pi OS](https://www.raspberrypi.org/softw
*注:*`Raspberry Pi OS` 由树莓派的开发与维护机构[树莓派基金会](https://www.raspberrypi.org/)官方支持,并推荐用作树莓派的首选系统,其基于 `Debian`。
-### 使用 APT 安装
+### 3.5.2 使用 APT 安装
推荐使用 APT 包管理器进行安装,以确保版本的稳定性和安全性。
@@ -114,7 +114,7 @@ $ sudo apt-get update
$ sudo apt-get install docker-ce
```
-### 使用脚本自动安装
+### 3.5.3 使用脚本自动安装
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Raspberry Pi OS 系统上可以使用这套脚本安装,另外可以通过 `--mirror` 选项使用国内源进行安装:
@@ -131,7 +131,7 @@ $ sudo sh get-docker.sh --mirror Aliyun
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 的稳定 (stable) 版本安装在系统中。
-### 启动 Docker
+### 3.5.4 启动 Docker
运行以下命令:
@@ -140,7 +140,7 @@ $ sudo systemctl enable docker
$ sudo systemctl start docker
```
-### 建立 docker 用户组
+### 3.5.5 建立 docker 用户组
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好地做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
@@ -158,7 +158,7 @@ $ sudo usermod -aG docker $USER
退出当前终端并重新登录,进行如下测试。
-### 测试 Docker 是否安装正确
+### 3.5.6 测试 Docker 是否安装正确
运行以下命令:
@@ -197,6 +197,6 @@ For more examples and ideas, visit:
*注意:*ARM 平台不能使用 `x86` 镜像,查看 Raspberry Pi OS 可使用镜像请访问 [arm32v7](https://hub.docker.com/u/arm32v7/) 或者 [arm64v8](https://hub.docker.com/u/arm64v8/)。
-### 镜像加速
+### 3.5.7 镜像加速
如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。
diff --git a/03_install/3.6_offline.md b/03_install/3.6_offline.md
index 2fc3469..20d757b 100644
--- a/03_install/3.6_offline.md
+++ b/03_install/3.6_offline.md
@@ -8,11 +8,11 @@

-### 概述
+### 3.6.1 概述
总体概述了以下内容。
-### CentOS/Rocky/AlmaLinux 离线安装 Docker
+### 3.6.2 CentOS/Rocky/AlmaLinux 离线安装 Docker
在无法连接外网的安全环境中,离线安装是唯一的选择。本节介绍如何在 RHEL 系发行版中进行离线安装。
diff --git a/03_install/3.7_mac.md b/03_install/3.7_mac.md
index 19abe3a..de7a24c 100644
--- a/03_install/3.7_mac.md
+++ b/03_install/3.7_mac.md
@@ -2,11 +2,11 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 系统要求
+### 3.7.1 系统要求
[Docker Desktop for Mac](https://docs.docker.com/docker-for-mac/) 要求系统最低为 macOS Sonora 14.0 或更高版本,建议升级到最新版本的 macOS。
-### 安装
+### 3.7.2 安装
Docker Desktop 为 Mac 用户提供了无缝的 Docker 体验。你可以选择使用 Homebrew 或手动下载安装包进行安装。
@@ -28,7 +28,7 @@ $ brew install --cask docker

-### 运行
+### 3.7.3 运行
从应用中找到 Docker 图标并点击运行。
@@ -66,10 +66,10 @@ $ docker stop webserver
$ docker rm webserver
```
-### 镜像加速
+### 3.7.4 镜像加速
如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。
-### 参考链接
+### 3.7.5 参考链接
* [官方文档](https://docs.docker.com/desktop/setup/install/mac-install/)
diff --git a/03_install/3.8_windows.md b/03_install/3.8_windows.md
index 8e2cc88..0e15241 100644
--- a/03_install/3.8_windows.md
+++ b/03_install/3.8_windows.md
@@ -2,11 +2,11 @@
在 Windows 平台上,Docker Desktop 提供了完整的 Docker 开发环境。本节介绍在 Windows 10/11 上的安装和配置。
-### 系统要求
+### 3.8.1 系统要求
[Docker Desktop for Windows](https://docs.docker.com/desktop/setup/install/windows-install/) 支持 64 位版本的 Windows 11 或 Windows 10 (需开启 Hyper-V),推荐使用 Windows 11。
-### 安装
+### 3.8.2 安装
**手动下载安装**
@@ -20,11 +20,11 @@
$ winget install Docker.DockerDesktop
```
-### 在 WSL2 运行 Docker
+### 3.8.3 在 WSL2 运行 Docker
若你的 Windows 版本为 Windows 10 专业版或家庭版 v1903 及以上版本可以使用 WSL2 运行 Docker,具体请查看 [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl/)。
-### 运行
+### 3.8.4 运行
在 Windows 搜索栏输入 **Docker** 点击 **Docker Desktop** 开始运行。
@@ -38,11 +38,11 @@ Docker 启动之后会在 Windows 任务栏出现鲸鱼图标。
> 推荐使用 [Windows Terminal](https://docs.microsoft.com/zh-cn/windows/terminal/get-started) 在终端使用 Docker。
-### 镜像加速
+### 3.8.5 镜像加速
如果在使用过程中发现拉取 Docker 镜像十分缓慢,可以配置 Docker [国内镜像加速](3.9_mirror.md)。
-### 参考链接
+### 3.8.6 参考链接
* [官方文档](https://docs.docker.com/desktop/setup/install/windows-install/)
* [WSL 2 Support is coming to Windows 10 Versions 1903 and 1909](https://devblogs.microsoft.com/commandline/wsl-2-support-is-coming-to-windows-10-versions-1903-and-1909/)
diff --git a/03_install/3.9_mirror.md b/03_install/3.9_mirror.md
index baba30b..373b9d0 100644
--- a/03_install/3.9_mirror.md
+++ b/03_install/3.9_mirror.md
@@ -4,7 +4,7 @@
> ⚠️ **注意**:镜像加速器的可用性经常变化。配置前请先访问 [docker-practice/docker-registry-cn-mirror-test](https://github.com/docker-practice/docker-registry-cn-mirror-test/actions) 查看各镜像站的实时状态。
-### 推荐配置方案
+### 3.9.1 推荐配置方案
针对不同的使用场景,我们推荐以下几种镜像加速配置方案,以确保最佳的拉取速度。
@@ -18,7 +18,7 @@
> `hub.atomgit.com` 仅包含部分官方镜像,可以满足初学者的使用。
-### Ubuntu 22.04+、Debian 12+、Rocky/Alma/CentOS Stream 9+
+### 3.9.2 Ubuntu 22.04+、Debian 12+、Rocky/Alma/CentOS Stream 9+
目前主流 Linux 发行版均已使用 [systemd](https://systemd.io/) 进行服务管理,这里介绍如何在使用 systemd 的 Linux 发行版中配置镜像加速器。
@@ -49,7 +49,7 @@ $ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```
-### Windows 10/11
+### 3.9.3 Windows 10/11
对于使用 `Windows 10/11` 的用户,在任务栏托盘 Docker 图标内右键菜单选择 `Change settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。
@@ -61,7 +61,7 @@ $ sudo systemctl restart docker
}
```
-### macOS
+### 3.9.4 macOS
对于使用 macOS 的用户,在任务栏点击 Docker Desktop 应用图标 -> `Settings...`,在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件。修改完成之后,点击 `Apply & restart` 按钮,Docker 就会重启并应用配置的镜像地址了。
@@ -73,7 +73,7 @@ $ sudo systemctl restart docker
}
```
-### 检查加速器是否生效
+### 3.9.5 检查加速器是否生效
执行 `$ docker info`,如果从结果中看到了如下内容,说明配置成功。
@@ -82,7 +82,7 @@ Registry Mirrors:
https://hub.atomgit.com/
```
-### Kubernetes 官方镜像地址迁移
+### 3.9.6 Kubernetes 官方镜像地址迁移
可以登录[阿里云容器镜像服务](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu&type=copy)**镜像中心**->**镜像搜索** 查找。
@@ -94,7 +94,7 @@ Kubernetes 社区已将官方镜像地址从 `k8s.gcr.io` 迁移到 `registry.k8
$ docker pull registry.k8s.io/xxx
```
-### 不再提供服务的镜像
+### 3.9.7 不再提供服务的镜像
某些镜像不再提供服务,添加无用的镜像加速器,会拖慢镜像拉取速度,你可以从镜像配置列表中删除它们。
@@ -106,7 +106,7 @@ $ docker pull registry.k8s.io/xxx
建议 **watch (页面右上角)** [镜像测试](https://github.com/docker-practice/docker-registry-cn-mirror-test)这个 GitHub 仓库,我们会在此更新各个镜像地址的状态。
-### 云服务商
+### 3.9.8 云服务商
某些云服务商提供了 **仅供内部** 访问的镜像服务,当您的 Docker 运行在云平台时可以选择它们。
diff --git a/04_image/4.1_pull.md b/04_image/4.1_pull.md
index 2625cde..1996943 100644
--- a/04_image/4.1_pull.md
+++ b/04_image/4.1_pull.md
@@ -2,7 +2,7 @@
从 Docker 镜像仓库获取镜像可谓是 Docker 运作的第一步。本节将介绍如何使用 `docker pull` 命令下载镜像,以及如何理解下载过程。
-### docker pull 命令
+### 4.1.1 docker pull 命令
从镜像仓库获取镜像的命令是 `docker pull`:
@@ -61,7 +61,7 @@ $ docker pull ghcr.io/username/myapp:v1.0
---
-### 下载过程解析
+### 4.1.2 下载过程解析
当我们执行 `docker pull` 命令时,Docker 会输出详细的下载进度。让我们以 `ubuntu:24.04` 为例来解析这些信息。
@@ -108,7 +108,7 @@ flowchart TD
---
-### 常用选项
+### 4.1.3 常用选项
`docker pull` 命令支持多种选项来满足不同的下载需求,例如下载所有标签、指定平台架构等。
@@ -132,7 +132,7 @@ $ docker pull --platform linux/amd64 nginx
---
-### 拉取后运行
+### 4.1.4 拉取后运行
拉取镜像后,可以基于它启动容器:
@@ -162,7 +162,7 @@ root@e7009c6ce357:/# exit
---
-### 镜像加速
+### 4.1.5 镜像加速
从 Docker Hub 下载可能较慢。可以配置镜像加速器:
@@ -190,7 +190,7 @@ $ sudo systemctl restart docker # Linux
---
-### 验证镜像完整性
+### 4.1.6 验证镜像完整性
为了确保下载的镜像没有被篡改且内容一致,我们可以校验镜像的摘要 (Digest)。
@@ -216,7 +216,7 @@ $ docker pull ubuntu@sha256:4bc3ae6596938cb0d9e5ac51a1152ec9dcac2a1c50829c74abd9
---
-### 常见问题
+### 4.1.7 常见问题
在使用 `docker pull` 过程中,可能会遇到下载速度慢、镜像不存在或磁盘空间不足等问题。以下是一些常见问题的排查思路。
diff --git a/04_image/4.2_list.md b/04_image/4.2_list.md
index dd817cf..62969b7 100644
--- a/04_image/4.2_list.md
+++ b/04_image/4.2_list.md
@@ -2,7 +2,7 @@
在下载了镜像后,我们可以使用 `docker image ls` 命令列出本地主机上的镜像。
-### 基本用法
+### 4.2.1 基本用法
查看本地已下载的镜像:
@@ -19,7 +19,7 @@ ubuntu noble 329ed837d508 3 days ago 78MB
---
-### 输出字段说明
+### 4.2.2 输出字段说明
`docker image ls` 命令默认输出的列表包含仓库名、标签、镜像 ID、创建时间和占用空间等信息。
@@ -41,7 +41,7 @@ ubuntu noble 329ed837d508 3 days ago 78MB
---
-### 理解镜像大小
+### 4.2.3 理解镜像大小
Docker 镜像的大小可能与我们通常理解的文件大小有所不同,这涉及到分层存储的概念。
@@ -83,7 +83,7 @@ Build Cache 0 0 0B 0B
---
-### 过滤镜像
+### 4.2.4 过滤镜像
随着本地镜像数量的增加,我们需要更有效的方式来查找特定的镜像。Docker 提供了多种过滤方式。
@@ -139,7 +139,7 @@ $ docker images -f label=maintainer=example@email.com
---
-### 虚悬镜像
+### 4.2.5 虚悬镜像
在镜像列表里,你可能会看到一些仓库名和标签都为 `` 的镜像,这类镜像被称为虚悬镜像。
@@ -174,7 +174,7 @@ $ docker image prune
---
-### 中间层镜像
+### 4.2.6 中间层镜像
除了虚悬镜像,`docker image ls` 默认列出的只是顶层镜像。还有一种镜像是为了加速镜像构建、重复利用资源而存在的中间层镜像。
@@ -196,7 +196,7 @@ $ docker images -a
---
-### 格式化输出
+### 4.2.7 格式化输出
为了配合脚本使用或展示更关注的信息,我们可以使用 `--format` 参数来自定义输出格式。
@@ -278,7 +278,7 @@ ubuntu 24.04 78MB
---
-### 常用命令组合
+### 4.2.8 常用命令组合
运行以下命令:
diff --git a/04_image/4.3_rm.md b/04_image/4.3_rm.md
index 4c7a2ec..1a3cefd 100644
--- a/04_image/4.3_rm.md
+++ b/04_image/4.3_rm.md
@@ -2,7 +2,7 @@
当不再需要某个镜像时,我们可以将其删除以释放存储空间。本节介绍删除镜像的常用方法。
-### 基本用法
+### 4.3.1 基本用法
使用 `docker image rm` 删除本地镜像:
@@ -14,7 +14,7 @@ $ docker image rm [选项] <镜像1> [<镜像2> ...]
---
-### 镜像标识方式
+### 4.3.2 镜像标识方式
删除镜像时,可以使用多种方式指定镜像:
@@ -70,7 +70,7 @@ $ docker rmi nginx@sha256:b4f0e0bdeb578043c1ea6862f0d40cc4afe32a4a582f3be235a3b1
---
-### 理解输出信息
+### 4.3.3 理解输出信息
执行删除命令后,Docker 会输出一系列的操作记录,理解这些信息有助于我们掌握镜像删除的机制。
@@ -122,7 +122,7 @@ flowchart TD
---
-### 批量删除
+### 4.3.4 批量删除
手动一个一个删除镜像非常繁琐,Docker 提供了 `image prune` 命令和 shell 组合命令来实现批量清理。
@@ -178,7 +178,7 @@ $ docker image prune -a --filter "until=168h" # 7天前
---
-### 删除失败的常见原因
+### 4.3.5 删除失败的常见原因
在删除镜像时,Docker 可能会提示错误并拒绝执行。这通常是为了防止误删正在使用的资源。
@@ -236,7 +236,7 @@ Error: image has dependent child images
---
-### 常用过滤条件
+### 4.3.6 常用过滤条件
相关信息如下表:
@@ -250,7 +250,7 @@ Error: image has dependent child images
---
-### 清理策略
+### 4.3.7 清理策略
针对不同的环境 (开发环境 vs 生产环境),我们应该采用不同的镜像清理策略。
diff --git a/04_image/4.4_commit.md b/04_image/4.4_commit.md
index d47cb0c..75aa299 100644
--- a/04_image/4.4_commit.md
+++ b/04_image/4.4_commit.md
@@ -120,11 +120,11 @@ docker run --name web2 -d -p 81:80 nginx:v2
至此,我们第一次完成了定制镜像,使用的是 `docker commit` 命令,手动操作给旧的镜像添加了新的一层,形成新的镜像,对镜像多层存储应该有了更直观的感觉。
-### 概述
+### 4.4.1 概述
总体概述了以下内容。
-### 慎用 `docker commit`
+### 4.4.2 慎用 `docker commit`
使用 `docker commit` 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。
diff --git a/04_image/4.5_build.md b/04_image/4.5_build.md
index 4d4c018..00e5148 100644
--- a/04_image/4.5_build.md
+++ b/04_image/4.5_build.md
@@ -4,7 +4,7 @@
Dockerfile 是一个文本文件,其内包含了一条条的 **指令 (Instruction)**,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
-### 使用 docker init 快速创建 (推荐)
+### 4.5.1 使用 docker init 快速创建 (推荐)
Docker 提供了 `docker init` 命令,可以根据项目类型自动生成 Dockerfile、。dockerignore 和 compose.yaml 文件:
@@ -14,7 +14,7 @@ $ docker init
该命令会交互式地询问项目类型 (如 Go、Node.js、Python、Rust 等),并生成符合最佳实践的配置文件。对于新项目,这是推荐的起步方式。
-### 手动创建 Dockerfile
+### 4.5.2 手动创建 Dockerfile
还以之前定制 `nginx` 镜像为例,这次我们使用 Dockerfile 来定制。
@@ -35,7 +35,7 @@ RUN echo 'Hello, Docker!
' > /usr/share/nginx/html/index.html
这个 Dockerfile 很简单,一共就两行。涉及到了两条指令,`FROM` 和 `RUN`。
-### FROM 指定基础镜像
+### 4.5.3 FROM 指定基础镜像
所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 `nginx` 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 `FROM` 就是指定 **基础镜像**,因此一个 `Dockerfile` 中 `FROM` 是必备的指令,并且必须是第一条指令。
@@ -54,7 +54,7 @@ FROM scratch
不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 `FROM scratch` 会让镜像体积更加小巧。使用 [Go 语言](https://golang.google.cn/)开发的应用很多会使用这种方式来制作镜像,这也是有人认为 Go 是特别适合容器微服务架构的语言的原因之一。
-### RUN 执行命令
+### 4.5.4 RUN 执行命令
`RUN` 指令是用来执行命令行命令的。由于命令行的强大能力,`RUN` 指令在定制镜像时是最常用的指令之一。其格式有两种:
@@ -76,7 +76,7 @@ Dockerfile 中每一个指令都会建立一层,`RUN` 也不例外。每一个
要想编写优秀的 `Dockerfile`,必须了解每一条指令的作用和副作用。在 **[第七章 Dockerfile 指令详解](../07_dockerfile/README.md)** 中,我们将对 `COPY`,`ADD`,`CMD`,`ENTRYPOINT` 等指令进行详细讲解。
-### 构建镜像
+### 4.5.5 构建镜像
好了,让我们再回到之前定制的 nginx 镜像的 Dockerfile 来。现在我们明白了这个 Dockerfile 的内容,那么让我们来构建这个镜像吧。
@@ -104,7 +104,7 @@ docker build [选项] <上下文路径/URL/->
在这里我们指定了最终镜像的名称 `-t nginx:v3`,构建成功后,我们可以像之前运行 `nginx:v2` 那样来运行这个镜像,其结果会和 `nginx:v2` 一样。
-### 镜像构建上下文
+### 4.5.6 镜像构建上下文
如果注意,会看到 `docker build` 命令最后有一个 `.`。`.` 表示当前目录,而 `Dockerfile` 就在当前目录,因此不少初学者以为这个路径是在指定 `Dockerfile` 所在路径,这么理解其实是不准确的。如果对应上面的命令格式,你可能会发现,这是在指定 **上下文路径**。那么什么是上下文呢?
@@ -144,7 +144,7 @@ Sending build context to Docker daemon 2.048 kB
当然,一般大家习惯性的会使用默认的文件名 `Dockerfile`,以及会将其置于镜像构建上下文目录中。
-### 其它 `docker build` 的用法
+### 4.5.7 其它 `docker build` 的用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/04_image/4.6_other.md b/04_image/4.6_other.md
index ef0f90e..813a8a2 100644
--- a/04_image/4.6_other.md
+++ b/04_image/4.6_other.md
@@ -2,7 +2,7 @@
除了标准的使用 `Dockerfile` 生成镜像的方法外,由于各种特殊需求和历史原因,还提供了一些其它方法用以生成镜像。
-### 从 rootfs 压缩包导入
+### 4.6.1 从 rootfs 压缩包导入
格式:`docker import [选项] <文件>||- [<仓库名>[:<标签>]]`
@@ -37,7 +37,7 @@ IMAGE CREATED CREATED BY SIZE
f477a6e18e98 About a minute ago 214.9 MB Imported from http://download.openvz.org/template/precreated/ubuntu-16.04-x86_64.tar.gz
```
-### Docker 镜像的导入和导出 `docker save` 和 `docker load`
+### 4.6.2 Docker 镜像的导入和导出 `docker save` 和 `docker load`
Docker 还提供了 `docker save` 和 `docker load` 命令,用以将镜像保存为一个文件,然后传输到另一个位置上,再加载进来。这是在没有 Docker Registry 时的做法,现在已经不推荐,镜像迁移应该直接使用 Docker Registry,无论是直接使用 Docker Hub 还是使用内网私有 Registry 都可以。
diff --git a/04_image/4.7_internal.md b/04_image/4.7_internal.md
index 7dbfba6..ba790fe 100644
--- a/04_image/4.7_internal.md
+++ b/04_image/4.7_internal.md
@@ -2,7 +2,7 @@
Docker 镜像是怎么实现增量的修改和维护的?为什么容器启动如此之快?这一切都归功于 Docker 的镜像分层存储设计。
-### 镜像与分层存储
+### 4.7.1 镜像与分层存储
在之前的章节中,我们一直强调镜像包含操作系统完整的 `root` 文件系统,其体积往往是庞大的。因此在 Docker 设计时,就充分利用 **Union FS** 的技术,将其设计为分层存储的架构。
@@ -17,7 +17,7 @@ Docker 镜像并不是一个单纯的文件,而是由一组文件系统叠加
* **复用**:如果多个镜像都基于同一个基础镜像 (例如都基于 `ubuntu:24.04`),那么宿主机只需要下载一份 `ubuntu:24.04`,所有镜像都可以共享它。
* **轻量**:镜像仅仅记录了与基础镜像的差异,因此体积非常小。
-### 容器层与读写
+### 4.7.2 容器层与读写
我们要理解的一个关键概念是:**镜像的每一层都是只读的 (Read-only)**。
@@ -48,7 +48,7 @@ flowchart TD
1. **容器删除后数据会丢失**:因为所有的数据修改都保存在最上层的容器层中,容器销毁时,这个层也就随之销毁了。(除非使用了数据卷,详见[数据管理](../08_data_network/README.md))。
2. **镜像不可变**:无论我们在容器里删除了多少文件,基础镜像的体积并不会减小,因为它们依然存在于底层的只读层中。
-### 内容寻址与镜像 ID
+### 4.7.3 内容寻址与镜像 ID
Docker 镜像的每一层都有一个唯一的 ID,这个 ID 是根据该层的内容计算出来的哈希值 (SHA256)。这意味着:
@@ -56,7 +56,7 @@ Docker 镜像的每一层都有一个唯一的 ID,这个 ID 是根据该层的
* **安全性**:确保了镜像内容的完整性,下载过程中如果数据损坏,ID 校验就会失败。
* **去重**:如果两个不同的镜像 (甚至是不同来源的镜像) 包含相同的层 (ID 相同),Docker 引擎在本地只会存储一份,绝不重复下载。
-### 联合文件系统
+### 4.7.4 联合文件系统
Docker 使用联合文件系统 (Union FS) 来实现这种分层挂载。常见的驱动包括 `overlay2` (目前推荐)、`aufs` (早期使用)、`btrfs`、`zfs` 等。
diff --git a/04_image/summary.md b/04_image/summary.md
index 7291ee9..4987283 100644
--- a/04_image/summary.md
+++ b/04_image/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 4.8 本章小结
相关信息如下表:
@@ -9,7 +9,7 @@
| 指定平台 | `docker pull --platform linux/amd64 镜像名` |
| 用摘要拉取 | `docker pull 镜像名@sha256:...` |
-### 延伸阅读
+### 4.8.1 延伸阅读
- [列出镜像](4.2_list.md):查看本地镜像
- [删除镜像](4.3_rm.md):清理本地镜像
@@ -26,7 +26,7 @@
| 自定义格式 | `docker images --format "..."` |
| 查看空间占用 | `docker system df` |
-### 延伸阅读
+### 4.8.2 延伸阅读
- [获取镜像](4.1_pull.md):从 Registry 拉取镜像
- [删除镜像](4.3_rm.md):清理本地镜像
@@ -41,7 +41,7 @@
| 批量删除 | `docker rmi $(docker images -q -f ...)` |
| 查看空间占用 | `docker system df` |
-### 延伸阅读
+### 4.8.3 延伸阅读
- [列出镜像](4.2_list.md):查看和过滤镜像
- [删除容器](../05_container/5.6_rm.md):清理容器
diff --git a/05_container/5.1_run.md b/05_container/5.1_run.md
index 1412038..ded0bd8 100644
--- a/05_container/5.1_run.md
+++ b/05_container/5.1_run.md
@@ -2,7 +2,7 @@
本节将详细介绍 Docker 容器的启动方式,包括新建启动和重新启动已停止的容器。
-### 启动方式概述
+### 5.1.1 启动方式概述
启动容器有两种方式:
@@ -11,7 +11,7 @@
由于 Docker 容器非常轻量,实际使用中常常是随时删除和新建容器,而不是反复重启同一个容器。
-### 新建并启动
+### 5.1.2 新建并启动
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -61,7 +61,7 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr
root@af8bae53bdd3:/# exit # 退出容器
```
-### docker run 的完整流程
+### 5.1.3 docker run 的完整流程
执行 `docker run` 时,Docker 在后台完成以下操作:
@@ -82,7 +82,7 @@ flowchart TD
Step5["5. 命令执行完毕,容器停止"]
```
-### 常用启动选项
+### 5.1.4 常用启动选项
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -161,7 +161,7 @@ $ docker run -m 512m nginx
$ docker run --cpus=1.5 nginx
```
-### 启动已终止容器
+### 5.1.5 启动已终止容器
使用 `docker start` 重新启动已停止的容器:
@@ -181,7 +181,7 @@ $ docker start myubuntu
$ docker start -ai myubuntu
```
-### 容器内进程的特点
+### 5.1.6 容器内进程的特点
容器内只运行指定的应用程序及其必需资源:
@@ -196,7 +196,7 @@ root@ba267838cc1b:/# ps
> 💡 笔者提示:容器内的 PID 1 进程很重要——它是容器的主进程,该进程退出则容器停止。详见[后台运行](5.2_daemon.md)章节。
-### 常见问题
+### 5.1.7 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/05_container/5.2_daemon.md b/05_container/5.2_daemon.md
index b698d48..8871735 100644
--- a/05_container/5.2_daemon.md
+++ b/05_container/5.2_daemon.md
@@ -2,7 +2,7 @@
在生产环境中,我们通常需要容器持续运行,不受终端关闭的影响。本节将深入讲解如何让容器在后台运行,以及理解容器生命周期的核心概念。
-### 核心概念:前台 vs 后台
+### 5.2.1 核心概念:前台 vs 后台
当你在终端运行一个程序时,有两种模式:
@@ -11,7 +11,7 @@
Docker 容器默认是 **前台运行** 的。使用 `-d` (detach) 参数可以让容器在后台运行。
-### 基本使用
+### 5.2.2 基本使用
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -49,7 +49,7 @@ $ docker run -d ubuntu:24.04 /bin/sh -c "while true; do echo hello world; sleep
- 终端立即释放,可以继续执行其他命令
- 输出不会直接显示 (需要用 `docker logs` 查看)
-### 深入理解:容器为什么会 “立即退出”?
+### 5.2.3 深入理解:容器为什么会 “立即退出”?
> **这是初学者最常遇到的困惑。** 理解这个问题,你就理解了 Docker 的核心设计理念。
@@ -97,7 +97,7 @@ flowchart TD
| `docker run -d nginx` 后改了配置 | 配置错误导致 nginx 启动失败 | 查看 `docker logs` |
| 自定义镜像容器启动即退 | Dockerfile 的 CMD 执行完毕 | 确保 CMD 是前台进程 |
-### 查看后台容器
+### 5.2.4 查看后台容器
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -139,7 +139,7 @@ $ docker container ls -a
加上 `-a` 参数可以看到所有容器,包括已停止的。这对于调试 “容器启动即退出” 的问题非常有用。
-### 最佳实践
+### 5.2.5 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -205,7 +205,7 @@ $ docker logs -f myapp
$ docker logs -t myapp
```
-### 常见问题排查
+### 5.2.6 常见问题排查
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -252,7 +252,7 @@ $ docker attach mycontainer
> **注意**:`attach` 会连接到容器的主进程。如果主进程不是交互式的,你可能只能看到输出。使用 `Ctrl+P` `Ctrl+Q` 可以安全退出而不停止容器。
-### 延伸阅读
+### 5.2.7 延伸阅读
- [进入容器](5.4_attach_exec.md):如何进入正在运行的容器执行命令
- [容器日志](../appendix/20.1_best_practices.md):生产环境的日志管理最佳实践
diff --git a/05_container/5.3_stop.md b/05_container/5.3_stop.md
index 34a1a93..a049e0f 100644
--- a/05_container/5.3_stop.md
+++ b/05_container/5.3_stop.md
@@ -2,7 +2,7 @@
本节将介绍如何终止一个运行中的容器,以及几种不同的终止方式及其区别。
-### 终止方式概述
+### 5.3.1 终止方式概述
终止容器有三种方式:
@@ -14,7 +14,7 @@
---
-### docker stop (推荐)
+### 5.3.2 docker stop (推荐)
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -67,7 +67,7 @@ $ docker stop $(docker ps -q)
---
-### docker kill
+### 5.3.3 docker kill
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -104,7 +104,7 @@ $ docker kill -s TERM mycontainer
---
-### 容器自动终止
+### 5.3.4 容器自动终止
容器的生命周期与主进程绑定。主进程退出时,容器自动停止:
@@ -121,7 +121,7 @@ $ docker run ubuntu echo "Hello" # echo 执行完 → 容器停止
---
-### 查看已停止的容器
+### 5.3.5 查看已停止的容器
运行以下命令:
@@ -144,7 +144,7 @@ c5d3a5e8f7b2 nginx "nginx" Up 5 minutes mynginx
---
-### 重新启动容器
+### 5.3.6 重新启动容器
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -176,7 +176,7 @@ $ docker restart -t 30 容器名
---
-### 生命周期状态图
+### 5.3.7 生命周期状态图
具体内容如下:
@@ -198,7 +198,7 @@ stateDiagram-v2
---
-### 批量操作
+### 5.3.8 批量操作
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -228,7 +228,7 @@ $ docker stop $(docker ps -q) && docker container prune -f
---
-### 常见问题
+### 5.3.9 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/05_container/5.4_attach_exec.md b/05_container/5.4_attach_exec.md
index 44f83a3..40edbda 100644
--- a/05_container/5.4_attach_exec.md
+++ b/05_container/5.4_attach_exec.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 为什么需要进入容器
+### 5.4.1 为什么需要进入容器
使用 `-d` 参数启动容器后,容器在后台运行。以下场景需要进入容器内部操作:
@@ -13,7 +13,7 @@
| **检查状态** | 查看进程、网络连接、文件系统 |
| **开发测试** | 交互式测试命令、验证环境 |
-### 两种进入方式
+### 5.4.2 两种进入方式
Docker 提供两种进入容器的命令:
@@ -24,7 +24,7 @@ Docker 提供两种进入容器的命令:
---
-### docker exec (推荐)
+### 5.4.3 docker exec (推荐)
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -121,7 +121,7 @@ root@69d137adef7a:/# # 有提示符
---
-### docker attach (谨慎使用)
+### 5.4.4 docker attach (谨慎使用)
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -197,7 +197,7 @@ CONTAINER ID IMAGE STATUS NAMES
---
-### exec vs attach 对比
+### 5.4.5 exec vs attach 对比
相关信息如下表:
@@ -236,7 +236,7 @@ flowchart LR
---
-### 最佳实践
+### 5.4.6 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -283,7 +283,7 @@ $ docker debug myapp
---
-### 常见问题
+### 5.4.7 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/05_container/5.5_import_export.md b/05_container/5.5_import_export.md
index 89dd6d8..4b96bd2 100644
--- a/05_container/5.5_import_export.md
+++ b/05_container/5.5_import_export.md
@@ -2,7 +2,7 @@
当我们需要迁移容器或者备份容器时,可以使用 Docker 的导入和导出功能。本节将介绍这两个命令的使用方法。
-### 导出容器
+### 5.5.1 导出容器
如果要导出本地某个容器,可以使用 `docker export` 命令。
```bash
@@ -14,7 +14,7 @@ $ docker export 7691a814370e > ubuntu.tar
这样将导出容器快照到本地文件。
-### 导入容器快照
+### 5.5.2 导入容器快照
可以使用 `docker import` 从容器快照文件中再导入为镜像,例如
diff --git a/05_container/5.6_rm.md b/05_container/5.6_rm.md
index 9374b6f..b8adf2f 100644
--- a/05_container/5.6_rm.md
+++ b/05_container/5.6_rm.md
@@ -2,7 +2,7 @@
随着容器的创建和停止,系统中会积累大量的容器。本节将介绍如何删除不再需要的容器,以及如何清理所有停止的容器。
-### 基本用法
+### 5.6.1 基本用法
使用 `docker rm` 删除已停止的容器:
@@ -14,7 +14,7 @@ $ docker rm 容器名或ID
---
-### 删除选项
+### 5.6.2 删除选项
相关信息如下表:
@@ -65,7 +65,7 @@ $ docker rm -v mycontainer
---
-### 批量删除
+### 5.6.3 批量删除
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -125,7 +125,7 @@ $ docker container prune --filter "until=24h"
---
-### 常用过滤条件
+### 5.6.4 常用过滤条件
`docker ps` 的过滤条件可以配合 `rm` 使用:
@@ -158,7 +158,7 @@ $ docker rm $(docker ps -aq -f status=created)
---
-### 容器与镜像的依赖关系
+### 5.6.5 容器与镜像的依赖关系
> 有容器依赖的镜像无法删除。
@@ -176,7 +176,7 @@ $ docker image rm nginx
---
-### 清理策略建议
+### 5.6.6 清理策略建议
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -235,7 +235,7 @@ docker system df
---
-### 常见问题
+### 5.6.7 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/05_container/summary.md b/05_container/summary.md
index 86cc5b8..bba3de8 100644
--- a/05_container/summary.md
+++ b/05_container/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 5.7 本章小结
相关信息如下表:
@@ -9,7 +9,7 @@
| 后台运行 | `docker run -d` | 用于服务类应用 |
| 启动已停止的容器 | `docker start` | 重用已有容器 |
-### 延伸阅读
+### 5.7.1 延伸阅读
- [后台运行](5.2_daemon.md):理解 `-d` 参数和容器生命周期
- [进入容器](5.4_attach_exec.md):操作运行中的容器
@@ -24,7 +24,7 @@
| 重启 | `docker restart` | 停止后立即启动 |
| 停止全部 | `docker stop $(docker ps -q)` | 停止所有运行中容器 |
-### 延伸阅读
+### 5.7.2 延伸阅读
- [启动容器](../05_container/5.1_run.md):容器启动详解
- [删除容器](5.6_rm.md):清理容器
@@ -36,7 +36,7 @@
| 执行单条命令 | `docker exec 容器名 命令` |
| 查看主进程输出 | `docker attach 容器名` (慎用)|
-### 延伸阅读
+### 5.7.3 延伸阅读
- [后台运行](5.2_daemon.md):理解容器主进程
- [查看容器](5.1_run.md):列出和过滤容器
@@ -50,7 +50,7 @@
| 清理所有已停止容器 | `docker container prune` |
| 删除所有容器 | `docker rm -f $(docker ps -aq)` |
-### 延伸阅读
+### 5.7.4 延伸阅读
- [终止容器](5.3_stop.md):优雅停止容器
- [删除镜像](../04_image/4.3_rm.md):清理镜像
diff --git a/06_repository/6.1_dockerhub.md b/06_repository/6.1_dockerhub.md
index 51ff191..e6d6adc 100644
--- a/06_repository/6.1_dockerhub.md
+++ b/06_repository/6.1_dockerhub.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 什么是 Docker Hub
+### 6.1.1 什么是 Docker Hub
Docker Hub 是 Docker 的中央镜像仓库,通过它您可以轻松地分享和获取 Docker 镜像。
@@ -18,7 +18,7 @@ Docker Hub 是 Docker 的中央镜像仓库,通过它您可以轻松地分享
---
-### 核心功能
+### 6.1.2 核心功能
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -70,7 +70,7 @@ $ docker push username/myapp:v1
---
-### 限制与配额
+### 6.1.3 限制与配额
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -95,7 +95,7 @@ $ docker push username/myapp:v1
---
-### 安全最佳实践
+### 6.1.4 安全最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -123,7 +123,7 @@ Docker Hub 会对官方镜像和付费用户的镜像进行安全扫描。在镜
---
-### Webhooks
+### 6.1.5 Webhooks
当镜像被推送时,可以自动触发 HTTP 回调 (例如通知 CI 系统部署)。
@@ -132,7 +132,7 @@ Docker Hub 会对官方镜像和付费用户的镜像进行安全扫描。在镜
---
-### 自动构建
+### 6.1.6 自动构建
> ⚠️ 目前仅限付费用户 (Pro/Team) 使用。
diff --git a/06_repository/6.2_registry.md b/06_repository/6.2_registry.md
index 65d691c..2f398d1 100644
--- a/06_repository/6.2_registry.md
+++ b/06_repository/6.2_registry.md
@@ -6,7 +6,7 @@
[`docker-registry`](https://docs.docker.com/registry/) 是官方提供的工具,可以用于构建私有的镜像仓库。本文内容基于 [`docker-registry`](https://github.com/docker/distribution) v2.x 版本。
-### 安装运行 docker-registry
+### 6.2.1 安装运行 docker-registry
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -33,7 +33,7 @@ $ docker run -d \
registry
```
-### 在私有仓库上传、搜索、下载镜像
+### 6.2.2 在私有仓库上传、搜索、下载镜像
创建好私有仓库之后,就可以使用 `docker tag` 来标记一个镜像,然后推送它到仓库。例如私有仓库地址为 `127.0.0.1:5000`。
@@ -99,7 +99,7 @@ REPOSITORY TAG IMAGE ID CREAT
127.0.0.1:5000/ubuntu:latest latest ba5877dc9bec 6 weeks ago 192.7 MB
```
-### 配置非 https 仓库地址
+### 6.2.3 配置非 https 仓库地址
如果你不想使用 `127.0.0.1:5000` 作为仓库地址,比如想让本网段的其他主机也能把镜像推送到私有仓库。你就得把例如 `192.168.199.100:5000` 这样的内网地址作为私有仓库地址,这时你会发现无法成功推送镜像。
@@ -130,6 +130,6 @@ REPOSITORY TAG IMAGE ID CREAT
>注意:该文件必须符合 `json` 规范,否则 Docker 将不能启动。
-### 其他
+### 6.2.4 其他
对于 Docker Desktop for Windows、Docker Desktop for Mac 在设置中的 `Docker Engine` 中进行编辑,增加和上边一样的字符串即可。
diff --git a/06_repository/6.3_registry_auth.md b/06_repository/6.3_registry_auth.md
index c572175..5315416 100644
--- a/06_repository/6.3_registry_auth.md
+++ b/06_repository/6.3_registry_auth.md
@@ -4,7 +4,7 @@
新建一个文件夹,以下步骤均在该文件夹中进行。
-### 准备站点证书
+### 6.3.1 准备站点证书
如果你拥有一个域名,国内各大云服务商均提供免费的站点证书。你也可以使用 `openssl` 自行签发证书。
@@ -82,7 +82,7 @@ $ openssl x509 -req -days 750 -in "site.csr" -sha256 \
新建 `ssl` 文件夹并将 `docker.domain.com.key` `docker.domain.com.crt` `root-ca.crt` 这三个文件移入,删除其他文件。
-### 配置私有仓库
+### 6.3.2 配置私有仓库
私有仓库默认的配置文件位于 `/etc/docker/registry/config.yml`,我们先在本地编辑 `config.yml`,之后挂载到容器中。
@@ -123,7 +123,7 @@ health:
threshold: 3
```
-### 生成 http 认证文件
+### 6.3.3 生成 http 认证文件
运行以下命令:
@@ -138,7 +138,7 @@ $ docker run --rm \
> 将上面的 `username` `password` 替换为你自己的用户名和密码。
-### 编辑 Docker Compose 配置
+### 6.3.4 编辑 Docker Compose 配置
编辑 `compose.yaml` (或 `docker-compose.yml`) 配置如下:
@@ -156,7 +156,7 @@ volumes:
registry-data:
```
-### 修改 Hosts 文件
+### 6.3.5 修改 Hosts 文件
编辑 `/etc/hosts`
@@ -164,7 +164,7 @@ volumes:
127.0.0.1 docker.domain.com
```
-### 启动
+### 6.3.6 启动
运行以下命令:
@@ -174,7 +174,7 @@ $ docker compose up -d
这样我们就搭建好了一个具有权限认证、TLS 的私有仓库,接下来我们测试其功能是否正常。
-### 测试私有仓库功能
+### 6.3.7 测试私有仓库功能
由于自行签发的 CA 根证书不被系统信任,所以我们需要将 CA 根证书 `ssl/root-ca.crt` 移入 `/etc/docker/certs.d/docker.domain.com` 文件夹中。
@@ -216,6 +216,6 @@ no basic auth credentials
发现会提示没有登录,不能将镜像推送到私有仓库中。
-### 注意事项
+### 6.3.8 注意事项
如果你本机占用了 `443` 端口,你可以配置 [Nginx 代理](https://docs.docker.com/registry/recipes/nginx/),这里不再赘述。
diff --git a/06_repository/6.4_nexus3_registry.md b/06_repository/6.4_nexus3_registry.md
index 31762db..15637be 100644
--- a/06_repository/6.4_nexus3_registry.md
+++ b/06_repository/6.4_nexus3_registry.md
@@ -2,7 +2,7 @@
使用 Docker 官方的 Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry。在企业中把内部的一些工具包放入 `Nexus` 中是比较常见的做法,最新版本 `Nexus3.x` 全面支持 Docker 的私有镜像。所以使用 [`Nexus3.x`](https://www.sonatype.com/product/repository-oss-download) 一个软件来管理 `Docker`,`Maven`,`Yum`,`PyPI` 等是一个明智的选择。
-### 启动 Nexus 容器
+### 6.4.1 启动 Nexus 容器
运行以下命令:
@@ -40,7 +40,7 @@ $ docker exec nexus3 cat /nexus-data/admin.password
登录之后可以点击页面上方的齿轮按钮按照下面的方法进行设置。
-### 创建仓库
+### 6.4.2 创建仓库
创建一个私有仓库的方法:`Repository->Repositories` 点击右边菜单 `Create repository` 选择 `docker (hosted)`
@@ -50,7 +50,7 @@ $ docker exec nexus3 cat /nexus-data/admin.password
其它的仓库创建方法请各位自己摸索,还可以创建一个 `docker (proxy)` 类型的仓库链接到 DockerHub 上。再创建一个 `docker (group)` 类型的仓库把刚才的 `hosted` 与 `proxy` 添加在一起。主机在访问的时候默认下载私有仓库中的镜像,如果没有将链接到 DockerHub 中下载并缓存到 Nexus 中。
-### 添加访问权限
+### 6.4.3 添加访问权限
菜单 `Security->Realms` 把 Docker Bearer Token Realm 移到右边的框中保存。
@@ -58,7 +58,7 @@ $ docker exec nexus3 cat /nexus-data/admin.password
添加用户:菜单 `Security->Users`->`Create local user` 在 `Roles` 选项中选中刚才创建的规则移动到右边的窗口保存。
-### NGINX 反向代理配置
+### 6.4.4 NGINX 反向代理配置
证书的生成请参见 [`私有仓库高级配置`](6.3_registry_auth.md) 里面证书生成一节。
@@ -113,7 +113,7 @@ server {
}
```
-### Docker 主机访问镜像仓库
+### 6.4.5 Docker 主机访问镜像仓库
如果不启用 SSL 加密可以通过[前面章节](6.2_registry.md)的方法添加非 https 仓库地址到 Docker 的配置文件中然后重启 Docker。
diff --git a/06_repository/summary.md b/06_repository/summary.md
index e317a23..e933330 100644
--- a/06_repository/summary.md
+++ b/06_repository/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 6.5 本章小结
相关信息如下表:
@@ -9,11 +9,11 @@
| **安全** | 推荐开启 2FA 并使用 Access Token |
| **自动化** | 支持 Webhooks 和自动构建 |
-### 概述
+### 6.5.1 概述
总体概述了以下内容。
-### 延伸阅读
+### 6.5.2 延伸阅读
- [私有仓库](6.2_registry.md):搭建自己的 Registry
- [镜像加速器](../03_install/3.9_mirror.md):加速下载
diff --git a/07_dockerfile/7.10_workdir.md b/07_dockerfile/7.10_workdir.md
index 0986265..4e96557 100644
--- a/07_dockerfile/7.10_workdir.md
+++ b/07_dockerfile/7.10_workdir.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.10.1 基本语法
如下代码块所示,展示了相关示例:
@@ -14,7 +14,7 @@ WORKDIR <工作目录路径>
---
-### 基本用法
+### 7.10.2 基本用法
如下代码块所示,展示了相关示例:
@@ -28,7 +28,7 @@ COPY . . # 复制到 /app/
---
-### 为什么需要 WORKDIR
+### 7.10.3 为什么需要 WORKDIR
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -73,7 +73,7 @@ RUN echo "hello" > world.txt # 创建 /app/world.txt
---
-### 相对路径
+### 7.10.4 相对路径
WORKDIR 支持相对路径,基于上一个 WORKDIR:
@@ -87,7 +87,7 @@ RUN pwd # 输出 /a/b/c
---
-### 使用环境变量
+### 7.10.5 使用环境变量
如下代码块所示,展示了相关示例:
@@ -100,7 +100,7 @@ RUN pwd # 输出 /app
---
-### 多阶段构建中的 WORKDIR
+### 7.10.6 多阶段构建中的 WORKDIR
如下代码块所示,展示了相关示例:
@@ -123,7 +123,7 @@ COPY --from=builder /build/dist .
---
-### 最佳实践
+### 7.10.7 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -186,7 +186,7 @@ WORKDIR /data
---
-### 与其他指令的关系
+### 7.10.8 与其他指令的关系
相关信息如下表:
@@ -208,7 +208,7 @@ CMD ["./start.sh"] # /app/start.sh
---
-### 运行时覆盖
+### 7.10.9 运行时覆盖
使用 `-w` 参数覆盖工作目录:
diff --git a/07_dockerfile/7.11_user.md b/07_dockerfile/7.11_user.md
index 7d91761..a58fce3 100644
--- a/07_dockerfile/7.11_user.md
+++ b/07_dockerfile/7.11_user.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.11.1 基本语法
如下代码块所示,展示了相关示例:
@@ -15,7 +15,7 @@ USER [:]
---
-### 为什么要使用 USER
+### 7.11.2 为什么要使用 USER
> 笔者强调:以非 root 用户运行容器是最重要的安全实践之一。
@@ -36,7 +36,7 @@ flowchart LR
---
-### 基本用法
+### 7.11.3 基本用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -78,7 +78,7 @@ USER 1001:1001
---
-### 用户必须已存在
+### 7.11.4 用户必须已存在
`USER` 指令只能切换到 **已存在** 的用户:
@@ -124,7 +124,7 @@ RUN addgroup -g 1001 -S appgroup && \
---
-### 运行时切换用户
+### 7.11.5 运行时切换用户
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -176,7 +176,7 @@ exec gosu redis "$@"
---
-### 运行时覆盖用户
+### 7.11.6 运行时覆盖用户
使用 `-u` 或 `--user` 参数:
@@ -192,7 +192,7 @@ $ docker run -u root myimage
---
-### 文件权限处理
+### 7.11.7 文件权限处理
切换用户后,确保应用有权访问文件:
@@ -221,7 +221,7 @@ CMD ["node", "server.js"]
---
-### 最佳实践
+### 7.11.8 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -277,7 +277,7 @@ CMD ["node", "server.js"]
---
-### 常见问题
+### 7.11.9 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.12_healthcheck.md b/07_dockerfile/7.12_healthcheck.md
index 4235655..4b970cc 100644
--- a/07_dockerfile/7.12_healthcheck.md
+++ b/07_dockerfile/7.12_healthcheck.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.12.1 基本语法
如下代码块所示,展示了相关示例:
@@ -15,7 +15,7 @@ HEALTHCHECK NONE
---
-### 为什么需要 HEALTHCHECK
+### 7.12.2 为什么需要 HEALTHCHECK
在没有 HEALTHCHECK 之前,Docker 只能通过 **进程退出码** 来判断容器状态。**问题场景**:
@@ -35,7 +35,7 @@ Starting ──成功──> Healthy ──失败N次──> Unhealthy
---
-### 基本用法
+### 7.12.3 基本用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -70,7 +70,7 @@ HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
---
-### 屏蔽健康检查
+### 7.12.4 屏蔽健康检查
如果基础镜像定义了 HEALTHCHECK,但你不想使用它:
@@ -81,7 +81,7 @@ HEALTHCHECK NONE
---
-### 常见检查脚本
+### 7.12.5 常见检查脚本
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -124,7 +124,7 @@ HEALTHCHECK CMD ["healthcheck.sh"]
---
-### 在 Compose 中使用
+### 7.12.6 在 Compose 中使用
可以在 `compose.yaml` (或 `docker-compose.yml`) 中覆盖或定义健康检查:
@@ -156,7 +156,7 @@ services:
---
-### 查看健康状态
+### 7.12.7 查看健康状态
运行以下命令:
@@ -187,7 +187,7 @@ $ docker inspect --format '{{json .State.Health}}' mycontainer | jq
---
-### 最佳实践
+### 7.12.8 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.13_onbuild.md b/07_dockerfile/7.13_onbuild.md
index d402d72..a7bc508 100644
--- a/07_dockerfile/7.13_onbuild.md
+++ b/07_dockerfile/7.13_onbuild.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.13.1 基本语法
如下代码块所示,展示了相关示例:
@@ -14,7 +14,7 @@ ONBUILD <其它指令>
---
-### 为什么需要 ONBUILD
+### 7.13.2 为什么需要 ONBUILD
`ONBUILD` 主要用于制作 **语言栈基础镜像** 或 **框架基础镜像**。
@@ -60,7 +60,7 @@ FROM my-node-base
---
-### 执行机制
+### 7.13.3 执行机制
如下代码块所示,展示了相关示例:
@@ -75,7 +75,7 @@ FROM 基础镜像 ──build──> 读取基础镜像触发器 ──> 执行
---
-### 常见使用场景
+### 7.13.4 常见使用场景
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -113,7 +113,7 @@ ONBUILD COPY dist/ /usr/share/nginx/html/
---
-### 注意事项
+### 7.13.5 注意事项
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -139,7 +139,7 @@ ONBUILD COPY dist/ /usr/share/nginx/html/
---
-### 最佳实践
+### 7.13.6 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.14_label.md b/07_dockerfile/7.14_label.md
index b02e04b..4aff853 100644
--- a/07_dockerfile/7.14_label.md
+++ b/07_dockerfile/7.14_label.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.14.1 基本语法
如下代码块所示,展示了相关示例:
@@ -14,7 +14,7 @@ LABEL = = ...
---
-### 为什么需要 LABEL
+### 7.14.2 为什么需要 LABEL
1. **版本管理**:记录版本号、构建时间、Git Commit ID
2. **联系信息**:维护者邮箱、文档地址、支持渠道
@@ -23,7 +23,7 @@ LABEL = = ...
---
-### 基本用法
+### 7.14.3 基本用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -51,7 +51,7 @@ LABEL maintainer="user@example.com" \
---
-### 常用标签规范
+### 7.14.4 常用标签规范
为了标准和互操作性,推荐使用 [OCI Image Format Specification](https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys) 定义的标准标签:
@@ -84,7 +84,7 @@ LABEL org.opencontainers.image.authors="yeasy" \
---
-### MAINTAINER 指令 (已废弃)
+### 7.14.5 MAINTAINER 指令 (已废弃)
旧版本的 Dockerfile 中常看到 `MAINTAINER` 指令:
@@ -107,7 +107,7 @@ LABEL org.opencontainers.image.authors="user@example.com"
---
-### 动态标签
+### 7.14.6 动态标签
配合 `ARG` 使用,可以在构建时动态注入标签:
@@ -130,7 +130,7 @@ $ docker build \
---
-### 查看标签
+### 7.14.7 查看标签
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.15_shell.md b/07_dockerfile/7.15_shell.md
index 30ef281..59537ea 100644
--- a/07_dockerfile/7.15_shell.md
+++ b/07_dockerfile/7.15_shell.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.15.1 基本语法
如下代码块所示,展示了相关示例:
@@ -19,7 +19,7 @@ SHELL ["executable", "parameters"]
---
-### 为什么要用 SHELL 指令
+### 7.15.2 为什么要用 SHELL 指令
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -84,7 +84,7 @@ SHELL ["cmd", "/S", "/C"]
---
-### 作用范围
+### 7.15.3 作用范围
`SHELL` 指令可以出现多次,每次只影响其后的指令:
@@ -108,7 +108,7 @@ RUN echo "Using sh again"
---
-### 对其他指令的影响
+### 7.15.4 对其他指令的影响
`SHELL` 影响的是所有使用 **shell 格式** 的指令:
@@ -123,7 +123,7 @@ RUN echo "Using sh again"
---
-### 最佳实践
+### 7.15.5 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.17_multistage_builds.md b/07_dockerfile/7.17_multistage_builds.md
index 3e7ec27..f467390 100644
--- a/07_dockerfile/7.17_multistage_builds.md
+++ b/07_dockerfile/7.17_multistage_builds.md
@@ -2,7 +2,7 @@
在 Docker 17.05 版本之前,我们构建 Docker 镜像时,通常会采用两种方式:
-### 全部放入一个 Dockerfile
+### 7.17.1 全部放入一个 Dockerfile
一种方式是将所有的构建过程包含在一个 `Dockerfile` 中,包括项目及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题:
@@ -49,7 +49,7 @@ CMD ["./app"]
$ docker build -t go/helloworld:1 -f Dockerfile.one .
```
-### 分散到多个 Dockerfile
+### 7.17.2 分散到多个 Dockerfile
另一种方式,就是我们事先在一个 `Dockerfile` 将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要我们编写两个 `Dockerfile` 和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好地规避第一种方式存在的风险,但明显部署过程较复杂。
@@ -118,7 +118,7 @@ go/helloworld 2 f7cf3465432c 22 seconds ago 6.47MB
go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
```
-## 使用多阶段构建
+## 7.17 使用多阶段构建
为解决以上问题,Docker v17.05 开始支持多阶段构建 (`multistage builds`)。使用多阶段构建我们就可以很容易解决前面提到的问题,并且只需要编写一个 `Dockerfile`:
@@ -167,7 +167,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
很明显使用多阶段构建的镜像体积小,同时也完美解决了上边提到的问题。
-### 只构建某一阶段的镜像
+### 7.17.1 只构建某一阶段的镜像
我们可以使用 `as` 来为某一阶段命名,例如
@@ -181,7 +181,7 @@ FROM golang:alpine as builder
$ docker build --target builder -t username/imagename:tag .
```
-### 构建时从其他镜像复制文件
+### 7.17.2 构建时从其他镜像复制文件
上面例子中我们使用 `COPY --from=0 /go/src/github.com/go/helloworld/app .` 从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。
diff --git a/07_dockerfile/7.18_multistage_builds_laravel.md b/07_dockerfile/7.18_multistage_builds_laravel.md
index b1c051f..6c3560f 100644
--- a/07_dockerfile/7.18_multistage_builds_laravel.md
+++ b/07_dockerfile/7.18_multistage_builds_laravel.md
@@ -2,7 +2,7 @@
> 本节适用于 PHP 开发者阅读。`Laravel` 基于 8.x 版本,各个版本的文件结构可能会有差异,请根据实际自行修改。
-### 准备
+### 7.18.1 准备
新建一个 `Laravel` 项目或在已有的 `Laravel` 项目根目录下新建 `Dockerfile` `.dockerignore` `laravel.conf` 文件。
@@ -56,7 +56,7 @@ server {
}
```
-### 前端构建
+### 7.18.2 前端构建
第一阶段进行前端构建。
@@ -77,7 +77,7 @@ RUN set -x ; cd /app \
&& npm run production
```
-### 安装 Composer 依赖
+### 7.18.3 安装 Composer 依赖
第二阶段安装 Composer 依赖。
@@ -97,7 +97,7 @@ RUN set -x ; cd /app \
--prefer-dist
```
-### 整合以上阶段所生成的文件
+### 7.18.4 整合以上阶段所生成的文件
第三阶段对以上阶段生成的文件进行整合。
@@ -123,7 +123,7 @@ RUN set -x ; cd ${LARAVEL_PATH} \
&& php artisan package:discover
```
-### 最后一个阶段构建 NGINX 镜像
+### 7.18.5 最后一个阶段构建 NGINX 镜像
如下代码块所示,展示了相关示例:
@@ -136,7 +136,7 @@ COPY laravel.conf /etc/nginx/conf.d/
COPY --from=laravel ${LARAVEL_PATH}/public ${LARAVEL_PATH}/public
```
-### 构建 Laravel 及 Nginx 镜像
+### 7.18.6 构建 Laravel 及 Nginx 镜像
使用 `docker build` 命令构建镜像。
@@ -146,7 +146,7 @@ $ docker build -t my/laravel --target=laravel .
$ docker build -t my/nginx --target=nginx .
```
-### 启动容器并测试
+### 7.18.7 启动容器并测试
新建 Docker 网络
@@ -170,13 +170,13 @@ $ docker run -dit --rm --network=laravel -p 8080:80 my/nginx
> 也许 Laravel 项目依赖其他外部服务,例如 redis、MySQL,请自行启动这些服务之后再进行测试,本小节不再赘述。
-### 生产环境优化
+### 7.18.8 生产环境优化
本小节内容为了方便测试,将配置文件直接放到了镜像中,实际在使用时 **建议** 将配置文件作为 `config` 或 `secret` 挂载到容器中,请读者自行学习 `Kubernetes` 的相关内容。
由于篇幅所限本小节只是简单列出,更多内容可以参考 https://github.com/khs1994-docker/laravel-demo 项目。
-### 附录
+### 7.18.9 附录
完整的 `Dockerfile` 文件如下。
diff --git a/07_dockerfile/7.1_run.md b/07_dockerfile/7.1_run.md
index bfc162b..224e6a1 100644
--- a/07_dockerfile/7.1_run.md
+++ b/07_dockerfile/7.1_run.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.1.1 基本语法
如下代码块所示,展示了相关示例:
@@ -15,7 +15,7 @@ RUN ["executable", "param1", "param2"]
---
-### 两种格式对比
+### 7.1.2 两种格式对比
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -48,7 +48,7 @@ RUN ["apt-get", "update"]
---
-### 常见最佳实践
+### 7.1.3 常见最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -108,7 +108,7 @@ RUN wget http://url | gzip -d > file
---
-### 常见问题
+### 7.1.4 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -146,7 +146,7 @@ RUN echo $MY_VAR
---
-### 高级技巧
+### 7.1.5 高级技巧
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.2_copy.md b/07_dockerfile/7.2_copy.md
index 0304ab1..9962aad 100644
--- a/07_dockerfile/7.2_copy.md
+++ b/07_dockerfile/7.2_copy.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.2.1 基本语法
如下代码块所示,展示了相关示例:
@@ -15,7 +15,7 @@ COPY [选项] ["<源路径1>", "<源路径2>", ... "<目标路径>"]
---
-### 基本用法
+### 7.2.2 基本用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -69,7 +69,7 @@ src/ /app/src/
---
-### 通配符规则
+### 7.2.3 通配符规则
COPY 支持 Go 的 `filepath.Match` 通配符规则:
@@ -88,7 +88,7 @@ COPY app[0-9].js /app/ # app0.js ~ app9.js
---
-### 目标路径
+### 7.2.4 目标路径
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -122,7 +122,7 @@ COPY settings.json /app/config/
---
-### 修改文件所有者
+### 7.2.5 修改文件所有者
使用 `--chown` 选项设置文件的用户和组:
@@ -144,7 +144,7 @@ COPY --chown=node . /app/
---
-### 保留文件元数据
+### 7.2.6 保留文件元数据
COPY 会保留源文件的元数据:
@@ -161,7 +161,7 @@ COPY start.sh /app/
---
-### COPY vs ADD
+### 7.2.7 COPY vs ADD
相关信息如下表:
@@ -187,7 +187,7 @@ ADD app.tar.gz /app/
---
-### 多阶段构建中的 COPY
+### 7.2.8 多阶段构建中的 COPY
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -229,7 +229,7 @@ COPY --link --from=builder /app/dist /usr/share/nginx/html
---
-### .dockerignore
+### 7.2.9 dockerignore
使用 `.dockerignore` 排除不需要复制的文件:
@@ -252,7 +252,7 @@ Dockerfile
---
-### 最佳实践
+### 7.2.10 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.3_add.md b/07_dockerfile/7.3_add.md
index cda7062..5e7cd9b 100644
--- a/07_dockerfile/7.3_add.md
+++ b/07_dockerfile/7.3_add.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.3.1 基本语法
如下代码块所示,展示了相关示例:
@@ -18,7 +18,7 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
---
-### ADD vs COPY
+### 7.3.2 ADD vs COPY
相关信息如下表:
@@ -34,7 +34,7 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
---
-### 自动解压功能
+### 7.3.3 自动解压功能
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -83,7 +83,7 @@ app.tar.gz 包含: /app/ 目录结果:
---
-### URL 下载功能 (不推荐)
+### 7.3.4 URL 下载功能 (不推荐)
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -131,7 +131,7 @@ RUN curl -fsSL https://example.com/app.tar.gz | tar -xz -C /app
---
-### 修改文件所有者
+### 7.3.5 修改文件所有者
如下代码块所示,展示了相关示例:
@@ -142,7 +142,7 @@ ADD --chown=1000:1000 files/ /app/
---
-### 何时使用 ADD
+### 7.3.6 何时使用 ADD
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -184,7 +184,7 @@ COPY archive.tar.gz /archives/ # ✅ 保持原样
---
-### 缓存行为
+### 7.3.7 缓存行为
ADD 可能导致构建缓存失效:
@@ -210,7 +210,7 @@ ADD app.tar.gz /app/
---
-### 最佳实践
+### 7.3.8 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.4_cmd.md b/07_dockerfile/7.4_cmd.md
index 16db40f..2cc873c 100644
--- a/07_dockerfile/7.4_cmd.md
+++ b/07_dockerfile/7.4_cmd.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 什么是 CMD
+### 7.4.1 什么是 CMD
`CMD` 指令用于指定容器启动时默认执行的命令。它定义了容器的 “主进程”。
@@ -10,7 +10,7 @@
---
-### 语法格式
+### 7.4.2 语法格式
CMD 有三种格式:
@@ -61,7 +61,7 @@ CMD ["sh", "-c", "echo $HOME"]
---
-### exec 格式 vs shell 格式
+### 7.4.3 exec 格式 vs shell 格式
相关信息如下表:
@@ -98,7 +98,7 @@ CMD ["node", "server.js"]
---
-### 运行时覆盖 CMD
+### 7.4.4 运行时覆盖 CMD
`docker run` 后的命令会覆盖 Dockerfile 中的 CMD:
@@ -120,7 +120,7 @@ CMD ["/bin/bash"] + cat /etc/os-release
---
-### 经典错误:容器立即退出
+### 7.4.5 经典错误:容器立即退出
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -164,7 +164,7 @@ CMD ["nginx", "-g", "daemon off;"]
---
-### CMD vs ENTRYPOINT
+### 7.4.6 CMD vs ENTRYPOINT
相关信息如下表:
@@ -208,7 +208,7 @@ $ docker run myimage http://other.com # curl -s http://other.com(参数覆盖
---
-### 最佳实践
+### 7.4.7 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -276,7 +276,7 @@ $ docker run myapp --port 9000
---
-### 常见问题
+### 7.4.8 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.5_entrypoint.md b/07_dockerfile/7.5_entrypoint.md
index 6d7c626..2d13797 100644
--- a/07_dockerfile/7.5_entrypoint.md
+++ b/07_dockerfile/7.5_entrypoint.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 什么是 ENTRYPOINT
+### 7.5.1 什么是 ENTRYPOINT
`ENTRYPOINT` 指定容器启动时运行的入口程序。与 CMD 不同,ENTRYPOINT 定义的命令不会被 `docker run` 的参数覆盖,而是 **接收这些参数**。
@@ -10,7 +10,7 @@
---
-### 语法格式
+### 7.5.2 语法格式
相关信息如下表:
@@ -31,7 +31,7 @@ ENTRYPOINT nginx -g "daemon off;"
---
-### ENTRYPOINT vs CMD
+### 7.5.3 ENTRYPOINT vs CMD
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -88,7 +88,7 @@ $ docker run myimage -v http://other.com # curl -s -v http://other.com ✓
---
-### 场景一:让镜像像命令一样使用
+### 7.5.4 场景一:让镜像像命令一样使用
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -154,7 +154,7 @@ curl -s http://myip.ipip.net -i
---
-### 场景二:启动前的准备工作
+### 7.5.5 场景二:启动前的准备工作
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -219,7 +219,7 @@ docker-entrypoint.sh redis-server docker-entrypoint.sh bash
---
-### 场景三:带参数的应用
+### 7.5.6 场景三:带参数的应用
如下代码块所示,展示了相关示例:
@@ -254,7 +254,7 @@ $ docker run myapp --help
---
-### 覆盖 ENTRYPOINT
+### 7.5.7 覆盖 ENTRYPOINT
使用 `--entrypoint` 参数覆盖:
@@ -274,7 +274,7 @@ $ docker run --entrypoint /bin/cat myimage /etc/os-release
---
-### ENTRYPOINT 与 CMD 组合表
+### 7.5.8 ENTRYPOINT 与 CMD 组合表
相关信息如下表:
@@ -290,7 +290,7 @@ $ docker run --entrypoint /bin/cat myimage /etc/os-release
---
-### 最佳实践
+### 7.5.9 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.6_env.md b/07_dockerfile/7.6_env.md
index 5fa75f6..c6cc13f 100644
--- a/07_dockerfile/7.6_env.md
+++ b/07_dockerfile/7.6_env.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.6.1 基本语法
如下代码块所示,展示了相关示例:
@@ -18,7 +18,7 @@ ENV = = ...
---
-### 基本用法
+### 7.6.2 基本用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -45,7 +45,7 @@ ENV NODE_VERSION=20.10.0 \
---
-### 环境变量的作用
+### 7.6.3 环境变量的作用
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -92,7 +92,7 @@ const dbUrl = process.env.DATABASE_URL;
---
-### 支持环境变量的指令
+### 7.6.4 支持环境变量的指令
以下指令可以使用 `$变量名` 或 `${变量名}` 格式:
@@ -112,7 +112,7 @@ const dbUrl = process.env.DATABASE_URL;
---
-### 运行时覆盖
+### 7.6.5 运行时覆盖
使用 `-e` 或 `--env` 覆盖 Dockerfile 中定义的环境变量:
@@ -148,7 +148,7 @@ DATABASE_URL=postgres://localhost/mydb
---
-### ENV vs ARG
+### 7.6.6 ENV vs ARG
相关信息如下表:
@@ -189,7 +189,7 @@ $ docker build --build-arg NODE_VERSION=18 -t myapp .
---
-### 最佳实践
+### 7.6.7 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -255,7 +255,7 @@ ENV HOST=localhost \
---
-### 常见问题
+### 7.6.8 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.7_arg.md b/07_dockerfile/7.7_arg.md
index 2779255..a39be38 100644
--- a/07_dockerfile/7.7_arg.md
+++ b/07_dockerfile/7.7_arg.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.7.1 基本语法
如下代码块所示,展示了相关示例:
@@ -14,7 +14,7 @@ ARG <参数名>[=<默认值>]
---
-### ARG vs ENV
+### 7.7.2 ARG vs ENV
相关信息如下表:
@@ -37,7 +37,7 @@ ARG <参数名>[=<默认值>]
---
-### 基本用法
+### 7.7.3 基本用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -72,7 +72,7 @@ $ docker build --build-arg NODE_VERSION=18 -t myapp .
---
-### ARG 的作用域
+### 7.7.4 ARG 的作用域
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -130,7 +130,7 @@ RUN echo "Running with Node $NODE_VERSION"
---
-### 常见使用场景
+### 7.7.5 常见使用场景
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -192,7 +192,7 @@ $ docker build --build-arg NPM_TOKEN=xxx .
---
-### 将 ARG 传递给 ENV
+### 7.7.6 将 ARG 传递给 ENV
如果需要在运行时使用 ARG 的值:
@@ -210,7 +210,7 @@ CMD echo "App version: $APP_VERSION"
---
-### 预定义 ARG
+### 7.7.7 预定义 ARG
Docker 提供了一些预定义的 ARG,无需声明即可使用:
@@ -229,7 +229,7 @@ $ docker build --build-arg HTTP_PROXY=http://proxy:8080 .
---
-### 最佳实践
+### 7.7.8 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.8_volume.md b/07_dockerfile/7.8_volume.md
index b780115..c40ab8d 100644
--- a/07_dockerfile/7.8_volume.md
+++ b/07_dockerfile/7.8_volume.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.8.1 基本语法
如下代码块所示,展示了相关示例:
@@ -15,7 +15,7 @@ VOLUME /路径
---
-### 为什么使用 VOLUME
+### 7.8.2 为什么使用 VOLUME
> **核心原则**:容器存储层应该保持无状态,任何运行时数据都应该存储在卷中。
@@ -45,7 +45,7 @@ flowchart LR
---
-### 基本用法
+### 7.8.3 基本用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -69,7 +69,7 @@ VOLUME ["/data", "/logs", "/config"]
---
-### VOLUME 的行为
+### 7.8.4 VOLUME 的行为
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -106,7 +106,7 @@ $ docker run -v /my/data:/var/lib/mysql mysql:8.0
---
-### VOLUME 在构建时的特殊行为
+### 7.8.5 VOLUME 在构建时的特殊行为
> ⚠️ **重要**:VOLUME 之后对该目录的修改会被丢弃!
@@ -143,7 +143,7 @@ VOLUME /data
---
-### 常见使用场景
+### 7.8.6 常见使用场景
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -176,7 +176,7 @@ VOLUME /app/uploads
---
-### 查看 VOLUME 定义
+### 7.8.7 查看 VOLUME 定义
运行以下命令:
@@ -195,7 +195,7 @@ $ docker inspect mycontainer --format '{{json .Mounts}}' | jq
---
-### VOLUME vs docker run -v
+### 7.8.8 VOLUME vs docker run -v
相关信息如下表:
@@ -208,7 +208,7 @@ $ docker inspect mycontainer --format '{{json .Mounts}}' | jq
---
-### 在 Compose 中
+### 7.8.9 在 Compose 中
在 Compose 中配置如下:
@@ -230,7 +230,7 @@ volumes:
---
-### 安全注意事项
+### 7.8.10 安全注意事项
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -259,7 +259,7 @@ $ docker run -v mysql_data:/var/lib/mysql mysql:8.0
---
-### 最佳实践
+### 7.8.11 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/07_dockerfile/7.9_expose.md b/07_dockerfile/7.9_expose.md
index 56f8d27..4098ea1 100644
--- a/07_dockerfile/7.9_expose.md
+++ b/07_dockerfile/7.9_expose.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 基本语法
+### 7.9.1 基本语法
如下代码块所示,展示了相关示例:
@@ -14,7 +14,7 @@ EXPOSE <端口> [<端口>/<协议>...]
---
-### 基本用法
+### 7.9.2 基本用法
如下代码块所示,展示了相关示例:
@@ -35,7 +35,7 @@ EXPOSE 53/udp
---
-### EXPOSE 的作用
+### 7.9.3 EXPOSE 的作用
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -74,7 +74,7 @@ $ docker port $(docker ps -q)
---
-### EXPOSE vs -p
+### 7.9.4 EXPOSE vs -p
相关信息如下表:
@@ -117,7 +117,7 @@ $ docker run -p 8080:80 mynginx
---
-### 常见误解
+### 7.9.5 常见误解
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -158,7 +158,7 @@ $ docker run -p 8080:80 nginx # 2. 映射:宿主机 8080 → 容器 80
---
-### 最佳实践
+### 7.9.6 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -220,7 +220,7 @@ CMD ["node", "server.js"] # 实际监听 3000
---
-### 使用环境变量
+### 7.9.7 使用环境变量
如下代码块所示,展示了相关示例:
@@ -231,7 +231,7 @@ EXPOSE $PORT
---
-### 在 Compose 中
+### 7.9.8 在 Compose 中
在 Compose 中配置如下:
diff --git a/07_dockerfile/summary.md b/07_dockerfile/summary.md
index 7f5c171..5604d21 100644
--- a/07_dockerfile/summary.md
+++ b/07_dockerfile/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 7.19 本章小结
相关信息如下表:
@@ -10,7 +10,7 @@
| **持久性** | 影响后续所有指令,直到下次 WORKDIR |
| **不要用** | `RUN cd /path` (无效)|
-### 延伸阅读
+### 7.19.1 延伸阅读
- [COPY 复制文件](7.2_copy.md):文件复制
- [RUN 执行命令](../04_image/4.5_build.md):执行构建命令
@@ -24,7 +24,7 @@
| **运行时覆盖** | `docker run -u` |
| **切换工具** | 使用 gosu,不用 su/sudo |
-### 延伸阅读
+### 7.19.2 延伸阅读
- [安全](../17_security/README.md):容器安全实践
- [ENTRYPOINT](7.5_entrypoint.md):入口脚本中的用户切换
@@ -38,7 +38,7 @@
| **Compose** | 支持 `condition: service_healthy` 依赖 |
| **注意** | 避免副作用,节省资源 |
-### 延伸阅读
+### 7.19.3 延伸阅读
- [CMD 容器启动命令](7.4_cmd.md):启动主进程
- [Compose 模板文件](../10_compose/10.5_compose_file.md):Compose 中的健康检查
@@ -52,7 +52,7 @@
| **限制** | 只继承一次,不可级联 |
| **规范** | 建议使用 `-onbuild` 标签后缀 |
-### 延伸阅读
+### 7.19.4 延伸阅读
- [COPY 指令](7.2_copy.md):文件复制
- [Dockerfile 最佳实践](../appendix/20.1_best_practices.md):基础镜像设计
@@ -65,7 +65,7 @@
| **弃用** | 不要再使用 `MAINTAINER` |
| **查看** | `docker inspect` |
-### 延伸阅读
+### 7.19.5 延伸阅读
- [OCI 标签规范](https://github.com/opencontainers/image-spec/blob/main/annotations.md)
- [Dockerfile 最佳实践](../appendix/20.1_best_practices.md)
@@ -78,7 +78,7 @@
| **推荐用法** | `SHELL ["/bin/bash", "-o", "pipefail", "-c"]` |
| **影响范围** | 后续所有使用 shell 格式的指令 |
-### 延伸阅读
+### 7.19.6 延伸阅读
- [RUN 指令](../04_image/4.5_build.md):执行命令
- [Dockerfile 最佳实践](../appendix/20.1_best_practices.md):错误处理与调试
@@ -91,7 +91,7 @@
| **陷阱** | `cd` 不持久,环境变量不持久 |
| **进阶** | 使用 Cache Mount 加速构建 |
-### 延伸阅读
+### 7.19.7 延伸阅读
- [CMD 容器启动命令](7.4_cmd.md):容器启动时的命令
- [WORKDIR 指定工作目录](7.10_workdir.md):改变目录
@@ -105,7 +105,7 @@
| 修改所有者 | `COPY --chown=node:node . /app/` |
| 从构建阶段复制 | `COPY --from=builder /app/dist ./` |
-### 延伸阅读
+### 7.19.8 延伸阅读
- [ADD 指令](7.3_add.md):复制和解压
- [WORKDIR 指令](7.10_workdir.md):设置工作目录
@@ -120,7 +120,7 @@
| 从 URL 下载 | `RUN curl` |
| 保持 tar 不解压 | `COPY` |
-### 延伸阅读
+### 7.19.9 延伸阅读
- [COPY 复制文件](7.2_copy.md):基本复制操作
- [多阶段构建](7.17_multistage_builds.md):减少镜像体积
@@ -134,7 +134,7 @@
| **与 ENTRYPOINT** | CMD 作为 ENTRYPOINT 的默认参数 |
| **核心原则** | 应用必须在前台运行 |
-### 延伸阅读
+### 7.19.10 延伸阅读
- [ENTRYPOINT 入口点](7.5_entrypoint.md):固定的启动命令
- [后台运行](../05_container/5.2_daemon.md):容器前台/后台概念
@@ -146,7 +146,7 @@
| ✗ | ✓ | 简单的默认命令 |
| ✓ | ✓ | **推荐**:固定命令 + 可配置参数 |
-### 延伸阅读
+### 7.19.11 延伸阅读
- [CMD 容器启动命令](7.4_cmd.md):默认命令
- [最佳实践](../appendix/20.1_best_practices.md):启动命令设计
@@ -160,7 +160,7 @@
| **与 ARG** | ARG 仅构建时,ENV 持久化到运行时 |
| **安全** | 不要存储敏感信息 |
-### 延伸阅读
+### 7.19.12 延伸阅读
- [ARG 构建参数](7.7_arg.md):构建时变量
- [Compose 环境变量](../10_compose/10.5_compose_file.md):Compose 中的环境变量
@@ -175,7 +175,7 @@
| **vs ENV** | ARG 仅构建时,ENV 构建+运行时 |
| **安全** | 不要存储敏感信息 |
-### 延伸阅读
+### 7.19.13 延伸阅读
- [ENV 设置环境变量](7.6_env.md):运行时环境变量
- [FROM 指令](../04_image/4.5_build.md):基础镜像指定
@@ -189,7 +189,7 @@
| **覆盖方式** | `docker run -v name:/path` |
| **注意** | VOLUME 之后的修改会丢失 |
-### 延伸阅读
+### 7.19.14 延伸阅读
- [数据卷](../08_data_network/data/volume.md):卷的管理和使用
- [挂载主机目录](../08_data_network/data/bind-mounts.md):Bind Mount
@@ -203,7 +203,7 @@
| **外部访问** | 需要 `-p 宿主机端口:容器端口` |
| **语法** | `EXPOSE 80` 或 `EXPOSE 80/tcp` |
-### 延伸阅读
+### 7.19.15 延伸阅读
- [网络配置](../08_data_network/network/README.md):Docker 网络详解
- [端口映射](../08_data_network/network/port_mapping.md):-p 参数详解
diff --git a/08_data_network/data/bind-mounts.md b/08_data_network/data/bind-mounts.md
index 86a7f9a..d5c5eee 100644
--- a/08_data_network/data/bind-mounts.md
+++ b/08_data_network/data/bind-mounts.md
@@ -1,8 +1,8 @@
-## 挂载主机目录
+## 8.3 挂载主机目录
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 什么是绑定挂载
+### 8.3.1 什么是绑定挂载
Bind Mount (绑定挂载) 将 **宿主机的目录或文件** 直接挂载到容器中。容器可以读写宿主机的文件系统。
@@ -23,7 +23,7 @@ flowchart LR
---
-### Bind Mount vs Volume
+### 8.3.2 Bind Mount vs Volume
相关信息如下表:
@@ -55,7 +55,7 @@ flowchart LR
---
-### 基本语法
+### 8.3.3 基本语法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -91,7 +91,7 @@ $ docker run -d \
---
-### 使用场景
+### 8.3.4 使用场景
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -153,7 +153,7 @@ $ docker run --rm -it \
---
-### 只读挂载
+### 8.3.5 只读挂载
防止容器修改宿主机文件:
@@ -180,7 +180,7 @@ touch: /app/config/new.txt: Read-only file system
---
-### 挂载单个文件
+### 8.3.6 挂载单个文件
运行以下命令:
@@ -202,7 +202,7 @@ $ docker run -d \
---
-### 查看挂载信息
+### 8.3.7 查看挂载信息
运行以下命令:
@@ -235,7 +235,7 @@ $ docker inspect mycontainer --format '{{json .Mounts}}' | jq
---
-### 常见问题
+### 8.3.8 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -287,7 +287,7 @@ $ docker run -v /host/path:/container/path:cached myapp
---
-### 最佳实践
+### 8.3.9 最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/08_data_network/data/summary.md b/08_data_network/data/summary.md
index 114b076..18a001c 100644
--- a/08_data_network/data/summary.md
+++ b/08_data_network/data/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 8.5 本章小结
相关信息如下表:
@@ -10,7 +10,7 @@
| **适用场景** | 开发环境、配置文件、日志 |
| **vs Volume** | Bind 更灵活,Volume 更适合生产 |
-### 延伸阅读
+### 8.5.1 延伸阅读
- [数据卷](volume.md):Docker 管理的持久化存储
- [tmpfs 挂载](tmpfs.md):内存临时存储
@@ -25,7 +25,7 @@
| 清理未用 | `docker volume prune` |
| 挂载数据卷 | `-v name:/path` 或 `--mount source=name,target=/path` |
-### 延伸阅读
+### 8.5.2 延伸阅读
- [绑定挂载](bind-mounts.md):挂载宿主机目录
- [tmpfs 挂载](tmpfs.md):内存中的临时存储
diff --git a/08_data_network/data/tmpfs.md b/08_data_network/data/tmpfs.md
index 709a132..38e9ff1 100644
--- a/08_data_network/data/tmpfs.md
+++ b/08_data_network/data/tmpfs.md
@@ -1,14 +1,14 @@
-## tmpfs 挂载
+## 8.4 tmpfs 挂载
`tmpfs` 挂载会把数据放在宿主机内存中,而不是写入容器可写层或数据卷。
-### 适用场景
+### 8.4.1 适用场景
- 临时缓存
- 会话数据
- 不希望落盘的敏感中间文件
-### 基本用法
+### 8.4.2 基本用法
如下代码块所示,展示了相关示例:
@@ -22,13 +22,13 @@ $ docker run --tmpfs /run:rw,noexec,nosuid,size=64m nginx
$ docker run --mount type=tmpfs,destination=/run,tmpfs-size=67108864 nginx
```
-### 注意事项
+### 8.4.3 注意事项
- 容器停止后,`tmpfs` 数据会丢失。
- `tmpfs` 占用宿主机内存,建议显式限制大小。
- 不适合需要持久化的数据。
-### 与 Volume / Bind Mount 对比
+### 8.4.4 与 Volume / Bind Mount 对比
相关信息如下表:
diff --git a/08_data_network/data/volume.md b/08_data_network/data/volume.md
index ceb4207..b97c00d 100644
--- a/08_data_network/data/volume.md
+++ b/08_data_network/data/volume.md
@@ -1,8 +1,8 @@
-## 数据卷
+## 8.2 数据卷
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 为什么需要数据卷
+### 8.2.1 为什么需要数据卷
容器的存储层有一个关键问题:**容器删除后,数据就没了**。
@@ -17,7 +17,7 @@ flowchart LR
---
-### 数据卷的特性
+### 8.2.2 数据卷的特性
相关信息如下表:
@@ -31,7 +31,7 @@ flowchart LR
---
-### 数据卷 vs 容器存储层
+### 8.2.3 数据卷 vs 容器存储层
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -71,7 +71,7 @@ graph TD
---
-### 数据卷基本操作
+### 8.2.4 数据卷基本操作
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -121,7 +121,7 @@ $ docker volume inspect my-vol
---
-### 挂载数据卷
+### 8.2.5 挂载数据卷
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -187,7 +187,7 @@ $ docker run -d \
---
-### 使用场景示例
+### 8.2.6 使用场景示例
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -259,7 +259,7 @@ $ docker run -d \
---
-### 数据卷管理
+### 8.2.7 数据卷管理
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -299,7 +299,7 @@ $ docker volume prune -f
---
-### 数据卷备份与恢复
+### 8.2.8 数据卷备份与恢复
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -362,7 +362,7 @@ echo "Backed up ${VOLUME_NAME} to ${BACKUP_DIR}/${VOLUME_NAME}_${TIMESTAMP}.tar.
---
-### 数据卷 vs 绑定挂载
+### 8.2.9 数据卷 vs 绑定挂载
Docker 有两种主要的数据持久化方式:
@@ -388,7 +388,7 @@ $ docker run -v /host/path:/app/data nginx
---
-### 常见问题
+### 8.2.10 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/08_data_network/network/README.md b/08_data_network/network/README.md
index 326454f..140a9f8 100644
--- a/08_data_network/network/README.md
+++ b/08_data_network/network/README.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-## Docker 网络概述
+## 8.6 Docker 网络概述
Docker 容器需要网络来:
@@ -12,7 +12,7 @@ Docker 容器需要网络来:
Docker 在安装时会自动配置网络基础设施,大多数情况下开箱即用。
-## 默认网络架构
+## 8.6 默认网络架构
Docker 启动时自动创建以下网络组件:
@@ -39,7 +39,7 @@ graph TD
Internet((互联网)) <--> eth0
```
-### 核心组件
+### 8.6.1 核心组件
相关信息如下表:
@@ -50,7 +50,7 @@ graph TD
| **容器 eth0** | 容器内的网卡 |
| **IP 地址** | 自动从 172.17.0.0/16 网段分配 |
-### 数据流向
+### 8.6.2 数据流向
如下代码块所示,展示了相关示例:
@@ -74,7 +74,7 @@ flowchart LR
---
-## Docker 网络类型
+## 8.6 Docker 网络类型
查看默认网络:
@@ -96,11 +96,11 @@ ghi789... none null local
---
-## 用户自定义网络 (推荐)
+## 8.6 用户自定义网络 (推荐)
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 为什么要用自定义网络
+### 8.6.1 为什么要用自定义网络
默认 bridge 网络的局限:
@@ -110,7 +110,7 @@ ghi789... none null local
| 所有容器在同一网络 | 更好的隔离性 |
| 需要 --link (已废弃)| 原生支持服务发现 |
-### 创建自定义网络
+### 8.6.2 创建自定义网络
运行以下命令:
@@ -124,7 +124,7 @@ $ docker network create mynet
$ docker network inspect mynet
```
-### 使用自定义网络
+### 8.6.3 使用自定义网络
运行以下命令:
@@ -141,7 +141,7 @@ PING db (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.083 ms
```
-### 容器名 DNS 解析
+### 8.6.4 容器名 DNS 解析
自定义网络自动提供 DNS 服务:
@@ -155,11 +155,11 @@ flowchart LR
---
-## 容器互联
+## 8.6 容器互联
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 同一网络内的容器
+### 8.6.1 同一网络内的容器
同一自定义网络内的容器可以直接通信:
@@ -178,7 +178,7 @@ $ docker run -d --name app --network app-net myapp
...
```
-### 连接到多个网络
+### 8.6.2 连接到多个网络
一个容器可以连接到多个网络:
@@ -196,7 +196,7 @@ $ docker network connect backend multi-net-container
$ docker inspect multi-net-container --format '{{json .NetworkSettings.Networks}}'
```
-### ⚠️ --link 已废弃
+### 8.6.3 ⚠️ --link 已废弃
运行以下命令:
@@ -214,11 +214,11 @@ $ docker run --network mynet --name app myapp
---
-## 端口映射
+## 8.6 端口映射
容器默认只能在 Docker 网络内访问。要从外部访问容器,需要端口映射:
-### 基本语法
+### 8.6.1 基本语法
运行以下命令:
@@ -228,7 +228,7 @@ $ docker run --network mynet --name app myapp
$ docker run -d -p 8080:80 nginx
```
-### 映射方式
+### 8.6.2 映射方式
相关信息如下表:
@@ -240,7 +240,7 @@ $ docker run -d -p 8080:80 nginx
| `-p 127.0.0.1:8080:80` | 只绑定本地 | 仅本机可访问 |
| `-p 8080:80/udp` | UDP 端口 | UDP 协议 |
-### 查看端口映射
+### 8.6.3 查看端口映射
运行以下命令:
@@ -249,7 +249,7 @@ $ docker port mycontainer
80/tcp -> 0.0.0.0:8080
```
-### 端口映射示意图
+### 8.6.4 端口映射示意图
如下代码块所示,展示了相关示例:
@@ -261,7 +261,7 @@ flowchart TD
---
-## 网络隔离
+## 8.6 网络隔离
不同网络之间默认隔离:
@@ -289,7 +289,7 @@ ping: db: Name or service not known
---
-## 常用命令
+## 8.6 常用命令
运行以下命令:
@@ -325,7 +325,7 @@ $ docker network prune
---
-## 本章小结
+## 8.6 本章小结
相关信息如下表:
@@ -337,7 +337,7 @@ $ docker network prune
| **网络隔离** | 不同网络默认隔离,增强安全性 |
| **--link** | 已废弃,使用自定义网络替代 |
-## 延伸阅读
+## 8.6 延伸阅读
- [配置 DNS](dns.md):自定义 DNS 设置
- [端口映射](port_mapping.md):高级端口配置
diff --git a/08_data_network/network/dns.md b/08_data_network/network/dns.md
index 6e67677..eca8e24 100644
--- a/08_data_network/network/dns.md
+++ b/08_data_network/network/dns.md
@@ -1,8 +1,8 @@
-## 配置 DNS
+## 8.7 配置 DNS
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 容器的 DNS 机制
+### 8.7.1 容器的 DNS 机制
Docker 容器的 DNS 配置有两种情况:
@@ -11,7 +11,7 @@ Docker 容器的 DNS 配置有两种情况:
---
-### 嵌入式 DNS
+### 8.7.2 嵌入式 DNS
这是 Docker 网络最强大的功能之一。在自定义网络中,容器可以通过 “名字” 找到彼此,而不需要知道对方的 IP (因为 IP 可能会变)。
@@ -36,7 +36,7 @@ Docker 守护进程在 `127.0.0.11` 运行了一个 DNS 服务器。容器内的
---
-### 配置 DNS 参数
+### 8.7.3 配置 DNS 参数
如果你需要手动配置容器的 DNS (例如使用内网 DNS 服务器),可以在 `docker run` 中使用以下参数:
@@ -67,7 +67,7 @@ $ docker run -h myweb nginx
---
-### 全局 DNS 配置
+### 8.7.4 全局 DNS 配置
如果希望所有容器都使用特定的 DNS 服务器 (而不是继承宿主机),可以修改 `/etc/docker/daemon.json`:
@@ -84,7 +84,7 @@ $ docker run -h myweb nginx
---
-### 常见问题
+### 8.7.5 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/08_data_network/network/port_mapping.md b/08_data_network/network/port_mapping.md
index 0b454a0..c6bcc93 100644
--- a/08_data_network/network/port_mapping.md
+++ b/08_data_network/network/port_mapping.md
@@ -1,8 +1,8 @@
-## 外部访问容器
+## 8.8 外部访问容器
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 为什么要映射端口
+### 8.8.1 为什么要映射端口
容器运行在自己的隔离网络环境中 (通常是 Bridge 模式)。这意味着:
@@ -21,7 +21,7 @@ flowchart TD
---
-### 端口映射方式
+### 8.8.2 端口映射方式
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -72,7 +72,7 @@ abc123456 0.0.0.0:49153->80/tcp
---
-### 查看端口映射
+### 8.8.3 查看端口映射
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -101,7 +101,7 @@ abc123456 nginx 0.0.0.0:8080->80/tcp web
---
-### 最佳实践与安全
+### 8.8.4 最佳实践与安全
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -139,7 +139,7 @@ $ docker run -d -p 53:53/udp dns-server
---
-### 实现原理
+### 8.8.5 实现原理
Docker 使用 `docker-proxy` 进程 (用户态) 或 `iptables` DNAT 规则 (内核态) 来实现端口转发。
diff --git a/08_data_network/network/summary.md b/08_data_network/network/summary.md
index 50f3738..19df4a4 100644
--- a/08_data_network/network/summary.md
+++ b/08_data_network/network/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 8.9 本章小结
相关信息如下表:
@@ -8,7 +8,7 @@
| **自定义网络** | Docker 嵌入式 DNS | ✅ 支持容器名解析 |
| **手动指定** | 使用 `--dns` | 覆盖默认配置 |
-### 延伸阅读
+### 8.9.1 延伸阅读
- [网络模式](README.md):Docker 网络概览
- [端口映射](port_mapping.md):外部访问
@@ -20,7 +20,7 @@
| **安全性** | 默认监听所有 IP,敏感服务应绑定 `127.0.0.1` |
| **查看** | 使用 `docker port` 或 `docker ps` |
-### 延伸阅读
+### 8.9.2 延伸阅读
- [EXPOSE 指令](../../07_dockerfile/7.9_expose.md):在 Dockerfile 中声明端口
- [网络模式](README.md):Host 模式不需要端口映射
diff --git a/09_buildx/9.1_buildkit.md b/09_buildx/9.1_buildkit.md
index 5c1e0c8..788f694 100644
--- a/09_buildx/9.1_buildkit.md
+++ b/09_buildx/9.1_buildkit.md
@@ -6,7 +6,7 @@
目前,Docker Hub 自动构建已经支持 BuildKit,具体请参考 https://github.com/docker-practice/docker-hub-buildx
-### `Dockerfile` 新增指令详解
+### 9.1.1 `Dockerfile` 新增指令详解
BuildKit 引入了多项新指令,旨在优化构建缓存和安全性。以下将详细介绍这些指令的用法。
@@ -159,12 +159,12 @@ $ ssh-add ~/.ssh/id_rsa
$ docker build -t test --ssh default=$SSH_AUTH_SOCK .
```
-### 使用 `docker compose build` 与 BuildKit
+### 9.1.2 使用 `docker compose build` 与 BuildKit
Docker Compose 同样支持 BuildKit,这使得多服务应用的构建更加高效。
自 Docker 23.0 起,BuildKit 已默认启用,无需额外配置。如果使用旧版本,可设置 `DOCKER_BUILDKIT=1` 环境变量启用。
-### 官方文档
+### 9.1.3 官方文档
* https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md
diff --git a/09_buildx/9.2_buildx.md b/09_buildx/9.2_buildx.md
index e101c32..bb0add3 100644
--- a/09_buildx/9.2_buildx.md
+++ b/09_buildx/9.2_buildx.md
@@ -2,7 +2,7 @@
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 使用
+### 9.2.1 使用
Buildx 的使用非常直观,绝大多数情况下可以替代 `docker build` 命令。
@@ -40,6 +40,6 @@ $ docker buildx build --sbom=true -t myimage .
该命令会在构建结果中包含 SPDX 或 CycloneDX 格式的 SBOM 数据。
-### 官方文档
+### 9.2.2 官方文档
* https://docs.docker.com/engine/reference/commandline/buildx/
diff --git a/09_buildx/9.3_multi-arch-images.md b/09_buildx/9.3_multi-arch-images.md
index 48eedd0..6049772 100644
--- a/09_buildx/9.3_multi-arch-images.md
+++ b/09_buildx/9.3_multi-arch-images.md
@@ -2,7 +2,7 @@
Docker 镜像可以支持多种系统架构,这意味着你可以在 `x86_64`、`arm64` 等不同架构的机器上运行同一个镜像。这是通过一个名为 “manifest list” (或称为 “fat manifest”) 的文件来实现的。
-### Manifest List 是什么?
+### 9.3.1 Manifest List 是什么?
为了理解多架构镜像的原理,我们需要先了解 Manifest List 的概念。
@@ -40,7 +40,7 @@ $ docker manifest inspect hello-world
}
```
-### 使用 `docker buildx` 构建多架构镜像
+### 9.3.2 使用 `docker buildx` 构建多架构镜像
`docker buildx` 是构建多架构镜像的最佳实践工具,它屏蔽了底层的复杂性,提供了一键构建多架构镜像的能力。
@@ -101,7 +101,7 @@ COPY bin/dist-${TARGETOS}-${TARGETARCH} /dist
ENTRYPOINT ["/dist"]
```
-### 使用 `docker manifest` (底层工具)
+### 9.3.3 使用 `docker manifest` (底层工具)
除了 `docker buildx`,我们也可以直接操作 Manifest List 来手动组合不同架构的镜像。
diff --git a/10_compose/10.1_introduction.md b/10_compose/10.1_introduction.md
index 3cc0c60..4c8c1da 100644
--- a/10_compose/10.1_introduction.md
+++ b/10_compose/10.1_introduction.md
@@ -10,11 +10,11 @@
`Compose` 恰好满足了这样的需求。它允许用户通过一个单独的 `compose.yaml` (历史默认名也常见为 `docker-compose.yml`) 模板文件 (YAML 格式) 来定义一组相关联的应用容器为一个项目 (project)。
-### 概述
+### 10.1.1 概述
总体概述了以下内容。
-### 模板文件规范
+### 10.1.2 模板文件规范
Compose 模板文件采用 YAML 格式,扩展名为 `.yml` 或 `.yaml`。
diff --git a/10_compose/10.2_install.md b/10_compose/10.2_install.md
index 654d760..6cb364e 100644
--- a/10_compose/10.2_install.md
+++ b/10_compose/10.2_install.md
@@ -10,7 +10,7 @@
Linux 系统请使用以下介绍的方法安装。
-### Linux
+### 10.2.1 Linux
在 Linux 上,你可以通过下载 Docker Compose CLI 插件 (二进制文件名为 `docker-compose`) 来安装。
@@ -32,7 +32,7 @@ $ curl -SL https://github.com/docker/compose/releases/download/v5.0.2/docker-com
$ chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
```
-### 测试安装
+### 10.2.2 测试安装
运行以下命令:
@@ -41,7 +41,7 @@ $ docker compose version
Docker Compose version v5.0.2
```
-### bash 补全命令
+### 10.2.3 bash 补全命令
运行以下命令:
@@ -49,7 +49,7 @@ Docker Compose version v5.0.2
$ curl -L https://raw.githubusercontent.com/docker/compose/v5.0.2/contrib/completion/bash/docker-compose | sudo tee /etc/bash_completion.d/docker-compose > /dev/null
```
-### 卸载
+### 10.2.4 卸载
如果是二进制包方式安装的,删除二进制文件即可。
diff --git a/10_compose/10.3_usage.md b/10_compose/10.3_usage.md
index 19b1ac8..30b46b7 100644
--- a/10_compose/10.3_usage.md
+++ b/10_compose/10.3_usage.md
@@ -2,7 +2,7 @@
本节将通过一个具体的 Web 应用案例,介绍 Docker Compose 的基本概念和使用方法。
-### 术语
+### 10.3.1 术语
首先介绍几个术语。
@@ -12,7 +12,7 @@
可见,一个项目可以由多个服务 (容器) 关联而成,`Compose` 面向项目进行管理。
-### 场景
+### 10.3.2 场景
最常见的项目是 web 网站,该项目应该包含 web 应用和缓存。
diff --git a/10_compose/10.4_commands.md b/10_compose/10.4_commands.md
index 44ab909..5569a3d 100644
--- a/10_compose/10.4_commands.md
+++ b/10_compose/10.4_commands.md
@@ -2,7 +2,7 @@
Docker Compose 提供了丰富的命令来管理项目和容器。本节将详细介绍这些命令的使用格式和常用选项。
-### 命令对象与格式
+### 10.4.1 命令对象与格式
对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。
@@ -14,7 +14,7 @@ Docker Compose 提供了丰富的命令来管理项目和容器。本节将详
docker compose [-f=...] [options] [COMMAND] [ARGS...]
```
-### 命令选项
+### 10.4.2 命令选项
* `-f, --file FILE` 指定使用的 Compose 模板文件。默认会自动识别 `compose.yaml` (也兼容 `docker-compose.yml` 等),并且可以多次指定。
@@ -24,7 +24,7 @@ docker compose [-f=...] [options] [COMMAND] [ARGS...]
* `-v, --version` 打印版本并退出。
-### 命令使用说明
+### 10.4.3 命令使用说明
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/10_compose/10.5_compose_file.md b/10_compose/10.5_compose_file.md
index f6d60f9..613bc09 100644
--- a/10_compose/10.5_compose_file.md
+++ b/10_compose/10.5_compose_file.md
@@ -20,7 +20,7 @@ services:
下面分别介绍各个指令的用法。
-### `build`
+### 10.5.1 `build`
指定 `Dockerfile` 所在文件夹的路径 (可以是绝对路径,或者相对 Compose 文件的路径)。`Compose` 将会利用它自动构建这个镜像,然后使用这个镜像。
@@ -56,7 +56,7 @@ build:
- corp/web_app:3.14
```
-### `cap_add, cap_drop`
+### 10.5.2 `cap_add, cap_drop`
指定容器的内核能力 (capacity) 分配。
@@ -74,7 +74,7 @@ cap_drop:
- NET_ADMIN
```
-### `command`
+### 10.5.3 `command`
覆盖容器启动后默认执行的命令。
@@ -82,11 +82,11 @@ cap_drop:
command: echo "hello world"
```
-### `configs`
+### 10.5.4 `configs`
`configs` 来自 Compose Specification。它在 Swarm 中是原生对象;在本地 `docker compose` 模式下通常以文件挂载的形式实现,具体能力取决于 Compose 版本与运行平台。
-### `cgroup_parent`
+### 10.5.5 `cgroup_parent`
指定父 `cgroup` 组,意味着将继承该组的资源限制。
@@ -96,7 +96,7 @@ command: echo "hello world"
cgroup_parent: cgroups_1
```
-### `container_name`
+### 10.5.6 `container_name`
指定容器名称。默认将会使用 `项目名称_服务名称_序号` 这样的格式。
@@ -106,11 +106,11 @@ container_name: docker-web-container
>注意:指定容器名称后,该服务将无法进行扩展 (scale),因为 Docker 不允许多个容器具有相同的名称。
-### `deploy`
+### 10.5.7 `deploy`
`deploy` 用于描述副本数、更新策略、资源限制等部署参数。该字段在 Swarm 中支持最完整;在本地 `docker compose up` 场景下通常只有部分字段生效。
-### `devices`
+### 10.5.8 `devices`
指定设备映射关系。
@@ -119,7 +119,7 @@ devices:
- "/dev/ttyUSB1:/dev/ttyUSB0"
```
-### `depends_on`
+### 10.5.9 `depends_on`
解决容器的依赖、启动先后的问题。以下例子中会先启动 `redis` `db` 再启动 `web`
@@ -140,7 +140,7 @@ services:
>注意:`web` 服务不会等待 `redis` `db` “完全启动” 之后才启动。
-### `dns`
+### 10.5.10 `dns`
自定义 `DNS` 服务器。可以是一个值,也可以是一个列表。
@@ -152,7 +152,7 @@ dns:
- 114.114.114.114
```
-### `dns_search`
+### 10.5.11 `dns_search`
配置 `DNS` 搜索域。可以是一个值,也可以是一个列表。
@@ -164,7 +164,7 @@ dns_search:
- domain2.example.com
```
-### `tmpfs`
+### 10.5.12 `tmpfs`
挂载一个 tmpfs 文件系统到容器。
@@ -175,7 +175,7 @@ tmpfs:
- /tmp
```
-### `env_file`
+### 10.5.13 `env_file`
从文件中获取环境变量,可以为单独的文件路径或列表。
@@ -200,7 +200,7 @@ env_file:
PROG_ENV=development
```
-### `environment`
+### 10.5.14 `environment`
设置环境变量。你可以使用数组或字典两种格式。
@@ -222,7 +222,7 @@ environment:
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
```
-### `expose`
+### 10.5.15 `expose`
暴露端口,但不映射到宿主机,只被连接的服务访问。
@@ -234,7 +234,7 @@ expose:
- "8000"
```
-### `external_links`
+### 10.5.16 `external_links`
>注意:不建议使用该指令。
@@ -247,7 +247,7 @@ external_links:
- project_db_1:postgresql
```
-### `extra_hosts`
+### 10.5.17 `extra_hosts`
类似 Docker 中的 `--add-host` 参数,指定额外的 host 名称映射信息。
@@ -264,7 +264,7 @@ extra_hosts:
52.1.157.61 dockerhub
```
-### `healthcheck`
+### 10.5.18 `healthcheck`
通过命令检查容器是否健康运行。
@@ -276,7 +276,7 @@ healthcheck:
retries: 3
```
-### `image`
+### 10.5.19 `image`
指定为镜像名称或镜像 ID。如果镜像在本地不存在,`Compose` 将会尝试拉取这个镜像。
@@ -286,7 +286,7 @@ image: orchardup/postgresql
image: a4bc65fd
```
-### `labels`
+### 10.5.20 `labels`
为容器添加 Docker 元数据 (metadata) 信息。例如可以为容器添加辅助说明信息。
@@ -297,11 +297,11 @@ labels:
com.startupteam.release: "rc3 for v1.0"
```
-### `links`
+### 10.5.21 `links`
>注意:不推荐使用该指令。容器之间应通过 Docker 网络 (networks) 进行互联。
-### `logging`
+### 10.5.22 `logging`
配置日志选项。
@@ -328,7 +328,7 @@ options:
max-file: "10"
```
-### `network_mode`
+### 10.5.23 `network_mode`
设置网络模式。使用和 `docker run` 的 `--network` 参数一样的值。
@@ -340,7 +340,7 @@ network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
```
-### `networks`
+### 10.5.24 `networks`
配置容器连接的网络。
@@ -358,7 +358,7 @@ networks:
other-network:
```
-### `pid`
+### 10.5.25 `pid`
跟主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程 ID 来相互访问和操作。
@@ -366,7 +366,7 @@ networks:
pid: "host"
```
-### `ports`
+### 10.5.26 `ports`
暴露端口信息。
@@ -382,7 +382,7 @@ ports:
*注意:当使用 `HOST:CONTAINER` 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 `YAML` 会自动解析 `xx:yy` 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。*
-### `secrets`
+### 10.5.27 `secrets`
存储敏感数据,例如 `mysql` 服务密码。
@@ -405,7 +405,7 @@ secrets:
external: true
```
-### `security_opt`
+### 10.5.28 `security_opt`
指定容器模板标签 (label) 机制的默认属性 (用户、角色、类型、级别等)。例如配置标签的用户名和角色名。
@@ -415,7 +415,7 @@ security_opt:
- label:role:ROLE
```
-### `stop_signal`
+### 10.5.29 `stop_signal`
设置另一个信号来停止容器。在默认情况下使用的是 SIGTERM 停止容器。
@@ -423,7 +423,7 @@ security_opt:
stop_signal: SIGUSR1
```
-### `sysctls`
+### 10.5.30 `sysctls`
配置容器内核参数。
@@ -437,7 +437,7 @@ sysctls:
- net.ipv4.tcp_syncookies=0
```
-### `ulimits`
+### 10.5.31 `ulimits`
指定容器的 ulimits 限制值。
@@ -451,7 +451,7 @@ sysctls:
hard: 40000
```
-### `volumes`
+### 10.5.32 `volumes`
数据卷所挂载路径设置。可以设置为宿主机路径 (`HOST:CONTAINER`) 或者数据卷名称 (`VOLUME:CONTAINER`),并且可以设置访问模式 (`HOST:CONTAINER:ro`)。
@@ -477,7 +477,7 @@ volumes:
mysql_data:
```
-### 其它指令
+### 10.5.33 其它指令
此外,还有包括 `domainname, entrypoint, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir` 等指令,基本跟 `docker run` 中对应参数的功能一致。
@@ -537,7 +537,7 @@ stdin_open: true
tty: true
```
-### 读取变量
+### 10.5.34 读取变量
Compose 模板文件支持动态读取主机的系统环境变量和当前目录下的 `.env` 文件中的变量。
diff --git a/10_compose/10.6_django.md b/10_compose/10.6_django.md
index 65e8d6f..33d183c 100644
--- a/10_compose/10.6_django.md
+++ b/10_compose/10.6_django.md
@@ -4,7 +4,7 @@
本节将使用 Docker Compose 配置并运行一个 **Django + PostgreSQL** 应用。笔者不仅会介绍具体步骤,还会解释每个配置项的作用,以及开发环境和生产环境的差异。
-### 架构概览
+### 10.6.1 架构概览
在开始之前,先看整体架构 (如图 10-1 所示):
@@ -40,7 +40,7 @@ flowchart TD
- 两个服务通过 Docker Compose 自动创建的网络相互通信
- `web` 服务可以通过服务名 `db` 访问数据库 (Docker 内置 DNS)
-### 准备工作
+### 10.6.2 准备工作
创建一个项目目录并进入:
@@ -50,7 +50,7 @@ $ mkdir django-docker && cd django-docker
我们需要创建三个文件:`Dockerfile`、`requirements.txt` 和 `compose.yaml`。
-### 步骤 1:创建 Dockerfile
+### 10.6.3 步骤 1:创建 Dockerfile
如下代码块所示,展示了相关示例:
@@ -90,7 +90,7 @@ COPY . /code/
> 💡 **笔者建议**:总是将变化频率低的文件先复制,变化频率高的后复制。这样可以最大化利用 Docker 的构建缓存。
-### 步骤 2:创建 requirements.txt
+### 10.6.4 步骤 2:创建 requirements.txt
如下代码块所示,展示了相关示例:
@@ -108,7 +108,7 @@ gunicorn>=21.0,<22.0
| `psycopg[binary]` | PostgreSQL 数据库驱动 (推荐使用 psycopg 3)|
| `gunicorn` | 生产环境 WSGI 服务器 (可选,开发时可不用)|
-### 步骤 3:创建 compose.yaml
+### 10.6.5 步骤 3:创建 compose.yaml
配置如下:
@@ -192,7 +192,7 @@ web:
| `depends_on` + `healthcheck` | 启动顺序 | 确保数据库就绪后 Django 才启动,避免连接错误 |
| `environment` | 环境变量 | 推荐用环境变量管理配置,避免硬编码 |
-### 步骤 4:创建 Django 项目
+### 10.6.6 步骤 4:创建 Django 项目
运行以下命令创建新的 Django 项目:
@@ -225,7 +225,7 @@ django-docker/
> 💡 **Linux 用户注意**:如果遇到权限问题,执行 `sudo chown -R $USER:$USER .`
-### 步骤 5:配置数据库连接
+### 10.6.7 步骤 5:配置数据库连接
修改 `mysite/settings.py`,配置数据库连接:
@@ -252,7 +252,7 @@ ALLOWED_HOSTS = ['*']
在 Docker Compose 中,各服务通过服务名相互访问。Docker 内置的 DNS 会将 `db` 解析为 db 服务容器的 IP 地址。这是 Docker Compose 的核心功能之一。
-### 步骤 6:启动应用
+### 10.6.8 步骤 6:启动应用
运行以下命令:
@@ -275,7 +275,7 @@ web-1 | Starting development server at http://0.0.0.0:8000/
打开浏览器访问 http://localhost:8000,可以看到 Django 欢迎页面!
-### 常用开发命令
+### 10.6.9 常用开发命令
在另一个终端窗口执行:
@@ -299,7 +299,7 @@ $ docker compose exec db psql -U django_user -d django_db
> 💡 笔者建议使用 `exec` 而不是 `run`。`exec` 在已运行的容器中执行命令,`run` 会创建新容器。
-### 常见问题排查
+### 10.6.10 常见问题排查
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -338,7 +338,7 @@ $ docker compose logs db
$ sudo chown -R $USER:$USER .
```
-### 开发 vs 生产:关键差异
+### 10.6.11 开发 vs 生产:关键差异
笔者特别提醒,本节的配置是 **开发环境** 配置。生产环境需要以下调整:
@@ -366,7 +366,7 @@ services:
```
-### 延伸阅读
+### 10.6.12 延伸阅读
- [Compose 模板文件详解](10.5_compose_file.md):深入理解 Compose 文件的所有配置项
- [使用 WordPress](10.8_wordpress.md):另一个 Compose 实战案例
diff --git a/10_compose/10.7_rails.md b/10_compose/10.7_rails.md
index caee3d4..5623b51 100644
--- a/10_compose/10.7_rails.md
+++ b/10_compose/10.7_rails.md
@@ -4,7 +4,7 @@
本节使用 Docker Compose 配置并运行一个 **Rails + PostgreSQL** 应用。
-### 架构概览
+### 10.7.1 架构概览
如图 10-2 所示,Rails 与 PostgreSQL 在同一 Compose 网络中协同工作。
@@ -33,7 +33,7 @@ flowchart TD
图 10-2 Rails + PostgreSQL 的 Compose 架构
-### 准备工作
+### 10.7.2 准备工作
创建项目目录:
@@ -43,7 +43,7 @@ $ mkdir rails-docker && cd rails-docker
需要创建三个文件:`Dockerfile`、`Gemfile` 和 `compose.yaml`。
-### 步骤 1:创建 Dockerfile
+### 10.7.3 步骤 1:创建 Dockerfile
如下代码块所示,展示了相关示例:
@@ -80,7 +80,7 @@ COPY . /myapp
| `nodejs` | Rails Asset Pipeline 需要 |
| 先复制 Gemfile | 只有依赖变化时才重新 `bundle install` |
-### 步骤 2:创建 Gemfile
+### 10.7.4 步骤 2:创建 Gemfile
创建一个初始的 `Gemfile`,稍后会被 `rails new` 覆盖:
@@ -95,7 +95,7 @@ gem 'rails', '~> 7.1'
$ touch Gemfile.lock
```
-### 步骤 3:创建 compose.yaml
+### 10.7.5 步骤 3:创建 compose.yaml
配置如下:
@@ -133,7 +133,7 @@ volumes:
| `depends_on: db` | 确保数据库先启动 |
| `DATABASE_URL` | Rails 12-factor 风格的数据库配置 |
-### 步骤 4:生成 Rails 项目
+### 10.7.6 步骤 4:生成 Rails 项目
使用 `docker compose run` 生成项目骨架:
@@ -160,7 +160,7 @@ compose.yaml bin db public
> ⚠️ **Linux 用户**:如遇权限问题,执行 `sudo chown -R $USER:$USER .`
-### 步骤 5:重新构建镜像
+### 10.7.7 步骤 5:重新构建镜像
由于生成了新的 Gemfile,需要重新构建镜像以安装完整依赖:
@@ -168,7 +168,7 @@ compose.yaml bin db public
$ docker compose build
```
-### 步骤 6:配置数据库连接
+### 10.7.8 步骤 6:配置数据库连接
修改 `config/database.yml`:
@@ -192,7 +192,7 @@ production:
> 💡 使用 `DATABASE_URL` 环境变量配置数据库,符合 12-factor 应用原则,便于在不同环境间切换。
-### 步骤 7:启动应用
+### 10.7.9 步骤 7:启动应用
运行以下命令:
@@ -212,7 +212,7 @@ web-1 | Puma starting in single mode...
web-1 | * Listening on http://0.0.0.0:3000
```
-### 步骤 8:创建数据库
+### 10.7.10 步骤 8:创建数据库
在另一个终端执行:
@@ -224,7 +224,7 @@ Created database 'myapp_test'
访问 http://localhost:3000 查看 Rails 欢迎页面。
-### 常用开发命令
+### 10.7.11 常用开发命令
运行以下命令:
@@ -250,7 +250,7 @@ $ docker compose exec web rails generate scaffold Post title:string body:text
$ docker compose exec web bash
```
-### 常见问题
+### 10.7.12 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -281,7 +281,7 @@ $ docker compose exec web rm -f tmp/pids/server.pid
$ docker compose run --rm web bundle update
```
-### 开发 vs 生产
+### 10.7.13 开发 vs 生产
相关信息如下表:
@@ -292,7 +292,7 @@ $ docker compose run --rm web bundle update
| 静态资源 | 动态编译 | 预编译 (`rails assets:precompile`) |
| 数据库密码 | 明文配置 | 使用 Secrets 管理 |
-### 延伸阅读
+### 10.7.14 延伸阅读
- [使用 Django](10.6_django.md):Python Web 框架实战
- [Compose 模板文件](10.5_compose_file.md):配置详解
diff --git a/10_compose/10.8_wordpress.md b/10_compose/10.8_wordpress.md
index 14a18f2..84f740b 100644
--- a/10_compose/10.8_wordpress.md
+++ b/10_compose/10.8_wordpress.md
@@ -4,7 +4,7 @@ WordPress 是全球最流行的内容管理系统 (CMS)。使用 Docker Compose
---
-### 项目结构
+### 10.8.1 项目结构
如下代码块所示,展示了相关示例:
@@ -18,7 +18,7 @@ wordpress/
---
-### 编写 `compose.yaml`
+### 10.8.2 编写 `compose.yaml`
这是一个生产可用的最小化配置:
@@ -79,7 +79,7 @@ networks:
---
-### 配置文件详解
+### 10.8.3 配置文件详解
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -115,7 +115,7 @@ max_execution_time = 600
---
-### 启动与运行
+### 10.8.4 启动与运行
1. 启动服务:
@@ -134,7 +134,7 @@ $ docker compose logs -f
---
-### 生产环境最佳实践
+### 10.8.5 生产环境最佳实践
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -192,7 +192,7 @@ WordPress 支持 Redis 缓存以提高性能。
---
-### 常见问题
+### 10.8.6 常见问题
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -214,7 +214,7 @@ $ docker compose restart wordpress
---
-### 延伸阅读
+### 10.8.7 延伸阅读
- [Compose 模板文件](10.5_compose_file.md):深入了解配置项
- [数据卷](../08_data_network/data/volume.md):理解数据持久化
diff --git a/11_implementation/18.1_arch.md b/11_implementation/18.1_arch.md
index a32cb1b..2ccac43 100644
--- a/11_implementation/18.1_arch.md
+++ b/11_implementation/18.1_arch.md
@@ -1,8 +1,8 @@
-## 14.1 基本架构
+## 11.1 基本架构
Docker 的架构设计简洁而高效,主要由客户端和服务端两部分组成。
-### 核心架构图
+### 11.1.1 核心架构图
Docker 采用了 **C/S (客户端/服务端)** 架构。Client 向 Daemon 发送请求,Daemon 负责构建、运行和分发容器。
@@ -23,7 +23,7 @@ graph LR
---
-### 组件详解
+### 11.1.2 组件详解
Docker 的内部架构如同洋葱一样分层,每一层专注解决特定问题:
@@ -66,7 +66,7 @@ Docker 的大脑。
---
-### 容器启动流程
+### 11.1.3 容器启动流程
当执行 `docker run -d nginx` 时,内部发生了什么?
@@ -110,7 +110,7 @@ flowchart TD
---
-### Docker Engine v29+ 变化
+### 11.1.4 Docker Engine v29+ 变化
从 Docker Engine v29 (2025/2026) 开始,架构进一步简化和标准化:
@@ -119,7 +119,7 @@ flowchart TD
---
-### Docker Desktop 架构
+### 11.1.5 Docker Desktop 架构
在 macOS 和 Windows 上,因为内核差异,架构稍微复杂:
@@ -140,7 +140,7 @@ flowchart TD
---
-### 总结
+### 11.1.6 总结
相关信息如下表:
@@ -152,7 +152,7 @@ flowchart TD
| **Shim** | 监工 | 保持 IO,允许无守护进程重启 |
| **Runc** | 工人 | 真正干活 (创建容器),干完就走 |
-### 延伸阅读
+### 11.1.7 延伸阅读
- [命名空间](./18.2_namespace.md):Runc 如何隔离容器
- [控制组](./18.3_cgroups.md):Runc 如何限制资源
diff --git a/11_implementation/18.2_namespace.md b/11_implementation/18.2_namespace.md
index c0219c1..b807656 100644
--- a/11_implementation/18.2_namespace.md
+++ b/11_implementation/18.2_namespace.md
@@ -1,6 +1,6 @@
命名空间 (Namespace) 是 Linux 内核的一个强大特性,为容器提供了隔离的运行环境。
-## 什么是 Namespace
+## 11.2 什么是 Namespace
> **Namespace 是 Linux 内核提供的资源隔离机制,它让容器内的进程仿佛运行在独立的操作系统中。** Namespace 是容器技术的核心基础之一。它回答了一个关键问题:**如何让一个进程 “以为” 自己独占整个系统?**
@@ -24,7 +24,7 @@ flowchart LR
H4 -. "(实际是宿主机的 1234)" .- C1
```
-### Namespace 的类型
+### 11.2.1 Namespace 的类型
Linux 内核提供了以下几种 Namespace,Docker 容器使用了全部:
@@ -40,7 +40,7 @@ Linux 内核提供了以下几种 Namespace,Docker 容器使用了全部:
---
-### PID Namespace
+### 11.2.2 PID Namespace
PID Namespace 负责进程 ID 的隔离,使得容器内的进程彼此不可见。
@@ -75,7 +75,7 @@ PID USER COMMAND
---
-### NET Namespace
+### 11.2.3 NET Namespace
NET Namespace 负责网络栈的隔离,包括网卡、路由表和 iptables 规则等。
@@ -112,7 +112,7 @@ flowchart LR
---
-### MNT Namespace
+### 11.2.4 MNT Namespace
MNT Namespace 负责文件系统挂载点的隔离,确保容器看到独立的文件系统视图。
@@ -149,7 +149,7 @@ MNT Namespace 负责文件系统挂载点的隔离,确保容器看到独立的
---
-### UTS Namespace
+### 11.2.5 UTS Namespace
UTS Namespace 主要用于隔离主机名和域名。
@@ -177,7 +177,7 @@ UTS = “UNIX Time-sharing System”,是历史遗留的名称。
---
-### IPC Namespace
+### 11.2.6 IPC Namespace
IPC Namespace 用于隔离进程间通信资源,如 System V IPC 和 POSIX 消息队列。
@@ -198,7 +198,7 @@ IPC Namespace 用于隔离进程间通信资源,如 System V IPC 和 POSIX 消
---
-### USER Namespace
+### 11.2.7 USER Namespace
USER Namespace 允许将容器内的用户 ID 映射到宿主机的不同用户 ID。
@@ -236,7 +236,7 @@ flowchart LR
---
-### 动手实验:体验 Namespace
+### 11.2.8 动手实验:体验 Namespace
使用 `unshare` 命令可以在不使用 Docker 的情况下体验 Namespace:
@@ -301,7 +301,7 @@ $ ip addr
---
-### Namespace 的局限性
+### 11.2.9 Namespace 的局限性
Namespace 提供了隔离但不是安全边界:
diff --git a/11_implementation/18.3_cgroups.md b/11_implementation/18.3_cgroups.md
index 5f003a6..d0ec9b3 100644
--- a/11_implementation/18.3_cgroups.md
+++ b/11_implementation/18.3_cgroups.md
@@ -1,8 +1,8 @@
-## 14.3 控制组
+## 11.3 控制组
控制组 (Cgroups) 是 Linux 内核提供的另一种关键机制,主要用于资源的限制和审计。
-### 什么是控制组
+### 11.3.1 什么是控制组
控制组 (Control Groups,简称 cgroups) 是 Linux 内核的一个特性,用于 **限制、记录和隔离** 进程组的资源使用 (CPU、内存、磁盘 I/O、网络等)。
@@ -31,7 +31,7 @@ flowchart LR
---
-### cgroups 的历史
+### 11.3.2 cgroups 的历史
相关信息如下表:
@@ -44,7 +44,7 @@ flowchart LR
---
-### cgroups 可以限制的资源
+### 11.3.3 cgroups 可以限制的资源
相关信息如下表:
@@ -58,7 +58,7 @@ flowchart LR
---
-### Docker 中的资源限制
+### 11.3.4 Docker 中的资源限制
Docker 提供了丰富的参数来配置容器的资源限制,主要包括内存、CPU、磁盘 I/O 等。
@@ -142,7 +142,7 @@ $ docker run --pids-limit=100 myapp
---
-### 查看容器资源使用
+### 11.3.5 查看容器资源使用
运行以下命令:
@@ -165,7 +165,7 @@ $ docker inspect mycontainer --format '{{json .HostConfig}}' | jq
---
-### 资源限制的效果
+### 11.3.6 资源限制的效果
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -209,7 +209,7 @@ $ docker run --rm --cpus=1 stress --cpu 4
---
-### cgroups v1 vs v2
+### 11.3.7 cgroups v1 vs v2
相关信息如下表:
@@ -245,7 +245,7 @@ nodev cgroup2
---
-### 在 Compose 中设置限制
+### 11.3.8 在 Compose 中设置限制
在 Compose 中设置限制配置如下:
@@ -265,7 +265,7 @@ services:
---
-### 最佳实践
+### 11.3.9 最佳实践
在使用 Cgroups 限制资源时,遵循一些最佳实践可以避免潜在的问题。
diff --git a/11_implementation/18.4_ufs.md b/11_implementation/18.4_ufs.md
index 892b254..5d8fa97 100644
--- a/11_implementation/18.4_ufs.md
+++ b/11_implementation/18.4_ufs.md
@@ -1,8 +1,8 @@
-## 14.4 联合文件系统
+## 11.4 联合文件系统
联合文件系统 (UnionFS) 是 Docker 镜像分层存储的基础,它允许将多个目录挂载为同一个虚拟文件系统。
-### 什么是联合文件系统
+### 11.4.1 什么是联合文件系统
联合文件系统 (UnionFS) 是一种 **分层、轻量级** 的文件系统,它将多个目录 “联合” 挂载到同一个虚拟目录,形成一个统一的文件系统视图。
@@ -24,7 +24,7 @@ flowchart TD
---
-### 为什么 Docker 使用联合文件系统
+### 11.4.2 为什么 Docker 使用联合文件系统
Docker 选择联合文件系统作为其存储驱动,主要基于以下几个核心优势。
@@ -62,7 +62,7 @@ COPY . . # 层4:应用代码
---
-### Copy-on-Write (写时复制)
+### 11.4.3 Copy-on-Write (写时复制)
当容器修改只读层中的文件时:
@@ -92,7 +92,7 @@ flowchart LR
---
-### Docker 支持的存储驱动
+### 11.4.4 Docker 支持的存储驱动
Docker 可使用多种联合文件系统实现:
@@ -128,7 +128,7 @@ Storage Driver: overlay2
---
-### overlay2 工作原理
+### 11.4.5 overlay2 工作原理
overlay2 是目前最推荐的存储驱动:
@@ -169,7 +169,7 @@ flowchart TD
---
-### 查看镜像层
+### 11.4.6 查看镜像层
运行以下命令:
@@ -198,7 +198,7 @@ $ docker inspect nginx:alpine --format '{{json .GraphDriver.Data}}' | jq
---
-### 最佳实践
+### 11.4.7 最佳实践
为了构建高效、轻量的镜像,我们在使用联合文件系统时应注意以下几点。
diff --git a/11_implementation/18.5_container_format.md b/11_implementation/18.5_container_format.md
index 97610a1..f718fbf 100644
--- a/11_implementation/18.5_container_format.md
+++ b/11_implementation/18.5_container_format.md
@@ -1,3 +1,3 @@
-## 14.5 容器格式
+## 11.5 容器格式
最初,Docker 采用了 `LXC` 中的容器格式。从 0.7 版本以后开始去除 LXC,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://github.com/containerd/containerd)。
diff --git a/11_implementation/18.6_network.md b/11_implementation/18.6_network.md
index 58b384f..569837e 100644
--- a/11_implementation/18.6_network.md
+++ b/11_implementation/18.6_network.md
@@ -1,8 +1,8 @@
-## 14.6 Docker 网络实现
+## 11.6 Docker 网络实现
Docker 的网络实现其实就是利用了 Linux 上的网络命名空间和虚拟网络设备 (特别是 veth pair)。建议先熟悉了解这两部分的基本概念再阅读本章。
-### 基本原理
+### 11.6.1 基本原理
首先,要实现网络通信,机器需要至少一个网络接口 (物理接口或虚拟接口) 来收发数据包;此外,如果不同子网之间要进行通信,需要路由机制。
@@ -11,7 +11,7 @@ Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据
Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通 (这样的一对接口叫做 `veth pair`)。
-### 创建网络参数
+### 11.6.2 创建网络参数
Docker 创建一个容器的时候,会执行如下操作:
@@ -29,7 +29,7 @@ Docker 创建一个容器的时候,会执行如下操作:
* `--net=container:NAME_or_ID` 让 Docker 将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP 地址和端口等网络资源,两者进程可以直接通过 `lo` 环回接口通信。
* `--net=none` 让 Docker 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己进行配置。
-### 网络配置细节
+### 11.6.3 网络配置细节
用户使用 `--net=none` 后,可以自行配置网络,让容器达到跟平常一样具有访问网络的权限。通过这个过程,可以了解 Docker 配置网络的细节。
diff --git a/11_implementation/summary.md b/11_implementation/summary.md
index c81416c..4011bfc 100644
--- a/11_implementation/summary.md
+++ b/11_implementation/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 11.7 本章小结
相关信息如下表:
@@ -11,7 +11,7 @@
| IPC | 进程间通信 | 容器间 IPC 隔离 |
| USER | 用户 ID | 容器 root ≠ 宿主机 root |
-### 延伸阅读
+### 11.7.1 延伸阅读
- [控制组 (Cgroups)](18.3_cgroups.md):资源限制机制
- [联合文件系统](18.4_ufs.md):分层存储的实现
@@ -26,7 +26,7 @@
| **磁盘 I/O** | `--device-write-bps` | `--device-write-bps /dev/sda:10mb` |
| **进程数** | `--pids-limit` | `--pids-limit=100` |
-### 延伸阅读
+### 11.7.2 延伸阅读
- [命名空间](18.2_namespace.md):资源隔离
- [安全](../17_security/README.md):容器安全概述
@@ -39,7 +39,7 @@
| **overlay2** | Docker 默认推荐的存储驱动 |
| **分层好处** | 镜像复用、快速构建、快速启动 |
-### 延伸阅读
+### 11.7.3 延伸阅读
- [镜像](../02_basic_concept/2.1_image.md):理解镜像分层
- [容器](../02_basic_concept/2.2_container.md):容器存储层
diff --git a/12_kubernetes_concepts/advanced.md b/12_kubernetes_concepts/advanced.md
index 7181ec1..fdb6817 100644
--- a/12_kubernetes_concepts/advanced.md
+++ b/12_kubernetes_concepts/advanced.md
@@ -1,8 +1,8 @@
-## Kubernetes 高级特性
+## 12.4 Kubernetes 高级特性
掌握了 Kubernetes 的核心概念 (Pod,Service,Deployment) 后,我们需要了解更多高级特性以构建生产级应用。
-### Helm - 包管理工具
+### 12.4.1 Helm - 包管理工具
[Helm](https://helm.sh/) 被称为 Kubernetes 的包管理器 (类似于 Linux 的 apt/yum)。它将一组 Kubernetes 资源定义文件打包为一个 **Chart**。
@@ -10,7 +10,7 @@
* **版本管理**:轻松回滚应用的发布版本。
* **模板化**:支持复杂的应用部署逻辑配置。
-### Ingress - 服务的入口
+### 12.4.2 Ingress - 服务的入口
Service 虽然提供了负载均衡,但通常是 4 层 (TCP/UDP)。**Ingress** 提供了 7 层 (HTTP/HTTPS) 路由能力,充当集群的网关。
@@ -20,7 +20,7 @@ Service 虽然提供了负载均衡,但通常是 4 层 (TCP/UDP)。**Ingress**
常见的 Ingress Controller 有 Nginx Ingress Controller,Traefik,Istio Gateway 等。
-### Persistent Volume 与 StorageClass
+### 12.4.3 Persistent Volume 与 StorageClass
容器内的文件是临时的。对于有状态应用 (如数据库),需要持久化存储。
@@ -28,7 +28,7 @@ Service 虽然提供了负载均衡,但通常是 4 层 (TCP/UDP)。**Ingress**
* **PV (Persistent Volume)**:实际的存储资源 (NFS,AWS EBS,Ceph 等)。
* **StorageClass**:定义存储类,支持动态创建 PV。
-### Horizontal Pod Autoscaling
+### 12.4.4 Horizontal Pod Autoscaling
HPA 根据 CPU 利用率或其他指标 (如内存、自定义指标) 自动扩缩 Deployment 或 ReplicaSet 中的 Pod 数量。
@@ -53,7 +53,7 @@ spec:
averageUtilization: 50
```
-### ConfigMap 与 Secret
+### 12.4.5 ConfigMap 与 Secret
* **ConfigMap**:存储非机密的配置数据 (配置文件、环境变量)。
* **Secret**:存储机密数据 (密码、Token、证书),在 Etcd 中加密存储。
diff --git a/12_kubernetes_concepts/concepts.md b/12_kubernetes_concepts/concepts.md
index 0469c81..62ad0ba 100644
--- a/12_kubernetes_concepts/concepts.md
+++ b/12_kubernetes_concepts/concepts.md
@@ -1,4 +1,4 @@
-## 基本概念
+## 12.2 基本概念
如图 12-2 所示,Kubernetes 由控制平面与工作节点构成。
@@ -17,7 +17,7 @@
* web 界面 (`ux`):用户可以通过 web 界面操作 Kubernetes。
* 命令行操作 (`cli`):`kubectl` 命令。
-### 节点
+### 12.2.1 节点
在 `Kubernetes` 中,节点是实际工作的点,节点可以是虚拟机或者物理机器,依赖于一个集群环境。每个节点都有一些必要的服务以运行容器组,并且它们都可以通过主节点来管理。必要服务包括 Docker,kubelet 和代理服务。
@@ -69,7 +69,7 @@ Kubernetes 校验节点可用依赖于 ID。在当前的版本中,有两个接
节点控制有一个同步轮询,主要监听所有云平台的虚拟实例,会根据节点状态创建和删除。可以通过 `--node_sync_period` 标志来控制该轮询。如果一个实例已经创建,节点控制将会为其创建一个结构。同样的,如果一个节点被删除,节点控制也会删除该结构。在 Kubernetes 启动时可用通过 `--machines` 标记来显示指定节点。同样可以使用 `kubectl` 来一条一条的添加节点,两者是相同的。通过设置 `--sync_nodes=false` 标记来禁止集群之间的节点同步,你也可以使用 api/kubectl 命令行来增删节点。
-### 容器组
+### 12.2.2 容器组
在 Kubernetes 中,使用的最小单位是容器组,容器组是创建,调度,管理的最小单位。一个容器组使用相同的 Docker 容器并共享卷 (挂载点)。一个容器组是一个特定应用的打包集合,包含一个或多个容器。
@@ -179,30 +179,30 @@ Kubernetes 校验节点可用依赖于 ID。在当前的版本中,有两个接
* 节点控制器标记容器组 `failed`
* 如果容器组运行在一个控制器下,容器组将会在其他地方重新创建
-### Replication Controllers
+### 12.2.3 Replication Controllers
> 注:Replication Controller (RC) 是早期的控制器类型,现代 Kubernetes 更推荐使用 ReplicaSet/Deployment。
-### 服务
+### 12.2.4 服务
> 注:服务 (Service) 定义一组 Pod 的逻辑集合和访问它们的策略。
-### 卷
+### 12.2.5 卷
> 注:卷 (Volume) 包含可被 Pod 中容器访问的数据的目录。
-### 标签
+### 12.2.6 标签
> 注:标签 (Label) 是附加到对象 (如 Pods) 上的键值对,用于组织和选择对象子集。
-### 接口权限
+### 12.2.7 接口权限
> 注:接口权限通过认证、授权和准入控制来保护 Kubernetes API 的访问。
-### web 界面
+### 12.2.8 web 界面
> 注:Kubernetes Dashboard 是一个基于 Web 的用户界面,用于管理集群。
-### 命令行操作
+### 12.2.9 命令行操作
> 注:kubectl 是 Kubernetes 的命令行工具,用于与集群进行交互。
diff --git a/12_kubernetes_concepts/design.md b/12_kubernetes_concepts/design.md
index e6bd841..0bc5d13 100644
--- a/12_kubernetes_concepts/design.md
+++ b/12_kubernetes_concepts/design.md
@@ -1,8 +1,8 @@
-## 架构设计
+## 12.3 架构设计
任何优秀的项目都离不开优秀的架构设计。本小节将介绍 Kubernetes 在架构方面的设计考虑。
-### 基本考虑
+### 12.3.1 基本考虑
如果让我们自己从头设计一套容器管理平台,有如下几个方面是很容易想到的:
@@ -11,7 +11,7 @@
* 一套资源调度系统,管理哪个容器该分配到哪个节点上;
* 一套对容器内服务进行抽象和 HA 的系统。
-### 运行原理
+### 12.3.2 运行原理
如图 12-3 所示,该图完整展示了 Kubernetes 的运行原理。
@@ -25,7 +25,7 @@
从这张图上,我们没有能发现 Kubernetes 中对于控制平面的分布式实现,但是由于数据后端自身就是一套分布式的数据库 Etcd,因此可以很容易扩展到分布式实现。
-### 控制平面
+### 12.3.3 控制平面
控制平面 (Control Plane) 是 Kubernetes 集群的大脑,负责做出全局决策 (如调度) 以及检测和响应集群事件。
@@ -45,7 +45,7 @@
组件可以自动的去侦测 Etcd 中的数值变化来获得通知,并且获得更新后的数据来执行相应的操作。
-### 工作节点
+### 12.3.4 工作节点
* kubelet 是工作节点执行操作的 agent,负责具体的容器生命周期管理,根据从数据库中获取的信息来管理容器,并上报 pod 运行状态等;
* kube-proxy 是一个简单的网络访问代理,同时也是一个 Load Balancer。它负责将访问到某个服务的请求具体分配给工作节点上的 Pod (同一类标签)。
diff --git a/12_kubernetes_concepts/intro.md b/12_kubernetes_concepts/intro.md
index a552f9a..8199956 100644
--- a/12_kubernetes_concepts/intro.md
+++ b/12_kubernetes_concepts/intro.md
@@ -1,4 +1,4 @@
-## Kubernetes 简介
+## 12.1 Kubernetes 简介
如图 12-1 所示,Kubernetes 使用舵手图标作为项目标识。
@@ -6,7 +6,7 @@
图 12-1 Kubernetes 项目标识
-### 什么是 Kubernetes
+### 12.1.1 什么是 Kubernetes
Kubernetes (常简称为 K8s) 是 Google 开源的容器编排引擎。如果说 Docker 解决了 “如何打包和运送集装箱” 的问题,那么 Kubernetes 解决的就是 “如何管理海量集装箱的调度、运行和维护” 的问题。
@@ -16,7 +16,7 @@ Kubernetes (常简称为 K8s) 是 Google 开源的容器编排引擎。如果说
---
-### 为什么需要 Kubernetes
+### 12.1.2 为什么需要 Kubernetes
当我们在单机运行几个容器时,Docker Compose 就足够了。但在生产环境中,我们需要面对:
@@ -30,7 +30,7 @@ Kubernetes 完美解决了这些问题。
---
-### 核心概念
+### 12.1.3 核心概念
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -56,7 +56,7 @@ Kubernetes 的最小调度单位。一个 Pod 可以包含一个或多个紧密
---
-### Docker 用户如何过渡
+### 12.1.4 Docker 用户如何过渡
如果你已经熟悉 Docker,学习 K8s 会很容易:
@@ -69,7 +69,7 @@ Kubernetes 的最小调度单位。一个 Pod 可以包含一个或多个紧密
---
-### 架构
+### 12.1.5 架构
Kubernetes 也是 C/S 架构,由 **Control Plane (控制平面)** 和 **Worker Node (工作节点)** 组成:
@@ -78,7 +78,7 @@ Kubernetes 也是 C/S 架构,由 **Control Plane (控制平面)** 和 **Worker
---
-### 学习建议
+### 12.1.6 学习建议
Kubernetes 的学习曲线较陡峭。建议的学习路径:
@@ -89,7 +89,7 @@ Kubernetes 的学习曲线较陡峭。建议的学习路径:
---
-### 延伸阅读
+### 12.1.7 延伸阅读
- [Minikube 安装](../setup/README.md):本地体验 K8s
- [Kubernetes 官网](https://kubernetes.io/):官方文档
diff --git a/12_kubernetes_concepts/practice.md b/12_kubernetes_concepts/practice.md
index 72cad4a..9f8b4c3 100644
--- a/12_kubernetes_concepts/practice.md
+++ b/12_kubernetes_concepts/practice.md
@@ -1,14 +1,14 @@
-## Kubernetes 实战练习
+## 12.5 Kubernetes 实战练习
本章将通过一个具体的案例:部署一个 Nginx 网站,并为其配置 Service 和 Ingress,来串联前面学到的知识。
-### 目标
+### 12.5.1 目标
1. 部署一个 Nginx Deployment。
2. 创建一个 Service 暴露 Nginx。
3. (可选) 通过 Ingress 访问服务。
-### 步骤 1:创建 Deployment
+### 12.5.2 步骤 1:创建 Deployment
创建一个名为 `nginx-deployment.yaml` 的文件:
@@ -42,7 +42,7 @@ spec:
kubectl apply -f nginx-deployment.yaml
```
-### 步骤 2:创建 Service
+### 12.5.3 步骤 2:创建 Service
创建一个名为 `nginx-service.yaml` 的文件:
@@ -75,7 +75,7 @@ kubectl get svc nginx-service
如果输出端口是 `80:30080/TCP`,你可以通过 `http://:30080` 访问 Nginx。
-### 步骤 3:模拟滚动更新
+### 12.5.4 步骤 3:模拟滚动更新
修改 `nginx-deployment.yaml`,将镜像版本改为 `nginx:1.27-alpine`。
@@ -89,7 +89,7 @@ kubectl apply -f nginx-deployment.yaml
kubectl rollout status deployment/nginx-deployment
```
-### 步骤 4:清理资源
+### 12.5.5 步骤 4:清理资源
练习结束后,记得清理资源:
diff --git a/13_kubernetes_setup/dashboard.md b/13_kubernetes_setup/dashboard.md
index ed67f45..b686bc9 100644
--- a/13_kubernetes_setup/dashboard.md
+++ b/13_kubernetes_setup/dashboard.md
@@ -1,10 +1,10 @@
-## Kubernetes Dashboard
+## 13.7 Kubernetes Dashboard
[Kubernetes Dashboard](https://github.com/kubernetes/dashboard) 是基于网页的 Kubernetes 用户界面。

-### 部署
+### 13.7.1 部署
执行以下命令即可部署 Dashboard:
@@ -12,7 +12,7 @@
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
```
-### 访问
+### 13.7.2 访问
通过命令行代理访问,执行以下命令:
@@ -22,7 +22,7 @@ $ kubectl proxy
到 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ 即可访问。
-### 登录
+### 13.7.3 登录
目前,Dashboard 仅支持使用 Bearer 令牌登录。下面教大家如何创建该令牌:
@@ -40,6 +40,6 @@ echo ${DASHBOARD_LOGIN_TOKEN}
将结果粘贴到登录页面,即可登录。
-### 参考文档
+### 13.7.4 参考文档
* [官方文档](https://kubernetes.io/zh/docs/tasks/access-application-cluster/web-ui-dashboard/)
diff --git a/13_kubernetes_setup/docker-desktop.md b/13_kubernetes_setup/docker-desktop.md
index d3c9d18..8e2748d 100644
--- a/13_kubernetes_setup/docker-desktop.md
+++ b/13_kubernetes_setup/docker-desktop.md
@@ -1,8 +1,8 @@
-## Docker Desktop 启用 Kubernetes
+## 13.3 Docker Desktop 启用 Kubernetes
使用 Docker Desktop 可以很方便的启用 Kubernetes。
-### 启用 Kubernetes
+### 13.3.1 启用 Kubernetes
在 Docker Desktop 设置页面,点击 `Kubernetes`,选择 `Enable Kubernetes`,稍等片刻,看到左下方 `Kubernetes` 变为 `running`,Kubernetes 启动成功。
@@ -10,7 +10,7 @@
> 注意:Kubernetes 的镜像存储在 `registry.k8s.io`,如果国内网络无法直接访问,可以在 Docker Desktop 配置中的 `Docker Engine` 处配置镜像加速器,或者利用国内云服务商的镜像仓库手动拉取镜像并 retag。
-### 测试
+### 13.3.2 测试
运行以下命令:
diff --git a/13_kubernetes_setup/k3s.md b/13_kubernetes_setup/k3s.md
index 4921faa..34d7acd 100644
--- a/13_kubernetes_setup/k3s.md
+++ b/13_kubernetes_setup/k3s.md
@@ -1,15 +1,15 @@
-## K3s - 轻量级 Kubernetes
+## 13.5 K3s - 轻量级 Kubernetes
[K3s](https://k3s.io/) 是一个轻量级的 Kubernetes 发行版,由 Rancher Labs 开发。它专为边缘计算、物联网、CI、ARM 等资源受限的环境设计。K3s 被打包为单个二进制文件,只有不到 100MB,但通过了 CNCF 的一致性测试。
-### 核心特性
+### 13.5.1 核心特性
* **轻量级**:移除过时的、非必须的 Kubernetes 功能 (如传统的云提供商插件),使用 SQLite 作为默认数据存储 (也支持 Etcd/MySQL/Postgres)。
* **单一二进制**:所有组件 (API Server,Controller Manager,Scheduler,Kubelet,Kube-proxy) 打包在一个进程中运行。
* **开箱即用**:内置 Helm Controller、Traefik Ingress controller、ServiceLB、Local-Path-Provisioner。
* **安全**:默认启用安全配置,基于 TLS 通信。
-### 安装
+### 13.5.2 安装
K3s 的安装非常简单,官方提供了便捷的安装脚本。
@@ -37,7 +37,7 @@ NAME STATUS ROLES AGE VERSION
k3s-master Ready control-plane,master 1m v1.35.1+k3s1
```
-### 快速使用
+### 13.5.3 快速使用
K3s 内置了 `kubectl` 命令 (通过 `k3s kubectl` 调用),为了方便,通常会建立别名或配置 `KUBECONFIG`。
@@ -51,7 +51,7 @@ export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get pods -A
```
-### 清理卸载
+### 13.5.4 清理卸载
运行以下命令:
diff --git a/13_kubernetes_setup/kind.md b/13_kubernetes_setup/kind.md
index 058a9fd..6117cd7 100644
--- a/13_kubernetes_setup/kind.md
+++ b/13_kubernetes_setup/kind.md
@@ -1,8 +1,8 @@
-## Kind - Kubernetes IN Docker
+## 13.4 Kind - Kubernetes IN Docker
[Kind](https://kind.sigs.k8s.io/) (Kubernetes in Docker) 是一个使用 Docker 容器作为节点运行本地 Kubernetes 集群的工具。主要用于测试 Kubernetes 本身,也非常适合本地开发和 CI 环境。
-### 为什么选择 Kind
+### 13.4.1 为什么选择 Kind
Kind 相比其他本地集群方案 (如 Minikube) 有以下显著优势:
@@ -11,7 +11,7 @@ Kind 相比其他本地集群方案 (如 Minikube) 有以下显著优势:
* **多版本支持**:支持指定 Kubernetes 版本进行测试。
* **HA 支持**:支持模拟高可用集群 (多 Control Plane)。
-### 安装 Kind
+### 13.4.2 安装 Kind
Kind 是一个二进制文件,并在 PATH 中即可使用。以下是不同系统的安装方法。
@@ -35,7 +35,7 @@ chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
```
-### 创建集群
+### 13.4.3 创建集群
最简单的创建方式:
@@ -49,7 +49,7 @@ kind create cluster
kind create cluster --name my-cluster
```
-### 与集群交互
+### 13.4.4 与集群交互
Kind 会自动将 kubeconfig 合并到 `~/.kube/config`。
@@ -58,7 +58,7 @@ kubectl cluster-info --context kind-kind
kubectl get nodes
```
-### 高级用法:配置集群
+### 13.4.5 高级用法:配置集群
创建一个 `kind-config.yaml` 来定制集群,例如映射端口到宿主机:
@@ -81,7 +81,7 @@ nodes:
kind create cluster --config kind-config.yaml
```
-### 删除集群
+### 13.4.6 删除集群
运行以下命令:
diff --git a/13_kubernetes_setup/kubeadm-docker.md b/13_kubernetes_setup/kubeadm-docker.md
index 488900e..742035e 100644
--- a/13_kubernetes_setup/kubeadm-docker.md
+++ b/13_kubernetes_setup/kubeadm-docker.md
@@ -1,4 +1,4 @@
-## 使用 kubeadm 部署 Kubernetes (使用 Docker)
+## 13.2 使用 kubeadm 部署 Kubernetes (使用 Docker)
`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令,作为快速创建 `Kubernetes` 集群的最佳实践。
@@ -6,11 +6,11 @@
>
> 本文档主要用于历史环境/学习目的:如果你确实需要在较新版本中继续使用 Docker Engine,通常需要额外部署 `cri-dockerd` 并在 `kubeadm init/join` 中指定 `--cri-socket`。
-### 安装 Docker
+### 13.2.1 安装 Docker
参考[安装 Docker](../../03_install/README.md) 一节安装 Docker。
-### 安装 **kubelet****kubeadm****kubectl**
+### 13.2.2 安装 **kubelet****kubeadm****kubectl**
需要在每台机器上安装以下的软件包:
@@ -56,7 +56,7 @@ EOF
$ sudo yum install -y kubelet kubeadm kubectl
```
-### 修改内核的运行参数
+### 13.2.3 修改内核的运行参数
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -99,7 +99,7 @@ EOF
$ sysctl --system
```
-### 配置 kubelet
+### 13.2.4 配置 kubelet
为了让 kubelet 正确运行,我们需要对其进行一些必要的配置。
@@ -127,7 +127,7 @@ ExecStartPre=-/sbin/modprobe ip_vs_sh
$ sudo systemctl daemon-reload
```
-### 部署
+### 13.2.5 部署
安装配置完成后,我们将分别在 Master 节点和 Worker 节点上进行部署操作。
@@ -182,7 +182,7 @@ $ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \
--discovery-token-ca-cert-hash sha256:5edb316fd0d8ea2792cba15cdf1c899a366f147aa03cba52d4e5c5884ad836fe
```
-### 查看服务
+### 13.2.6 查看服务
所有服务启动后,查看本地实际运行的 Docker 容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。
@@ -202,7 +202,7 @@ $ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \
* Etcd 是所有状态的存储数据库;
-### 使用
+### 13.2.7 使用
将 `/etc/kubernetes/admin.conf` 复制到 `~/.kube/config`
@@ -210,7 +210,7 @@ $ kubeadm join 192.168.199.100:6443 --token cz81zt.orsy9gm9v649e5lf \
由于未部署 CNI 插件,CoreDNS 未正常启动。如何使用 Kubernetes,请参考后续章节。
-### 部署 CNI
+### 13.2.8 部署 CNI
这里以 `flannel` 为例进行介绍。
@@ -235,7 +235,7 @@ $ kubectl get node -o yaml | grep CIDR
$ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.26.1/Documentation/kube-flannel.yml
```
-### master 节点默认不能运行 pod
+### 13.2.9 master 节点默认不能运行 pod
如果用 `kubeadm` 部署一个单节点集群,默认情况下无法使用,请执行以下命令解除限制
@@ -253,6 +253,6 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master-
...
```
-### 参考文档
+### 13.2.10 参考文档
* [官方文档](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)
diff --git a/13_kubernetes_setup/kubeadm.md b/13_kubernetes_setup/kubeadm.md
index 103c5b6..8b63de9 100644
--- a/13_kubernetes_setup/kubeadm.md
+++ b/13_kubernetes_setup/kubeadm.md
@@ -1,10 +1,10 @@
-## 使用 kubeadm 部署 Kubernetes (CRI 使用 containerd)
+## 13.1 使用 kubeadm 部署 Kubernetes (CRI 使用 containerd)
`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令,作为快速创建 `Kubernetes` 集群的最佳实践。
> **版本说明**:Kubernetes 版本更新较快 (约每 4 个月一个新版本),本文档基于 Kubernetes 1.35 编写。请访问 [Kubernetes 官方发布页](https://kubernetes.io/releases/)获取最新版本信息。
-### 安装 containerd
+### 13.1.1 安装 containerd
参考[安装 Docker](../../03_install/README.md) 一节添加 apt/yum 源,之后执行如下命令。
@@ -18,7 +18,7 @@ $ sudo apt install containerd.io
$ sudo yum install containerd.io
```
-### 配置 containerd
+### 13.1.2 配置 containerd
新建 `/etc/systemd/system/cri-containerd.service` 文件
@@ -228,7 +228,7 @@ oom_score = 0
async_remove = false
```
-### 安装 **kubelet****kubeadm****kubectl****cri-tools****kubernetes-cni**
+### 13.1.3 安装 **kubelet****kubeadm****kubectl****cri-tools****kubernetes-cni**
需要在每台机器上安装以下的软件包:
@@ -274,7 +274,7 @@ EOF
$ sudo yum install -y kubelet kubeadm kubectl cri-tools kubernetes-cni
```
-### 修改内核的运行参数
+### 13.1.4 修改内核的运行参数
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -317,7 +317,7 @@ EOF
$ sysctl --system
```
-### 配置 kubelet
+### 13.1.5 配置 kubelet
为了让 kubelet 正确运行,我们需要对其进行一些必要的配置。
@@ -345,7 +345,7 @@ ExecStartPre=-/sbin/modprobe ip_vs_sh
$ sudo systemctl daemon-reload
```
-### 部署
+### 13.1.6 部署
安装配置完成后,我们将分别在 Master 节点和 Worker 节点上进行部署操作。
@@ -412,7 +412,7 @@ $ kubeadm join 192.168.199.100:6443 \
--cri-socket /run/cri-containerd/cri-containerd.sock
```
-### 查看服务
+### 13.1.7 查看服务
所有服务启动后,通过 `crictl` 查看本地实际运行的容器。这些服务大概分为三类:主节点服务、工作节点服务和其它服务。
@@ -436,7 +436,7 @@ CONTAINER_RUNTIME_ENDPOINT=/run/cri-containerd/cri-containerd.sock crictl ps -a
* Etcd 是所有状态的存储数据库;
-### 使用
+### 13.1.8 使用
将 `/etc/kubernetes/admin.conf` 复制到 `~/.kube/config`
@@ -444,7 +444,7 @@ CONTAINER_RUNTIME_ENDPOINT=/run/cri-containerd/cri-containerd.sock crictl ps -a
由于未部署 CNI 插件,CoreDNS 未正常启动。如何使用 Kubernetes,请参考后续章节。
-### 部署 CNI
+### 13.1.9 部署 CNI
这里以 `flannel` 为例进行介绍。
@@ -469,7 +469,7 @@ $ kubectl get node -o yaml | grep CIDR
$ kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.26.1/Documentation/kube-flannel.yml
```
-### master 节点默认不能运行 pod
+### 13.1.10 master 节点默认不能运行 pod
如果用 `kubeadm` 部署一个单节点集群,默认情况下无法使用,请执行以下命令解除限制
@@ -487,7 +487,7 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master-
...
```
-### 参考文档
+### 13.1.11 参考文档
* [官方文档](https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)
* [Container runtimes](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd)
diff --git a/13_kubernetes_setup/kubectl.md b/13_kubernetes_setup/kubectl.md
index eaf1fdf..2446ddb 100644
--- a/13_kubernetes_setup/kubectl.md
+++ b/13_kubernetes_setup/kubectl.md
@@ -8,74 +8,74 @@ kubectl [flags]
kubectl [command]
```
-## get
+## 13.8 get
显示一个或多个资源
-## describe
+## 13.8 describe
显示资源详情
-## create
+## 13.8 create
从文件或标准输入创建资源
-## update
+## 13.8 update
从文件或标准输入更新资源
-## delete
+## 13.8 delete
通过文件名、标准输入、资源名或者 label selector 删除资源
-## logs
+## 13.8 logs
输出 pod 中一个容器的日志
-## rollout
+## 13.8 rollout
对 Deployment 等资源执行滚动更新/回滚
-## exec
+## 13.8 exec
在容器内部执行命令
-## port-forward
+## 13.8 port-forward
将本地端口转发到 Pod
-## proxy
+## 13.8 proxy
为 Kubernetes API server 启动代理服务器
-## run
+## 13.8 run
在集群中使用指定镜像启动容器
-## expose
+## 13.8 expose
将 replication controller service 或 pod 暴露为新的 Kubernetes service
-## label
+## 13.8 label
更新资源的 label
-## config
+## 13.8 config
修改 Kubernetes 配置文件
-## cluster-info
+## 13.8 cluster-info
显示集群信息
-## api-versions
+## 13.8 api-versions
以 “组/版本” 的格式输出服务端支持的 API 版本
-## version
+## 13.8 version
输出服务端和客户端的版本信息
-## help
+## 13.8 help
显示各个命令的帮助信息
diff --git a/13_kubernetes_setup/systemd.md b/13_kubernetes_setup/systemd.md
index ddd585c..f50de7b 100644
--- a/13_kubernetes_setup/systemd.md
+++ b/13_kubernetes_setup/systemd.md
@@ -1,3 +1,3 @@
-## 一步步部署 Kubernetes 集群
+## 13.6 一步步部署 Kubernetes 集群
可以参考 [opsnull/follow-me-install-kubernetes-cluster](https://github.com/opsnull/follow-me-install-kubernetes-cluster) 项目一步步部署 Kubernetes 集群。
diff --git a/14_etcd/cluster.md b/14_etcd/cluster.md
index 658bcbc..148336b 100644
--- a/14_etcd/cluster.md
+++ b/14_etcd/cluster.md
@@ -1,4 +1,4 @@
-## etcd 集群
+## 14.3 etcd 集群
下面我们使用 [Docker Compose](../../10_compose/README.md) 模拟启动一个 3 节点的 `etcd` 集群。
diff --git a/14_etcd/etcdctl.md b/14_etcd/etcdctl.md
index b067562..e62a5ff 100644
--- a/14_etcd/etcdctl.md
+++ b/14_etcd/etcdctl.md
@@ -1,4 +1,4 @@
-## 使用 etcdctl
+## 14.4 使用 etcdctl
`etcdctl` 是一个命令行客户端,它能提供一些简洁的命令,供用户直接跟 `etcd` 服务打交道,而无需基于 `HTTP API` 方式。这在某些情况下将很方便,例如用户对服务进行测试或者手动修改数据库内容。我们也推荐在刚接触 `etcd` 时通过 `etcdctl` 命令来熟悉相关的操作,这些操作跟 `HTTP API` 实际上是对应的。
@@ -81,7 +81,7 @@ OPTIONS:
-w, --write-out="simple" set the output format (fields, json, protobuf, simple, table)
```
-### 数据库操作
+### 14.4.1 数据库操作
数据库操作围绕对键值和目录的 CRUD (符合 REST 风格的一套操作:Create) 完整生命周期的管理。
@@ -125,7 +125,7 @@ $ etcdctl del testkey
1
```
-### 非数据库操作
+### 14.4.2 非数据库操作
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/14_etcd/install.md b/14_etcd/install.md
index d7702fd..77926d1 100644
--- a/14_etcd/install.md
+++ b/14_etcd/install.md
@@ -1,4 +1,4 @@
-## 安装
+## 14.2 安装
本节将介绍 etcd 的几种常见安装方式,包括二进制安装、Docker 镜像运行以及在 macOS 上的安装。
@@ -6,7 +6,7 @@
>注意:本章节内容基于 etcd `3.4.x` 版本
-### 二进制文件方式下载
+### 14.2.1 二进制文件方式下载
编译好的二进制文件都在 [github.com/etcd-io/etcd/releases](https://github.com/etcd-io/etcd/releases/) 页面,用户可以选择需要的版本,或通过下载工具下载。
@@ -61,7 +61,7 @@ hello world
说明 etcd 服务已经成功启动了。
-### Docker 镜像方式运行
+### 14.2.2 Docker 镜像方式运行
镜像名称为 `quay.io/coreos/etcd`,可以通过下面的命令启动 `etcd` 服务监听到 `2379` 和 `2380` 端口。
@@ -89,7 +89,7 @@ quay.io/coreos/etcd:v3.4.0 \
打开新的终端按照上一步的方法测试 `etcd` 是否成功启动。
-### macOS 中运行
+### 14.2.3 macOS 中运行
运行以下命令:
diff --git a/14_etcd/intro.md b/14_etcd/intro.md
index 89743b2..47a03a8 100644
--- a/14_etcd/intro.md
+++ b/14_etcd/intro.md
@@ -1,4 +1,4 @@
-## 简介
+## 14.1 简介
如图 12-5 所示,etcd 项目使用该标识。
diff --git a/15_cloud/alicloud.md b/15_cloud/alicloud.md
index dbbae37..6d3daf2 100644
--- a/15_cloud/alicloud.md
+++ b/15_cloud/alicloud.md
@@ -1,4 +1,4 @@
-## 阿里云
+## 15.3 阿里云
如图 13-3 所示,阿里云是国内主流云服务平台之一。
diff --git a/15_cloud/aws.md b/15_cloud/aws.md
index ae6dd84..8030eb0 100644
--- a/15_cloud/aws.md
+++ b/15_cloud/aws.md
@@ -1,4 +1,4 @@
-## 亚马逊云
+## 15.4 亚马逊云
如图 13-1 所示,AWS 是全球主流云服务平台之一。
diff --git a/15_cloud/intro.md b/15_cloud/intro.md
index bde7d62..f593119 100644
--- a/15_cloud/intro.md
+++ b/15_cloud/intro.md
@@ -1,22 +1,22 @@
-## 简介
+## 15.1 简介
随着容器技术的普及,目前主流的云计算服务商都提供了成熟的容器服务。与容器相关的云计算服务主要分为以下几种类型:
-### 1。容器编排托管服务
+### 15.1.1 。容器编排托管服务
这是目前最主流的形式。云厂商托管 Kubernetes 的控制平面 (Master 节点),用户只需管理工作节点 (Worker Node)。
* **优势**:降低了 Kubernetes 集群的维护成本,高可用性由厂商保证。
* **典型服务**:AWS EKS,Azure AKS,Google GKE,阿里云 ACK,腾讯云 TKE。
-### 2。容器实例服务
+### 15.1.2 。容器实例服务
这一类服务通常被称为 CaaS (Container as a Service)。用户无需管理底层服务器 (EC2/CVM),只需提供镜像和配置即可运行容器。
* **优势**:极致的弹性,按秒计费,零运维。
* **典型服务**:AWS Fargate,Azure Container Instances,Google Cloud Run,阿里云 ECI。
-### 3。镜像仓库服务
+### 15.1.3 。镜像仓库服务
提供安全、可靠的私有 Docker 镜像存储服务,通常与云厂商的 CI/CD 流水线深度集成。
diff --git a/15_cloud/multicloud.md b/15_cloud/multicloud.md
index e530e25..642950e 100644
--- a/15_cloud/multicloud.md
+++ b/15_cloud/multicloud.md
@@ -1,8 +1,8 @@
-## 多云部署策略比较
+## 15.6 多云部署策略比较
企业在选择容器云平台时,通常会在 AWS EKS,Azure AKS,Google GKE 以及国内的阿里云 ACK,腾讯云 TKE 之间进行权衡。
-### 三大公有云 Kubernetes 服务对比
+### 15.6.1 三大公有云 Kubernetes 服务对比
相关信息如下表:
@@ -14,7 +14,7 @@
| **网络模型** | VPC-native, 性能优秀 | AWS VPC CNI, Pod 直接获取 VPC IP | Azure CNI (消耗 IP 多) 或 Kubenet |
| **集成度** | 与 GCP 数据分析、AI 服务集成紧密 | 与 AWS IAM, ALB, CloudWatch 集成深度高 | 与 Active Directory, Azure DevOps 集成好 |
-### 多云部署策略
+### 15.6.2 多云部署策略
随着企业业务的扩展,单一云平台可能无法满足所有需求,多云部署成为趋势。
@@ -38,7 +38,7 @@
* **工具**:Google Anthos,AWS Outposts,Azure Arc 都是为了解决混合云统一管理而生。
-### 建议
+### 15.6.3 建议
* **技术选型**:尽量使用标准的 Kubernetes API,避免过度依赖特定云厂商的 CRD 或专有服务,以保持应用的可移植性。
* **IaC 管理**:使用 Terraform 或 Pulumi 等工具统一管理多云基础设施。
diff --git a/15_cloud/summary.md b/15_cloud/summary.md
index fd3c1fb..23e9f0c 100644
--- a/15_cloud/summary.md
+++ b/15_cloud/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 15.5 本章小结
本章介绍了公有云服务对 Docker 的积极支持,以及新出现的容器云平台。
diff --git a/15_cloud/tencentCloud.md b/15_cloud/tencentCloud.md
index 06d1ba7..fa206f6 100644
--- a/15_cloud/tencentCloud.md
+++ b/15_cloud/tencentCloud.md
@@ -1,4 +1,4 @@
-## 腾讯云
+## 15.2 腾讯云
如图 13-5 所示,腾讯云提供完整的云基础设施与容器能力。
diff --git a/16_ecosystem/coreos_install.md b/16_ecosystem/coreos_install.md
index 5b373ef..a06bb81 100644
--- a/16_ecosystem/coreos_install.md
+++ b/16_ecosystem/coreos_install.md
@@ -1,12 +1,12 @@
-## 安装 Fedora CoreOS
+## 16.2 安装 Fedora CoreOS
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 下载 ISO
+### 16.2.1 下载 ISO
在[下载页面](https://getfedora.org/coreos/download/) `Bare Metal & Virtualized` 标签页下载 ISO。
-### 编写 FCC
+### 16.2.2 编写 FCC
FCC 是 Fedora CoreOS Configuration (Fedora CoreOS 配置) 的简称。
@@ -24,7 +24,7 @@ passwd:
将 `ssh-rsa AAAA...` 替换为自己的 SSH 公钥 (位于 `~/.ssh/id_rsa.pub`)。
-### 转换 FCC 为 Ignition
+### 16.2.3 转换 FCC 为 Ignition
运行以下命令:
@@ -32,7 +32,7 @@ passwd:
$ docker run -i --rm quay.io/coreos/fcct:v0.5.0 --pretty --strict < example.fcc > example.ign
```
-### 挂载 ISO 启动虚拟机并安装
+### 16.2.4 挂载 ISO 启动虚拟机并安装
> 虚拟机需要分配 3GB 以上内存,否则会无法启动。
@@ -44,7 +44,7 @@ $ sudo coreos-installer install /dev/sda --ignition-file example.ign
安装之后重新启动即可使用。
-### 使用
+### 16.2.5 使用
运行以下命令:
@@ -54,6 +54,6 @@ $ ssh core@虚拟机IP
$ docker --version
```
-### 参考链接
+### 16.2.6 参考链接
* [官方文档](https://docs.fedoraproject.org/en-US/fedora-coreos/bare-metal/)
diff --git a/16_ecosystem/coreos_intro.md b/16_ecosystem/coreos_intro.md
index 40b8b4a..e802c84 100644
--- a/16_ecosystem/coreos_intro.md
+++ b/16_ecosystem/coreos_intro.md
@@ -1,8 +1,8 @@
-## Fedora CoreOS 介绍
+## 16.1 Fedora CoreOS 介绍
[Fedora CoreOS](https://getfedora.org/coreos/) 是一个自动更新的,最小的,整体的,以容器为中心的操作系统,不仅适用于集群,而且可独立运行,并针对运行 Kubernetes 进行了优化。它旨在结合 CoreOS Container Linux 和 Fedora Atomic Host 的优点,将 Container Linux 中的 [Ignition](https://github.com/coreos/ignition) 与 [rpm-ostree](https://github.com/coreos/rpm-ostree) 和 Project Atomic 中的 SELinux 强化等技术相集成。其目标是提供最佳的容器主机,以安全,大规模地运行容器化的工作负载。
-### FCOS 特性
+### 16.1.1 FCOS 特性
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -24,7 +24,7 @@ FCOS 使用 rpm-ostree 系统进行事务性升级。无需像 yum 升级那样
对于诸如构建,复制和其他管理容器的任务,FCOS 用一组容器工具代替了 **Docker CLI**。**podman CLI** 工具支持许多容器运行时功能,例如运行,启动,停止,列出和删除容器和镜像。**skopeo CLI** 工具可以复制,认证和签名镜像。您还可以使用 **crictl CLI** 工具来处理 CRI-O 容器引擎中的容器和镜像。
-### 参考文档
+### 16.1.2 参考文档
* [官方文档](https://docs.fedoraproject.org/en-US/fedora-coreos/)
* [openshift 官方文档](https://docs.openshift.com/container-platform/4.3/architecture/architecture-rhcos.html)
diff --git a/16_ecosystem/podman.md b/16_ecosystem/podman.md
index 6e62386..241ece2 100644
--- a/16_ecosystem/podman.md
+++ b/16_ecosystem/podman.md
@@ -2,7 +2,7 @@
[`podman`](https://github.com/containers/podman) 是一个无守护进程、与 Docker 命令高度兼容的下一代 Linux 容器工具。它由 Red Hat 开发,旨在提供一个更安全的容器运行环境。
-## Podman vs Docker
+## 16.3 Podman vs Docker
Podman 和 Docker 在设计理念上存在显著差异,主要体现在架构和权限模型上。
@@ -13,11 +13,11 @@ Podman 和 Docker 在设计理念上存在显著差异,主要体现在架构
| **生态** | 完整的生态系统 (Compose, Swarm) | 专注单机容器,配合 Kubernetes 使用 |
| **镜像构建** | `docker build` | `podman build` 或 `buildah` |
-## 安装
+## 16.3 安装
Podman 支持多种操作系统,安装过程也相对简单。
-### CentOS / RHEL
+### 16.3.1 CentOS / RHEL
运行以下命令:
@@ -25,7 +25,7 @@ Podman 支持多种操作系统,安装过程也相对简单。
$ sudo yum -y install podman
```
-### macOS
+### 16.3.2 macOS
macOS 上需要安装 Podman Desktop 或通过 Homebrew 安装:
@@ -35,11 +35,11 @@ $ podman machine init
$ podman machine start
```
-## 使用
+## 16.3 使用
`podman` 的命令行几乎与 `docker` 完全兼容,大多数情况下,你只需将 `docker` 替换为 `podman` 即可。
-### 运行容器
+### 16.3.1 运行容器
运行以下命令:
@@ -49,7 +49,7 @@ $ podman machine start
$ podman run -d -p 80:80 nginx:alpine
```
-### 列出容器
+### 16.3.2 列出容器
运行以下命令:
@@ -57,7 +57,7 @@ $ podman run -d -p 80:80 nginx:alpine
$ podman ps
```
-### 构建镜像
+### 16.3.3 构建镜像
运行以下命令:
@@ -65,7 +65,7 @@ $ podman ps
$ podman build -t myimage .
```
-## Pods 的概念
+## 16.3 Pods 的概念
与 Docker 不同,Podman 支持 “Pod” 的概念 (类似于 Kubernetes 的 Pod),允许你在同一个网络命名空间中运行多个容器。
@@ -79,7 +79,7 @@ $ podman pod create --name mypod -p 8080:80
$ podman run -d --pod mypod --name webbing nginx
```
-## 迁移到 Podman
+## 16.3 迁移到 Podman
如果你习惯使用 `docker` 命令,可以简单地设置别名:
@@ -87,7 +87,7 @@ $ podman run -d --pod mypod --name webbing nginx
$ alias docker=podman
```
-### 进阶用法
+### 16.3.1 进阶用法
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -118,7 +118,7 @@ $ pip3 install podman-compose
$ podman-compose up -d
```
-### 参考
+### 16.3.2 参考
* [Podman 官方网站](https://podman.io/)
* [Podman GitHub 仓库](https://github.com/containers/podman)
diff --git a/17_security/control_group.md b/17_security/control_group.md
index 61b766c..656d910 100644
--- a/17_security/control_group.md
+++ b/17_security/control_group.md
@@ -1,4 +1,4 @@
-## 控制组
+## 17.2 控制组
控制组是 Linux 容器机制的另外一个关键组件,负责实现资源的审计和限制。
diff --git a/17_security/daemon_sec.md b/17_security/daemon_sec.md
index a3d546d..ffead3b 100644
--- a/17_security/daemon_sec.md
+++ b/17_security/daemon_sec.md
@@ -1,4 +1,4 @@
-## Docker 服务端的防护
+## 17.3 Docker 服务端的防护
运行一个容器或应用程序的核心是通过 Docker 服务端。Docker 服务的运行目前需要 root 权限,因此其安全性十分关键。
diff --git a/17_security/kernel_capability.md b/17_security/kernel_capability.md
index afc8527..83f0f69 100644
--- a/17_security/kernel_capability.md
+++ b/17_security/kernel_capability.md
@@ -1,4 +1,4 @@
-## 内核能力机制
+## 17.4 内核能力机制
Docker 利用 Linux 的能力机制 (Capabilities) 来限制容器的权限,从而提高系统的安全性。
diff --git a/17_security/kernel_ns.md b/17_security/kernel_ns.md
index a26ffa1..f4d803d 100644
--- a/17_security/kernel_ns.md
+++ b/17_security/kernel_ns.md
@@ -1,4 +1,4 @@
-## 内核命名空间
+## 17.1 内核命名空间
命名空间 (Namespace) 是 Linux 容器隔离的基础,它确保了容器内的进程无法干扰主机或其他容器。
diff --git a/17_security/other_feature.md b/17_security/other_feature.md
index 4ef8803..7f99522 100644
--- a/17_security/other_feature.md
+++ b/17_security/other_feature.md
@@ -1,4 +1,4 @@
-## 其它安全特性
+## 17.5 其它安全特性
除了上述机制,Linux 内核还提供了一系列安全增强功能,可以进一步保护容器环境。
diff --git a/17_security/summary.md b/17_security/summary.md
index 31b5a3c..ffc9f6e 100644
--- a/17_security/summary.md
+++ b/17_security/summary.md
@@ -1,4 +1,4 @@
-## 总结
+## 17.6 总结
Docker 的安全性依赖于多层隔离机制的协同工作,同时需要用户遵循最佳实践。
diff --git a/18_observability/elk.md b/18_observability/elk.md
index 8373b16..622cf8a 100644
--- a/18_observability/elk.md
+++ b/18_observability/elk.md
@@ -1,8 +1,8 @@
-## ELK/EFK 堆栈
+## 18.2 ELK/EFK 堆栈
ELK (Elasticsearch,Logstash,Kibana) 是目前业界最流行的开源日志解决方案。而在容器领域,由于 Fluentd 更加轻量级且对容器支持更好,EFK (Elasticsearch,Fluentd,Kibana) 组合也变得非常流行。
-### 方案架构
+### 18.2.1 方案架构
我们将采用以下架构:
@@ -11,7 +11,7 @@ ELK (Elasticsearch,Logstash,Kibana) 是目前业界最流行的开源日志
3. **Elasticsearch**:存储从 Fluentd 接收到的日志数据。
4. **Kibana**:从 Elasticsearch 读取数据并进行可视化展示。
-### 部署流程
+### 18.2.2 部署流程
我们将使用 Docker Compose 来一键部署整个日志堆栈。
@@ -125,6 +125,6 @@ docker run -d \
4. 选择 `@timestamp` 作为时间字段。
5. 去 **Discover** 页面,你就能看到 Nginx 容器的日志了。
-### 总结
+### 18.2.3 总结
通过 Docker 的日志驱动机制,结合 ELK/EFK 强大的收集和分析能力,我们可以轻松构建一个能够处理海量日志的监控平台,这对于排查生产问题至关重要。
diff --git a/18_observability/logs_README.md b/18_observability/logs_README.md
index f53f973..9fd5d1c 100644
--- a/18_observability/logs_README.md
+++ b/18_observability/logs_README.md
@@ -2,7 +2,7 @@
在容器化环境中,日志管理比传统环境更为复杂。容器是短暂的,意味着容器内的日志文件可能会随着容器的销毁而丢失。因此,我们需要一种集中式的日志管理方案来收集、存储和分析容器日志。
-## Docker 日志驱动
+## 18.3 Docker 日志驱动
Docker 提供了多种日志驱动 (Log Driver) 机制,允许我们将容器日志转发到不同的后端。
@@ -15,7 +15,7 @@ Docker 提供了多种日志驱动 (Log Driver) 机制,允许我们将容器
* `gelf`:支持 GELF 协议的日志后端 (如 Graylog)。
* `awslogs`:发送到 Amazon CloudWatch Logs。
-## 日志管理方案
+## 18.3 日志管理方案
对于大规模的容器集群,我们通常会采用 EFK (Elasticsearch + Fluentd + Kibana) 或 ELK (Elasticsearch + Logstash + Kibana) 方案。
diff --git a/18_observability/prometheus.md b/18_observability/prometheus.md
index 0ae9588..7f6a4f2 100644
--- a/18_observability/prometheus.md
+++ b/18_observability/prometheus.md
@@ -1,10 +1,10 @@
-## Prometheus + Grafana
+## 18.1 Prometheus + Grafana
Prometheus 和 Grafana 是目前最流行的开源监控组合,前者负责数据采集与存储,后者负责数据可视化。
[Prometheus](https://prometheus.io/) 是一个开源的系统监控和报警工具包。它受 Google Borgmon 的启发,由 SoundCloud 在 2012 年创建。
-### 架构简介
+### 18.1.1 架构简介
Prometheus 的主要组件包括:
@@ -13,7 +13,7 @@ Prometheus 的主要组件包括:
* **Alertmanager**:处理报警发送。
* **Pushgateway**:用于支持短生命周期的 Job 推送数据。
-### 快速部署
+### 18.1.2 快速部署
我们可以使用 Docker Compose 快速部署一套 Prometheus + Grafana 监控环境。
@@ -101,7 +101,7 @@ $ docker compose up -d
* Prometheus: `http://localhost:9090`
* Grafana:`http://localhost:3000` (默认账号密码:admin/admin)
-### 配置 Grafana 面板
+### 18.1.3 配置 Grafana 面板
1. 在 Grafana 中添加 Prometheus 数据源,URL 填写 `http://prometheus:9090`。
2. 导入现成的 Dashboard 模板,例如 [Node Exporter Full](https://grafana.com/grafana/dashboards/1860) (ID:1860) 和 [Docker Container](https://grafana.com/grafana/dashboards/193) (ID:193)。
diff --git a/19_cases/ci/actions/README.md b/19_cases/ci/actions/README.md
index 302e0e3..78be38f 100644
--- a/19_cases/ci/actions/README.md
+++ b/19_cases/ci/actions/README.md
@@ -23,10 +23,10 @@ jobs:
args: go version
```
-## 概述
+## 19.9 概述
总体概述了以下内容。
-## 参考资料
+## 19.9 参考资料
* [Actions Docs](https://docs.github.com/en/actions)
diff --git a/19_cases/ci/devops_workflow.md b/19_cases/ci/devops_workflow.md
index 26aa575..93a8088 100644
--- a/19_cases/ci/devops_workflow.md
+++ b/19_cases/ci/devops_workflow.md
@@ -1,8 +1,8 @@
-## DevOps 工作流完整示例
+## 19.8 DevOps 工作流完整示例
本章将演示一个基于 Docker,Kubernetes 和 Jenkins/GitLab CI 的完整 DevOps 工作流。
-### 工作流概览
+### 19.8.1 工作流概览
1. **Code**:开发人员提交代码到 GitLab。
2. **Build**:GitLab CI 触发构建任务。
@@ -12,7 +12,7 @@
6. **Verify**:人工或自动化验证。
7. **Release (Production)**:审批后自动部署到生产环境。
-### 关键配置示例
+### 19.8.2 关键配置示例
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
@@ -79,7 +79,7 @@ deploy_staging:
- develop
```
-### 最佳实践
+### 19.8.3 最佳实践
1. **不可变基础设施**:一旦镜像构建完成,在各个环境 (Dev,Staging,Prod) 中都应该使用同一个镜像 tag (通常是 commit hash),而不是重新构建。
2. **配置分离**:使用 ConfigMap 和 Secret 管理环境特定的配置,不要打包进镜像。
diff --git a/19_cases/ci/drone/README.md b/19_cases/ci/drone/README.md
index 1f392ef..0563c34 100644
--- a/19_cases/ci/drone/README.md
+++ b/19_cases/ci/drone/README.md
@@ -6,13 +6,13 @@
本小节以 `GitHub` + `Drone` 来演示 `Drone` 的工作流程。当然在实际开发过程中,你的代码也许不在 GitHub 托管,那么你可以尝试使用 `Gogs` + `Drone` 来进行 `CI/CD`。
-## Drone 关联项目
+## 19.10 Drone 关联项目
在 Github 新建一个名为 `drone-demo` 的仓库。
打开我们已经[部署好的 Drone 网站](install.md)或者 [Drone Cloud](https://cloud.drone.io),使用 GitHub 账号登录,在界面中关联刚刚新建的 `drone-demo` 仓库。
-## 编写项目源代码
+## 19.10 编写项目源代码
初始化一个 git 仓库
@@ -72,7 +72,7 @@ trigger:
└── app.go
```
-## 推送项目源代码到 GitHub
+## 19.10 推送项目源代码到 GitHub
运行以下命令:
@@ -84,7 +84,7 @@ $ git commit -m "test drone ci"
$ git push origin master
```
-## 查看项目构建过程及结果
+## 19.10 查看项目构建过程及结果
打开我们部署好的 `Drone` 网站或者 Drone Cloud,即可看到构建结果。
@@ -94,7 +94,7 @@ $ git push origin master
本书 GitBook 也使用 Drone 进行 CI/CD,具体配置信息请查看本书根目录 [`.drone.yml`](https://github.com/yeasy/docker_practice/blob/master/.drone.yml) 文件。
-## 参考链接
+## 19.10 参考链接
* [Drone Github](https://github.com/drone/drone)
* [Drone 文档](https://docs.drone.io/)
diff --git a/19_cases/ci/drone/demo/README.md b/19_cases/ci/drone/demo/README.md
index cea50f3..3d63ebb 100644
--- a/19_cases/ci/drone/demo/README.md
+++ b/19_cases/ci/drone/demo/README.md
@@ -2,13 +2,13 @@
这是一个基于 Go 语言编写的简单 Web 应用示例,用于演示 Drone CI 的持续集成流程。
-## 目录结构
+## 19.12 目录结构
* `app.go`:简单的 Go Web 服务器代码。
* `.drone.yml`:Drone CI 的配置文件,定义了构建和测试流程。
* `Dockerfile`:定义了如何将该应用构建为 Docker 镜像。
-## 如何运行
+## 19.12 如何运行
1. 确保本地已安装 Docker 环境。
2. 进入本目录构建镜像:
diff --git a/19_cases/ci/drone/install.md b/19_cases/ci/drone/install.md
index e605062..ed05414 100644
--- a/19_cases/ci/drone/install.md
+++ b/19_cases/ci/drone/install.md
@@ -1,8 +1,8 @@
-## 部署 Drone
+## 19.11 部署 Drone
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 要求
+### 19.11.1 要求
* 拥有公网 IP、域名 (如果你不满足要求,可以尝试在本地使用 Gogs + Drone)
@@ -14,7 +14,7 @@
* 对 `CI/CD` 有一定了解
-### 新建 GitHub 应用
+### 19.11.2 新建 GitHub 应用
登录 GitHub,在 https://github.com/settings/applications/new 新建一个应用。
@@ -22,7 +22,7 @@
接下来查看这个应用的详情,记录 `Client ID` 和 `Client Secret`,之后配置 Drone 会用到。
-### 配置 Drone
+### 19.11.3 配置 Drone
我们通过使用 `Docker Compose` 来启动 `Drone`,编写 `compose.yaml` (或 `docker-compose.yml`) 文件。
diff --git a/19_cases/ide/vsCode.md b/19_cases/ide/vsCode.md
index 446b480..e6d062d 100644
--- a/19_cases/ide/vsCode.md
+++ b/19_cases/ide/vsCode.md
@@ -1,11 +1,11 @@
-## VS Code 中使用 Docker
+## 19.14 VS Code 中使用 Docker
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 概述
+### 19.14.1 概述
总体概述了以下内容。
-### 将 Docker 容器作为远程开发环境
+### 19.14.2 将 Docker 容器作为远程开发环境
无需本地安装开发工具,直接将 Docker 容器作为开发环境,具体参考[官方文档](https://code.visualstudio.com/docs/remote/containers)。
diff --git a/19_cases/os/alpine.md b/19_cases/os/alpine.md
index 7918b95..9432316 100644
--- a/19_cases/os/alpine.md
+++ b/19_cases/os/alpine.md
@@ -1,8 +1,8 @@
-## Alpine
+## 19.3 Alpine
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 简介
+### 19.3.1 简介
下图直观地展示了本节内容:
@@ -28,7 +28,7 @@ ubuntu latest b39b81afc8ca 188.3 MB
centos latest 8efe422e6104 210 MB
```
-### 获取并使用官方镜像
+### 19.3.2 获取并使用官方镜像
由于镜像很小,下载时间往往很短,读者可以直接使用 `docker run` 指令直接运行一个 `Alpine` 容器,并指定运行的 Linux 指令,例如:
@@ -37,7 +37,7 @@ $ docker run alpine echo '123'
123
```
-### 迁移至 Alpine 基础镜像
+### 19.3.3 迁移至 Alpine 基础镜像
目前,大部分 Docker 官方镜像都已经支持 `Alpine` 作为基础镜像,可以很容易进行迁移。
@@ -67,7 +67,7 @@ RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories
&& apk add --no-cache
```
-### 相关资源
+### 19.3.4 相关资源
* `Alpine` 官网:https://www.alpinelinux.org/
* `Alpine` 官方仓库:https://github.com/alpinelinux
diff --git a/19_cases/os/busybox.md b/19_cases/os/busybox.md
index f135b7b..766eed6 100644
--- a/19_cases/os/busybox.md
+++ b/19_cases/os/busybox.md
@@ -1,8 +1,8 @@
-## Busybox
+## 19.2 Busybox
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### 简介
+### 19.2.1 简介
下图直观地展示了本节内容:
@@ -13,7 +13,7 @@
`BusyBox` 可运行于多款 `POSIX` 环境的操作系统中,如 `Linux` (包括 `Android`)、`Hurd`、`FreeBSD` 等。
-### 获取官方镜像
+### 19.2.2 获取官方镜像
可以使用 `docker pull` 指令下载 `busybox:latest` 镜像:
@@ -34,7 +34,7 @@ REPOSITORY TAG IMAGE ID CREATED
busybox latest e72ac664f4f0 6 weeks ago 2.433 MB
```
-### 运行 busybox
+### 19.2.3 运行 busybox
启动一个 `busybox` 容器,并在容器中执行 `grep` 命令。
@@ -112,7 +112,7 @@ tmpfs on /sys/firmware type tmpfs (ro,relatime)
`busybox` 镜像虽然小巧,但包括了大量常见的 `Linux` 命令,读者可以用它快速熟悉 `Linux` 命令。
-### 相关资源
+### 19.2.4 相关资源
* `Busybox` 官网:https://busybox.net/
* `Busybox` 官方仓库:https://git.busybox.net/busybox/
diff --git a/19_cases/os/centos.md b/19_cases/os/centos.md
index 05c875b..38d1c48 100644
--- a/19_cases/os/centos.md
+++ b/19_cases/os/centos.md
@@ -1,8 +1,8 @@
-## CentOS 和 Fedora
+## 19.5 CentOS 和 Fedora
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
-### CentOS 系统简介
+### 19.5.1 CentOS 系统简介
`CentOS` 和 `Fedora` 都是基于 `Redhat` 的常见 Linux 分支。`CentOS` 是目前企业级服务器的常用操作系统;`Fedora` 则主要面向个人桌面用户。
@@ -35,7 +35,7 @@ Status: Downloaded newer image for centos:7
CentOS Linux release 7.9.2009 (Core)
```
-### Fedora 系统简介
+### 19.5.2 Fedora 系统简介
下图直观地展示了本节内容:
@@ -64,7 +64,7 @@ Fedora release 39 (Thirty Nine)
```
-### 相关资源
+### 19.5.3 相关资源
* `Fedora` 官网:https://getfedora.org/
* `Fedora` 官方仓库:https://github.com/fedora-infra
diff --git a/19_cases/os/debian.md b/19_cases/os/debian.md
index 89fbab9..d3cca95 100644
--- a/19_cases/os/debian.md
+++ b/19_cases/os/debian.md
@@ -1,8 +1,8 @@
-## Debian Ubuntu
+## 19.4 Debian Ubuntu
`Debian` 和 `Ubuntu` 都是目前较为流行的 **Debian 系** 的服务器操作系统,十分适合研发场景。`Docker Hub` 上提供了官方镜像,国内各大容器云服务也基本都提供了相应的支持。
-### Debian 系统简介
+### 19.4.1 Debian 系统简介
下图直观地展示了本节内容:
@@ -34,7 +34,7 @@ Debian GNU/Linux 8
`Debian` 镜像很适合作为基础镜像,构建自定义镜像。
-### Ubuntu 系统简介
+### 19.4.2 Ubuntu 系统简介
下图直观地展示了本节内容:
@@ -143,7 +143,7 @@ root@7d93de07bf76:/# curl 127.0.0.1
配合使用 `-p` 参数对外映射服务端口,可以允许容器外来访问该服务。
-### 相关资源
+### 19.4.3 相关资源
* `Debian` 官网:https://www.debian.org/
* `Neuro Debian` 官网:http://neuro.debian.net/
diff --git a/19_cases/os/summary.md b/19_cases/os/summary.md
index 227bcdf..0a1ad25 100644
--- a/19_cases/os/summary.md
+++ b/19_cases/os/summary.md
@@ -1,4 +1,4 @@
-## 本章小结
+## 19.6 本章小结
本章讲解了典型操作系统镜像的下载和使用。
diff --git a/README.md b/README.md
index da051da..324e1b2 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
[](https://github.com/yeasy/docker_practice) [](https://github.com/yeasy/docker_practice/releases) [](https://docs.docker.com/engine/release-notes/) [][1]
-**v1.5.6**
+**v1.5.7**
[Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松!
@@ -26,8 +26,6 @@
### 在线阅读
-> 推荐访问官方 GitBook,体验最佳。
-
* **GitBook**: [yeasy.gitbook.io/docker_practice](https://yeasy.gitbook.io/docker_practice/)
* **GitHub**: [github.com/yeasy/docker_practice](https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md)
* **Mirror**: [docker-practice.com](https://vuepress.mirror.docker-practice.com/)
diff --git a/appendix/20.1_best_practices.md b/appendix/20.1_best_practices.md
index f0a9ba6..9fbd2ff 100644
--- a/appendix/20.1_best_practices.md
+++ b/appendix/20.1_best_practices.md
@@ -1,4 +1,4 @@
-## 16.1 Dockerfile 最佳实践
+## Dockerfile 最佳实践
本附录是笔者对 Docker 官方文档中 [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) 的理解与翻译。
diff --git a/appendix/20.2_debug.md b/appendix/20.2_debug.md
index b5418a7..85c0dfd 100644
--- a/appendix/20.2_debug.md
+++ b/appendix/20.2_debug.md
@@ -1,4 +1,4 @@
-## 16.2 如何调试 Docker
+## 如何调试 Docker
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/appendix/20.3_resources.md b/appendix/20.3_resources.md
index e5be1f4..5d6713c 100644
--- a/appendix/20.3_resources.md
+++ b/appendix/20.3_resources.md
@@ -1,4 +1,4 @@
-## 16.3 资源链接
+## 资源链接
本节涵盖了相关内容与详细描述,主要探讨以下几个方面:
diff --git a/appendix/20.4_terminology.md b/appendix/20.4_terminology.md
index 5e98f83..5dd7796 100644
--- a/appendix/20.4_terminology.md
+++ b/appendix/20.4_terminology.md
@@ -1,4 +1,4 @@
-## 16.4 术语词表 (出版统一版)
+## 术语词表 (出版统一版)
本词表用于统一全书术语、缩写和命令表达,适用于最终出版前清稿。
diff --git a/appendix/20.5_editorial_style.md b/appendix/20.5_editorial_style.md
index 34907c6..8fde56b 100644
--- a/appendix/20.5_editorial_style.md
+++ b/appendix/20.5_editorial_style.md
@@ -1,4 +1,4 @@
-## 16.5 出版清稿规范 (图号与章节风格)
+## 出版清稿规范 (图号与章节风格)
本规范用于最终出版前清稿,确保全书图号、图题、章节结构与行文风格一致。
diff --git a/format_headings.py b/format_headings.py
new file mode 100644
index 0000000..0f9abdb
--- /dev/null
+++ b/format_headings.py
@@ -0,0 +1,250 @@
+import os
+import re
+
+ENG_ALLOWLIST = {
+ 'DOCKER', 'KUBERNETES', 'XML', 'LLM', 'RAG', 'LINUX', 'UBUNTU', 'MAC', 'MACOS',
+ 'WINDOWS', 'API', 'JSON', 'YAML', 'REGISTRY', 'HUB', 'REPOSITORY', 'TAG', 'IMAGE',
+ 'CONTAINER', 'DEBIAN', 'FEDORA', 'CENTOS', 'RASPBERRY', 'PI', 'PULL', 'LIST',
+ 'RM', 'COMMIT', 'BUILD', 'RUN', 'DAEMON', 'STOP', 'NEXUS', 'VOLUMES', 'TMPFS',
+ 'DNS', 'PORT', 'BUILDX', 'BUILDKIT', 'COMPOSE', 'DJANGO', 'RAILS', 'WORDPRESS',
+ 'LNMP', 'NAMESPACE', 'CGROUPS', 'UFS', 'PODMAN', 'PROMETHEUS', 'ELK', 'BUSYBOX',
+ 'ALPINE', 'DEVOPS', 'ACTIONS', 'DRONE', 'IDE', 'VS', 'CODE', 'NGINX', 'PHP',
+ 'NODE.JS', 'MYSQL', 'MONGODB', 'REDIS', 'MINIO', 'DOCKERD', 'TENCENTCLOUD',
+ 'ALICLOUD', 'AWS', 'COREOS', 'KUBEADM', 'CONTAINERD', 'DESKTOP', 'KIND', 'K3S',
+ 'SYSTEMD', 'DASHBOARD', 'KUBECTL', 'ETCD', 'ETCDCTL', 'VM', 'VAGRANT', 'LXC',
+ 'GITHUB', 'GOOGLE', 'CLOUD', 'NPM', 'MAVEN', 'ACR', 'TCR', 'ECR', 'HARBOR',
+ 'CNCF', 'SIGSTORE', 'NOTATION', 'SCOUT', 'TRIVY', 'CMD', 'ENTRYPOINT', 'ENV', 'ARG',
+ 'VOLUME', 'EXPOSE', 'WORKDIR', 'USER', 'HEALTHCHECK', 'ONBUILD', 'LABEL', 'SHELL',
+ 'COPY', 'ADD', 'DOCKERFILE', 'CI', 'CD', 'OS'
+}
+
+def parse_summary():
+ if not os.path.exists('SUMMARY.md'):
+ return {}
+ with open('SUMMARY.md', 'r', encoding='utf-8') as f:
+ content = f.read()
+
+ file_to_context = {}
+ chapter_idx = 0
+ section_idx = 0
+ is_appendix = False
+
+ for line in content.split('\n'):
+ if '## 附录' in line or '附录' in line and line.startswith('## '):
+ is_appendix = True
+
+ m_chap = re.match(r'^\* \[(第[一二三四五六七八九十百]+章[^\]]*)\]\((.*?)\)', line)
+ if m_chap:
+ title = m_chap.group(1).replace(' ', ':', 1)
+ if ':' not in title:
+ title = title.replace('章', '章:')
+ filepath = m_chap.group(2)
+ chapter_idx += 1
+ section_idx = 0
+ file_to_context[filepath] = {
+ 'level': 1,
+ 'title': title,
+ 'chap_num': chapter_idx,
+ 'is_app': False
+ }
+ continue
+
+ m_sec = re.match(r'^\s+\* \[(.*?)\]\((.*?)\)', line)
+ if m_sec:
+ title = m_sec.group(1)
+ filepath = m_sec.group(2)
+ section_idx += 1
+
+ if is_appendix or 'appendix' in filepath:
+ file_to_context[filepath] = {
+ 'level': 2,
+ 'title': title,
+ 'is_app': True
+ }
+ else:
+ file_to_context[filepath] = {
+ 'level': 2,
+ 'title': title,
+ 'chap_num': chapter_idx,
+ 'sec_num': section_idx,
+ 'is_app': False
+ }
+
+ m_app = re.match(r'^\* \[(附录[^\]]*)\]\((.*?)\)', line)
+ if m_app:
+ title = m_app.group(1)
+ filepath = m_app.group(2)
+ file_to_context[filepath] = {
+ 'level': 1,
+ 'title': title,
+ 'is_app': True
+ }
+ continue
+
+ return file_to_context
+
+def check_english(title):
+ words = re.findall(r'[a-zA-Z\.]+', title)
+ for w in words:
+ if w.upper() not in ENG_ALLOWLIST and w.upper() != 'DOCKER':
+ print(f" [!] Notice: English word '{w}' in title: {title}")
+
+def process_file(filepath, context):
+ try:
+ with open(filepath, 'r', encoding='utf-8') as f:
+ lines = f.readlines()
+ except Exception as e:
+ print(f"Error reading {filepath}: {e}")
+ return False
+
+ headings = []
+ in_code_block = False
+ for i, line in enumerate(lines):
+ line_stripped = line.strip()
+ if line_stripped.startswith('```'):
+ in_code_block = not in_code_block
+
+ if not in_code_block:
+ match = re.match(r'^(#{1,6})\s+(.*)', line)
+ if match:
+ level = len(match.group(1))
+ title = match.group(2).strip()
+ headings.append({'level': level, 'title': title, 'line_idx': i, 'children': []})
+
+ for i, h in enumerate(headings):
+ level = h['level']
+ for j in range(i+1, len(headings)):
+ if headings[j]['level'] <= level:
+ break
+ if headings[j]['level'] == level + 1:
+ h['children'].append(j)
+
+ actions = {}
+
+ def has_text_between(start_idx, end_idx):
+ for text_ln in range(start_idx + 1, end_idx):
+ content = lines[text_ln].strip()
+ if content and not content.startswith('#'):
+ return True
+ return False
+
+ is_app = context.get('is_app', False)
+ chap_num = context.get('chap_num', 0)
+ sec_num = context.get('sec_num', 0)
+
+ h2_counter = sec_num if sec_num > 0 else 0
+ h3_counter = 0
+
+ for i, h in enumerate(headings):
+ level = h['level']
+ title = h['title']
+ ln = h['line_idx']
+
+ original_title = title
+ check_english(title)
+
+ if level == 1:
+ if not is_app and chap_num > 0:
+ pass
+ elif is_app:
+ title = re.sub(r'^[\d\.]+\s*', '', title)
+ m = re.match(r'^(附录[一二三四五六七八九十]*)\s*(.*)', title)
+ if m:
+ p1 = m.group(1).strip()
+ p2 = m.group(2).strip()
+ if p2.startswith(':') or p2.startswith(':'):
+ p2 = p2[1:].strip()
+ title = f"{p1}:{p2}" if p2 else p1
+
+ elif level == 2:
+ if not is_app:
+ clean_title = re.sub(r'^[\d\.]+\s*', '', title)
+ title = f"{chap_num}.{h2_counter} {clean_title}" if h2_counter > 0 else clean_title
+ else:
+ title = re.sub(r'^[\d\.]+\s*', '', title)
+ h3_counter = 0
+
+ elif level == 3:
+ h3_counter += 1
+ if not is_app:
+ clean_title = re.sub(r'^[\d\.]+\s*', '', title)
+ if h2_counter > 0:
+ title = f"{chap_num}.{h2_counter}.{h3_counter} {clean_title}"
+ else:
+ title = re.sub(r'^[\d\.]+\s*', '', title)
+
+ elif level >= 4:
+ m = re.match(r'^([\d\.]+)\s+(.*)', title)
+ if m:
+ nums = m.group(1)
+ rest = m.group(2)
+ if '.' in nums.strip('.'):
+ title = rest
+
+ if title != original_title:
+ actions[ln] = f"{'#' * level} {title}\n"
+ h['title'] = title
+
+ children_indices = h['children']
+ if len(children_indices) == 1:
+ child_idx = children_indices[0]
+ child_h = headings[child_idx]
+ child_ln = child_h['line_idx']
+ child_title = child_h['title']
+
+ if child_ln in actions:
+ modified_line = actions[child_ln]
+ m_child = re.match(r'^(#{1,6})\s+(.*)', modified_line)
+ if m_child:
+ child_title = m_child.group(2).strip()
+
+ actions[child_ln] = f"**{child_title}**\n\n"
+
+ elif len(children_indices) >= 2:
+ child_idx = children_indices[0]
+ child_ln = headings[child_idx]['line_idx']
+ if not has_text_between(ln, child_ln):
+ if level < 4:
+ if ln in actions:
+ actions[ln] = actions[ln].rstrip() + "\n\n涵盖了如下重点内容:\n\n"
+ else:
+ actions[ln] = lines[ln].rstrip() + "\n\n涵盖了如下重点内容:\n\n"
+
+ if not actions:
+ return False
+
+ new_lines = []
+ for i, line in enumerate(lines):
+ if i in actions:
+ if actions[i].startswith('**'):
+ pass
+ new_lines.append(actions[i])
+ else:
+ new_lines.append(line)
+
+ with open(filepath, 'w', encoding='utf-8') as f:
+ f.writelines(new_lines)
+ return True
+
+if __name__ == "__main__":
+ file_contexts = parse_summary()
+ modified = 0
+ for filepath, context in file_contexts.items():
+ if os.path.exists(filepath):
+ if process_file(filepath, context):
+ modified += 1
+ print(f" -> MODIFIED: {filepath}")
+
+ for root, dirs, files in os.walk('.'):
+ if '.git' in root or 'node_modules' in root or '.gemini' in root:
+ continue
+ for file in files:
+ if file.endswith('.md') and file not in ['SUMMARY.md', 'README.md', 'CONTRIBUTING.md', 'CHANGELOG.md']:
+ filepath = os.path.join(root, file)
+ clean_path = filepath.replace('./', '')
+ if clean_path not in file_contexts:
+ if process_file(clean_path, {'is_app': True}):
+ modified += 1
+ print(f" -> MODIFIED: {clean_path}")
+
+ print(f"\nTotal Modified {modified} files")
diff --git a/format_report.txt b/format_report.txt
new file mode 100644
index 0000000..6e41aff
--- /dev/null
+++ b/format_report.txt
@@ -0,0 +1 @@
+Total issues found: 0