diff --git a/01_introduction/1.3_why.md b/01_introduction/1.3_why.md
index b849f78..6b6f7b4 100644
--- a/01_introduction/1.3_why.md
+++ b/01_introduction/1.3_why.md
@@ -179,7 +179,7 @@ flowchart TD
end
Redis["Redis 容器"]
DB["PostgreSQL 容器"]
-
+
Frontend --> API
API --> Redis
API --> DB
diff --git a/02_basic_concept/2.1_image.md b/02_basic_concept/2.1_image.md
index b39c161..5d1e87f 100644
--- a/02_basic_concept/2.1_image.md
+++ b/02_basic_concept/2.1_image.md
@@ -16,12 +16,12 @@ flowchart TD
direction TB
App["应用程序、工具、库、配置文件...
(这部分被打包成 Docker 镜像)"]
end
-
+
subgraph KernelSpace ["Linux 内核"]
direction TB
Kernel["容器共享宿主机的内核"]
end
-
+
UserSpace --- KernelSpace
```
对于 Linux 而言,内核启动后会挂载 `root` 文件系统来提供用户空间支持。**Docker 镜像** 本质上就是一个 `root` 文件系统。
@@ -63,7 +63,7 @@ flowchart TD
AppB_Trad["App B
Ubuntu 500MB"]
AppC_Trad["App C
Ubuntu 500MB"]
end
-
+
subgraph DockerLayered ["Docker 分层方式 总计: 620MB ✅"]
direction TB
subgraph Apps ["应用层"]
@@ -73,7 +73,7 @@ flowchart TD
AppC["App C 40MB"]
end
Ubuntu["Ubuntu
(共享)500MB"]
-
+
AppA --> Ubuntu
AppB --> Ubuntu
AppC --> Ubuntu
@@ -98,7 +98,7 @@ flowchart TD
Layer3["第 3 层: nginx 安装文件 (只读)"]
Layer2["第 2 层: apt 缓存更新 (只读)"]
Layer1["第 1 层: Ubuntu 基础系统 (只读)
← 基础镜像层"]
-
+
Layer4 --> Layer3 --> Layer2 --> Layer1
```
每一层的特点:
diff --git a/02_basic_concept/2.2_container.md b/02_basic_concept/2.2_container.md
index bb55dbf..5fd9669 100644
--- a/02_basic_concept/2.2_container.md
+++ b/02_basic_concept/2.2_container.md
@@ -20,7 +20,7 @@ flowchart TD
direction TB
N1["• 共享系统资源
• 共享网络
• 共享文件系统"]
end
-
+
subgraph ContainerProcess ["容器进程 (运行在宿主机内核上)"]
direction TB
C1["• 独立进程空间
• 独立网络环境
• 独立文件系统
• 独立用户空间"]
@@ -51,7 +51,7 @@ flowchart TD
VMHW[Hardware]
VMApp --> VMGuest --> V --> VMH --> VMHW
end
-
+
subgraph Container ["容器 (所有容器共享宿主机内核)"]
direction TB
subgraph CApp ["应用层"]
@@ -89,7 +89,7 @@ flowchart TD
ImageLayerN1["镜像第 N-1 层(只读)"]
Dots["..."]
ImageLayer1["镜像第 1 层(只读)
基础镜像层"]
-
+
ContainerLayer --> ImageLayerN --> ImageLayerN1 --> Dots --> ImageLayer1
```
@@ -157,11 +157,11 @@ stateDiagram-v2
Running --> Stopped : docker stop
Running --> Paused : docker pause
Paused --> Running : docker unpause
-
+
Created --> Deleted : docker rm
Stopped --> Deleted : docker rm
Paused --> Deleted : docker rm
-
+
Deleted --> [*]
```
图 2-1:容器生命周期状态流转图
diff --git a/03_install/3.1_ubuntu.md b/03_install/3.1_ubuntu.md
index 07e9c2a..ec42e8d 100644
--- a/03_install/3.1_ubuntu.md
+++ b/03_install/3.1_ubuntu.md
@@ -113,7 +113,7 @@ $ sudo systemctl start docker
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
> ⚠️ **安全警告:`docker` 用户组等同于 `root` 权限**
->
+>
> 将用户加入 `docker` 组免去了每次执行 `docker` 命令时输入 `sudo` 的繁琐,但这也意味着该用户可以轻易获取主机的最高 root 权限(例如通过挂载根目录运行容器)。
> 如果你在一个多用户共享的生产系统上配置,切勿随意将普通用户加入此组。此时,更安全的替代方案是使用官方提供的 **[Rootless 模式 (Rootless mode)](https://docs.docker.com/engine/security/rootless/)**,它允许在没有任何 root 权限的情况下运行 Docker 守护进程和容器。
diff --git a/03_install/3.2_debian.md b/03_install/3.2_debian.md
index d2c63b6..aa38526 100644
--- a/03_install/3.2_debian.md
+++ b/03_install/3.2_debian.md
@@ -104,7 +104,7 @@ $ sudo systemctl start docker
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
> ⚠️ **安全警告:`docker` 用户组等同于 `root` 权限**
->
+>
> 将用户加入 `docker` 组免去了每次执行 `docker` 命令时输入 `sudo` 的繁琐,但这也意味着该用户可以轻易获取主机的最高 root 权限(例如通过挂载根目录运行容器)。
> 如果你在一个多用户共享的生产系统上配置,切勿随意将普通用户加入此组。此时,更安全的替代方案是使用官方提供的 **[Rootless 模式 (Rootless mode)](https://docs.docker.com/engine/security/rootless/)**,它允许在没有任何 root 权限的情况下运行 Docker 守护进程和容器。
diff --git a/03_install/3.3_fedora.md b/03_install/3.3_fedora.md
index e07d078..5d0fd05 100644
--- a/03_install/3.3_fedora.md
+++ b/03_install/3.3_fedora.md
@@ -115,7 +115,7 @@ $ sudo systemctl start docker
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
> ⚠️ **安全警告:`docker` 用户组等同于 `root` 权限**
->
+>
> 将用户加入 `docker` 组免去了每次执行 `docker` 命令时输入 `sudo` 的繁琐,但这也意味着该用户可以轻易获取主机的最高 root 权限(例如通过挂载根目录运行容器)。
> 如果你在一个多用户共享的生产系统上配置,切勿随意将普通用户加入此组。此时,更安全的替代方案是使用官方提供的 **[Rootless 模式 (Rootless mode)](https://docs.docker.com/engine/security/rootless/)**,它允许在没有任何 root 权限的情况下运行 Docker 守护进程和容器。
diff --git a/03_install/3.4_centos.md b/03_install/3.4_centos.md
index 5ddbb7d..3a781d6 100644
--- a/03_install/3.4_centos.md
+++ b/03_install/3.4_centos.md
@@ -122,7 +122,7 @@ $ sudo systemctl start docker
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
> ⚠️ **安全警告:`docker` 用户组等同于 `root` 权限**
->
+>
> 将用户加入 `docker` 组免去了每次执行 `docker` 命令时输入 `sudo` 的繁琐,但这也意味着该用户可以轻易获取主机的最高 root 权限(例如通过挂载根目录运行容器)。
> 如果你在一个多用户共享的生产系统上配置,切勿随意将普通用户加入此组。此时,更安全的替代方案是使用官方提供的 **[Rootless 模式 (Rootless mode)](https://docs.docker.com/engine/security/rootless/)**,它允许在没有任何 root 权限的情况下运行 Docker 守护进程和容器。
diff --git a/03_install/3.5_raspberry-pi.md b/03_install/3.5_raspberry-pi.md
index fccece0..49d41b4 100644
--- a/03_install/3.5_raspberry-pi.md
+++ b/03_install/3.5_raspberry-pi.md
@@ -73,7 +73,7 @@ Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/softwareproperties/SoftwareProperties.py", line 109, in __init__
self.reload_sourceslist()
File "/usr/lib/python3/dist-packages/softwareproperties/SoftwareProperties.py", line 599, in reload_sourceslist
- self.distro.get_sources(self.sourceslist)
+ self.distro.get_sources(self.sourceslist)
File "/usr/lib/python3/dist-packages/aptsources/distro.py", line 91, in get_sources
raise NoDistroTemplateException(
aptsources.distro.NoDistroTemplateException: Error: could not find a distribution template for Raspbian/bullseye
@@ -129,7 +129,7 @@ $ sudo systemctl start docker
默认情况下,`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 `root` 用户。因此,更好的做法是将需要使用 `docker` 的用户加入 `docker` 用户组。
> ⚠️ **安全警告:`docker` 用户组等同于 `root` 权限**
->
+>
> 将用户加入 `docker` 组免去了每次执行 `docker` 命令时输入 `sudo` 的繁琐,但这也意味着该用户可以轻易获取主机的最高 root 权限(例如通过挂载根目录运行容器)。
> 如果你在一个多用户共享的生产系统上配置,切勿随意将普通用户加入此组。此时,更安全的替代方案是使用官方提供的 **[Rootless 模式 (Rootless mode)](https://docs.docker.com/engine/security/rootless/)**,它允许在没有任何 root 权限的情况下运行 Docker 守护进程和容器。
diff --git a/03_install/3.6_offline.md b/03_install/3.6_offline.md
index bf1b845..494e26f 100644
--- a/03_install/3.6_offline.md
+++ b/03_install/3.6_offline.md
@@ -162,7 +162,7 @@ EOF
```bash
## 测试刚才的本地源,安装createrepo软件
-yum clean all
+yum clean all
yum install createrepo -y
```
diff --git a/04_image/4.3_rm.md b/04_image/4.3_rm.md
index 77c9a86..2bad114 100644
--- a/04_image/4.3_rm.md
+++ b/04_image/4.3_rm.md
@@ -93,19 +93,19 @@ Docker 会检测镜像是否有容器依赖或其他标签指向,只有在确
```mermaid
flowchart TD
Start(["docker rmi redis:alpine"]) --> Step1
-
+
subgraph Process ["删除流程"]
direction TB
Step1["1. Untag:移除 redis:alpine 标签"] --> Step2
-
+
Step2{"2. 检查是否还有其他标签指向此镜像"}
Step2 -- "有" --> Keep1["只 Untag,不删除"]
Step2 -- "无" --> Step3
-
+
Step3{"3. 检查是否有容器依赖"}
Step3 -- "有" --> Error["报错,无法删除"]
Step3 -- "无" --> Step4
-
+
Step4{"4. 从上到下逐层删除,检查每层是否被其他镜像使用"}
Step4 -- "被使用" --> Keep2["保留该层"]
Step4 -- "未使用" --> Delete["Deleted (删除该层)"]
@@ -172,7 +172,7 @@ $ docker image prune -a --filter "until=168h" # 7天前
```bash
$ docker rmi nginx
-Error: conflict: unable to remove repository reference "nginx"
+Error: conflict: unable to remove repository reference "nginx"
(must force) - container abc123 is using its referenced image
```
**解决方案**:
diff --git a/04_image/4.7_internal.md b/04_image/4.7_internal.md
index b478f23..06478d3 100644
--- a/04_image/4.7_internal.md
+++ b/04_image/4.7_internal.md
@@ -33,7 +33,7 @@ flowchart TD
L3["镜像层 (只读, Read-only Image Layer)"]
L2["镜像层 (只读, Read-only Image Layer)"]
L1["基础镜像层 (只读, Base Image Layer)"]
-
+
L4 --- L3 --- L2 --- L1
end
Note["所有的写操作都在容器层这里"] -.-> L4
diff --git a/05_container/5.1_run.md b/05_container/5.1_run.md
index 66b00c7..49fe108 100644
--- a/05_container/5.1_run.md
+++ b/05_container/5.1_run.md
@@ -62,14 +62,14 @@ root@af8bae53bdd3:/# exit # 退出容器
```mermaid
flowchart TD
Cmd["docker run ubuntu:24.04 /bin/echo 'Hello'"] --> Step1
-
+
Step1{"1. 检查本地是否有 ubuntu:24.04 镜像"}
Step1 -- 有 --> Step1_Yes["使用本地镜像"]
Step1 -- 无 --> Step1_No["从 Registry 下载"]
-
+
Step1_Yes --> Step2
Step1_No --> Step2
-
+
Step2["2. 创建容器
• 基于镜像的只读层
• 添加一层可读写层(容器存储层)"] --> Step3
Step3["3. 配置网络
• 创建虚拟网卡
• 分配 IP 地址
• 连接到 Docker 网桥"] --> Step4
Step4["4. 启动容器,执行指定命令"] --> Step5
diff --git a/05_container/5.3_stop.md b/05_container/5.3_stop.md
index f785065..c629246 100644
--- a/05_container/5.3_stop.md
+++ b/05_container/5.3_stop.md
@@ -155,11 +155,11 @@ stateDiagram-v2
Running --> Stopped : docker stop
Running --> Paused : docker pause
Paused --> Running : docker unpause
-
+
Created --> Deleted : docker rm
Stopped --> Deleted : docker rm
Paused --> Deleted : docker rm
-
+
Deleted --> [*]
```
---
diff --git a/05_container/5.4_attach_exec.md b/05_container/5.4_attach_exec.md
index 1027190..db30342 100644
--- a/05_container/5.4_attach_exec.md
+++ b/05_container/5.4_attach_exec.md
@@ -165,7 +165,7 @@ CONTAINER ID IMAGE STATUS NAMES
```bash
$ docker attach myubuntu
-root@243c32535da7:/#
+root@243c32535da7:/#
## 按 Ctrl+P 然后 Ctrl+Q
@@ -197,7 +197,7 @@ flowchart LR
end
NewProc["新进程"] -- 附加到 --> E_PID50
end
-
+
subgraph Attach ["docker attach"]
direction TB
subgraph Container2 ["容器"]
@@ -205,7 +205,7 @@ flowchart LR
end
MainProc["附加到主进程"] --> A_PID1
end
-
+
note1["退出 bash 不影响 nginx"]
note2["退出 bash 容器停止"]
Container1 -.-> note1
diff --git a/07_dockerfile/7.11_user.md b/07_dockerfile/7.11_user.md
index 62b07cc..8616486 100644
--- a/07_dockerfile/7.11_user.md
+++ b/07_dockerfile/7.11_user.md
@@ -21,7 +21,7 @@ flowchart LR
R_C["容器内 root"] -- 可能逃逸 --> R_H["宿主机 root"]
R_C -- 漏洞利用 --> R_Control["完全控制宿主机"]
end
-
+
subgraph NonRoot ["非 root 用户运行:"]
direction TB
NR_C["容器内普通用户"] -- 逃逸后 --> NR_H["宿主机普通用户"]
diff --git a/07_dockerfile/7.8_volume.md b/07_dockerfile/7.8_volume.md
index e3d16c0..1772e6f 100644
--- a/07_dockerfile/7.8_volume.md
+++ b/07_dockerfile/7.8_volume.md
@@ -25,7 +25,7 @@ flowchart LR
Result1["容器删除 = 数据丢失"]
Container1 ~~~ Result1
end
-
+
subgraph UseVolume ["使用 VOLUME:"]
direction TB
Container2["容器存储层
(只读/无状态)"]
diff --git a/08_data/8.1_volume.md b/08_data/8.1_volume.md
index 66b0614..e1b6d27 100644
--- a/08_data/8.1_volume.md
+++ b/08_data/8.1_volume.md
@@ -37,7 +37,7 @@ graph TD
Image[镜像层
ReadOnly]
Writable --- Image
end
-
+
Lifecycle[生命周期 = 容器生命周期] -.-> Container
Delete[容器删除] -->|导致| DataLost[数据丢失 ❌]
```
@@ -49,11 +49,11 @@ graph TD
subgraph Container [容器]
AppDir["/app/data"]
end
-
+
subgraph Volume [数据卷 my-data]
Data[持久化数据]
end
-
+
AppDir == 挂载 ==> Volume
Delete[容器删除] -.->|不会影响| Volume
```
diff --git a/08_data/8.2_bind-mounts.md b/08_data/8.2_bind-mounts.md
index 04820b7..08517b8 100644
--- a/08_data/8.2_bind-mounts.md
+++ b/08_data/8.2_bind-mounts.md
@@ -9,11 +9,11 @@ flowchart LR
subgraph Host ["宿主机"]
Dir1["/home/user/code/"]
end
-
+
subgraph Container ["容器"]
Dir2["/usr/share/nginx/html/"]
end
-
+
Dir1 <-->|Bind Mount| Dir2
```
目录结构(同一份文件):
@@ -210,7 +210,7 @@ $ docker inspect mycontainer --format '{{json .Mounts}}' | jq
```bash
$ docker run --mount type=bind,source=/not/exist,target=/app nginx
-docker: Error response from daemon: invalid mount config for type "bind":
+docker: Error response from daemon: invalid mount config for type "bind":
bind source path does not exist: /not/exist
```
**解决**:确保源路径存在,或改用 `-v` (会自动创建)
diff --git a/09_network/9.2_network_types.md b/09_network/9.2_network_types.md
index fd20155..642c1a5 100644
--- a/09_network/9.2_network_types.md
+++ b/09_network/9.2_network_types.md
@@ -15,7 +15,7 @@ ghi789... none null local
各网络类型的特点和适用场景如下:
| 网络类型 | 说明 | 适用场景 |
-|---------|------|---------|
+|---------|------|---------|
| **bridge** | 默认类型,容器连接到虚拟网桥 | 大多数单机场景 |
| **host** | 容器直接使用宿主机网络栈 | 需要最高网络性能时 |
| **none** | 禁用网络 | 完全隔离的容器 |
@@ -64,12 +64,12 @@ flowchart LR
direction LR
C1A["容器 A (172.17.0.2)"] --> D0A["docker0"] --> C1B["容器 B (172.17.0.3)"]
end
-
+
subgraph Comm2 ["访问外网"]
direction LR
C2A["容器 A (172.17.0.2)"] --> D0B["docker0"] --> Eth0A["eth0"] --> InternetA["互联网"]
end
-
+
subgraph Comm3 ["被外部访问,需端口映射"]
direction LR
Req["外部请求"] --> Eth0B["eth0"] --> D0C["docker0"] --> C3A["容器 A"]
diff --git a/09_network/9.3_custom_network.md b/09_network/9.3_custom_network.md
index d35d358..c2ae68c 100644
--- a/09_network/9.3_custom_network.md
+++ b/09_network/9.3_custom_network.md
@@ -7,7 +7,7 @@
默认 bridge 网络存在以下局限,而自定义网络可以很好地解决这些问题:
| 问题 | 自定义网络的优势 |
-|------|-----------------|
+|------|-----------------|
| 只能用 IP 通信 | 支持容器名 DNS 解析 |
| 所有容器在同一网络 | 更好的隔离性 |
| 需要 --link (已废弃)| 原生支持服务发现 |
diff --git a/09_network/9.6_network_isolation.md b/09_network/9.6_network_isolation.md
index 3df6fbc..55bf97b 100644
--- a/09_network/9.6_network_isolation.md
+++ b/09_network/9.6_network_isolation.md
@@ -16,7 +16,7 @@ $ docker network create backend
$ docker run -d --name web --network frontend nginx
-## 容器 B 在 backend
+## 容器 B 在 backend
$ docker run -d --name db --network backend postgres
@@ -62,13 +62,13 @@ graph TD
Web1["Web 服务器 1"]
Web2["Web 服务器 2"]
end
-
+
subgraph BackendNet ["backend 网络"]
API["API 服务器"]
DB["数据库"]
Cache["Redis 缓存"]
end
-
+
LB --> Web1
LB --> Web2
Web1 -.-> API
diff --git a/11_compose/11.5_compose_file.md b/11_compose/11.5_compose_file.md
index 3ae9ecb..59d0369 100644
--- a/11_compose/11.5_compose_file.md
+++ b/11_compose/11.5_compose_file.md
@@ -459,7 +459,7 @@ services:
- mysql_data:/var/lib/mysql
volumes:
- mysql_data:
+ mysql_data:
```
### 11.5.33 其它指令
diff --git a/11_compose/11.6_django.md b/11_compose/11.6_django.md
index 13e6820..caa8887 100644
--- a/11_compose/11.6_django.md
+++ b/11_compose/11.6_django.md
@@ -18,15 +18,15 @@ flowchart TD
Port8000[":8000"]
Django ~~~ Port8000
end
-
+
subgraph DB ["db 服务"]
direction TB
Postgres["PostgreSQL
数据库"]
end
-
+
Django -- ":5432" --> Postgres
end
-
+
Browser["localhost:8000
(浏览器访问)"]
Port8000 --> Browser
```
diff --git a/11_compose/11.7_rails.md b/11_compose/11.7_rails.md
index 4e09869..a721c8a 100644
--- a/11_compose/11.7_rails.md
+++ b/11_compose/11.7_rails.md
@@ -18,15 +18,15 @@ flowchart TD
Port3000[":3000"]
Rails ~~~ Port3000
end
-
+
subgraph DB ["db 服务"]
direction TB
Postgres["PostgreSQL
数据库"]
end
-
+
Rails -- ":5432" --> Postgres
end
-
+
Browser["localhost:3000"]
Port3000 --> Browser
```
diff --git a/11_compose/11.8_wordpress.md b/11_compose/11.8_wordpress.md
index 4749fe5..617bff2 100644
--- a/11_compose/11.8_wordpress.md
+++ b/11_compose/11.8_wordpress.md
@@ -27,7 +27,7 @@ services:
image: mysql:8.0
container_name: wordpress_db
restart: always
- command:
+ command:
# 使用原生密码认证(旧版 WP 兼容性)
- --default-authentication-plugin=mysql_native_password
diff --git a/12_implementation/12.2_namespace.md b/12_implementation/12.2_namespace.md
index d837ada..a7eff9a 100644
--- a/12_implementation/12.2_namespace.md
+++ b/12_implementation/12.2_namespace.md
@@ -16,13 +16,13 @@ flowchart LR
H4["PID 1234: nginx"]
H5["PID 1235: nginx worker"]
end
-
+
subgraph Container ["容器内视角"]
direction TB
C1["PID 1: nginx
← 容器认为自己是 PID 1"]
C2["PID 2: nginx worker"]
end
-
+
H4 -. "(实际是宿主机的 1234)" .- C1
```
@@ -92,13 +92,13 @@ flowchart LR
H1["eth0: 192.168.1.10
端口 80 可用"]
H2["docker0: 172.17.0.1"]
end
-
+
subgraph Container ["容器"]
direction TB
C1["eth0: 172.17.0.2
端口 80 可用"]
C2["(veth pair 连接)"]
end
-
+
H2 <--> C2
```
diff --git a/12_implementation/12.3_cgroups.md b/12_implementation/12.3_cgroups.md
index 422c7e8..8ebfdcd 100644
--- a/12_implementation/12.3_cgroups.md
+++ b/12_implementation/12.3_cgroups.md
@@ -17,7 +17,7 @@ flowchart LR
B["容器 B、C 饥饿"]
end
end
-
+
subgraph Limit ["有 cgroups 限制"]
direction TB
subgraph HostRes2 ["宿主机资源"]
diff --git a/12_implementation/12.4_ufs.md b/12_implementation/12.4_ufs.md
index 8aa0f94..9a4f55e 100644
--- a/12_implementation/12.4_ufs.md
+++ b/12_implementation/12.4_ufs.md
@@ -12,12 +12,12 @@
flowchart TD
ContainerFS["容器看到的文件系统
/bin /etc /lib /usr /var /app /data"]
UnionFS["UnionFS 联合挂载"]
-
+
ContainerLayer["容器层 (读写) : /app/data/log.txt (新写入)"]
ImageLayer3["镜像层3 (只读) : /app/app.py"]
ImageLayer2["镜像层2 (只读) : /usr/local/bin/python"]
ImageLayer1["镜像层1 (只读) : /bin /etc /lib (基础系统)"]
-
+
ContainerFS --> UnionFS
UnionFS --> ContainerLayer --> ImageLayer3 --> ImageLayer2 --> ImageLayer1
```
@@ -68,7 +68,7 @@ flowchart LR
B_C["容器层 (空)"]
B_I["镜像层
/etc/nginx.conf"]
end
-
+
subgraph After ["修改后"]
direction TB
A_C["容器层
/etc/nginx.conf ← 复制到容器层后修改"]
@@ -126,11 +126,11 @@ overlay2 是目前最推荐的存储驱动:
flowchart TD
Merged["merged (合并视图)
容器看到的完整文件系统"]
OverlayFS["OverlayFS"]
-
+
Upper["upper
(容器层)
读写"]
Lower2["lower2
(镜像层)
只读"]
Lower1["lower1
(基础层)
只读"]
-
+
Merged --> OverlayFS
OverlayFS --> Upper
OverlayFS --> Lower2
diff --git a/12_implementation/summary.md b/12_implementation/summary.md
index d88bfbe..23670d0 100644
--- a/12_implementation/summary.md
+++ b/12_implementation/summary.md
@@ -9,7 +9,7 @@
| **Union FS** | 分层存储 | overlay2 为推荐驱动,支持 Copy-on-Write |
| Namespace | 隔离内容 | 一句话说明 |
-|-----------|---------|-----------|
+|-----------|---------|-----------|
| PID | 进程 ID | 容器有自己的进程树 |
| NET | 网络 | 容器有自己的 IP 和端口 |
| MNT | 文件系统 | 容器有自己的根目录 |
diff --git a/14_kubernetes_setup/14.2_kubeadm-docker.md b/14_kubernetes_setup/14.2_kubeadm-docker.md
index c174149..9814532 100644
--- a/14_kubernetes_setup/14.2_kubeadm-docker.md
+++ b/14_kubernetes_setup/14.2_kubeadm-docker.md
@@ -5,7 +5,7 @@
> ⚠️ **强烈提示:Docker 与 Kubernetes 环境的时代分界**
>
> 自 Kubernetes v1.24 起,内置的 `dockershim` 组件已被正式移除。这意味着 **Kubernetes 不再将 Docker Engine 作为默认内置的容器运行时**。虽然 Docker 仍然是你本地构建、管理镜像的绝佳工具,但它已不再是 kubelet 的默认运行时选项。
->
+>
> 因此,**强烈推荐** 读者直接参考同目录下的《[使用 kubeadm 部署 Kubernetes (CRI 使用 containerd)](14.1_kubeadm.md)》作为主要的部署路线。
>
> 本文档保留,主要用于历史环境维护或特殊需求场景:如果你必须在较新的 Kubernetes 集群中继续使用 Docker Engine 作为底层运行时,你必须理解 CRI 层机制,额外部署并配置第三方兼容层 `cri-dockerd`,同时在部署时手动补充 `--cri-socket` 等参数约束。