From 08e981018e11006441fdadc4e19f2d41ad92c865 Mon Sep 17 00:00:00 2001 From: yeasy Date: Fri, 7 Aug 2026 23:26:12 -0700 Subject: [PATCH] =?UTF-8?q?fix(content):=20=E4=BF=AE=E6=AD=A3=E5=9B=9B?= =?UTF-8?q?=E5=A4=84=E4=B9=A6=E5=86=85=E8=87=AA=E7=9B=B8=E7=9F=9B=E7=9B=BE?= =?UTF-8?q?=E7=9A=84=E6=8A=80=E6=9C=AF=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. FROM「必须是第一条指令」(4.5、7.16、summary 三处)与本书 7.7.4「FROM 之前的 ARG」整节直接冲突。官方 Dockerfile 参考写的是 "A Dockerfile must begin with a FROM instruction. This may be after parser directives, comments, and globally scoped ARGs",且 "ARG is the only instruction that may precede FROM"。三处 一并改成「第一条构建指令」并点明例外。 2. 12 章小结把 USER Namespace 列进「默认启用」的一档,并写「容器 root ≠ 宿主机 root」;而同章 12.2.2 明写 USER Namespace 默认**不**启用、需 userns-remap 显式 开启,18.1 更直说「在默认情况下,容器内的 root 用户(UID=0)就是宿主机上的 root 用户」。小结按正文口径改回——这条读反了会直接误判容器逃逸的风险面。 3. 11.5「目前支持三种日志驱动类型」是 Compose 早期文本的残留。官方支持 json-file、 local、syslog、journald、gelf、fluentd、awslogs、splunk、etwlogs、gcplogs、 none 共十余种,本书 19 章小结自己就列了六种。改为给出常见取值并链到官方清单。 4. 7.8 与 7.5 的示例注释建议 postgres:latest / redis:latest,而 4.1、7.10、 7.16、7 章小结、4.5 全都要求避免 latest(7.8 同一文件第 177 行也写「避免 latest」)。按全书口径改掉这两处。 另:ENV 的空格分隔旧写法(7.6 的「格式一」、附录四的 PG_MAJOR/PATH 示例)改为等号 形式并加注。BuildKit 的 LegacyKeyValueFormat 检查会报 "ENV key=value" should be used instead of legacy "ENV key value" format, 而本书 10.2 与 07 章 README 正是在推荐 docker buildx build --check。 --- 04_image/4.5_build.md | 2 +- 07_dockerfile/7.16_references.md | 2 +- 07_dockerfile/7.5_entrypoint.md | 2 +- 07_dockerfile/7.6_env.md | 12 ++++++++---- 07_dockerfile/7.8_volume.md | 2 +- 07_dockerfile/summary.md | 2 +- 11_compose/11.5_compose_file.md | 2 +- 12_implementation/summary.md | 4 ++-- 19_observability/summary.md | 3 ++- 9 files changed, 18 insertions(+), 13 deletions(-) diff --git a/04_image/4.5_build.md b/04_image/4.5_build.md index 9d1df24..219f831 100644 --- a/04_image/4.5_build.md +++ b/04_image/4.5_build.md @@ -36,7 +36,7 @@ RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html ### 4.5.3 FROM 指定基础镜像 -所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 `nginx` 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 `FROM` 就是指定 **基础镜像**,因此一个 `Dockerfile` 中 `FROM` 是必备的指令,并且必须是第一条指令。 +所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制。就像我们之前运行了一个 `nginx` 镜像的容器,再进行修改一样,基础镜像是必须指定的。而 `FROM` 就是指定 **基础镜像**,因此一个 `Dockerfile` 中 `FROM` 是必备的指令,并且必须是第一条**构建指令**——按官方 Dockerfile 参考,它之前只允许出现 parser 指令、注释和全局作用域的 `ARG`,`ARG` 是唯一能写在 `FROM` 之前的指令(见 [7.7 ARG](../07_dockerfile/7.7_arg.md))。 > **版本号最佳实践**:在 `FROM` 指令中 **务必指定具体版本号**(如 `FROM ubuntu:24.04` 或 `FROM python:3.12-slim`)而非 `FROM ubuntu` 或 `FROM python:latest`。这样可以确保 Dockerfile 在不同时间、不同环境下构建出的镜像内容一致,避免因基础镜像更新导致的不可预期的变化。 diff --git a/07_dockerfile/7.16_references.md b/07_dockerfile/7.16_references.md index 41395cd..0d643ab 100644 --- a/07_dockerfile/7.16_references.md +++ b/07_dockerfile/7.16_references.md @@ -12,7 +12,7 @@ Dockerfile 中的常用指令包括: -- **FROM**: 指定基础镜像,必须是第一条指令 +- **FROM**: 指定基础镜像,必须是第一条构建指令(只有全局 `ARG`、注释和 parser 指令可以在它之前) - **RUN**: 在镜像中执行命令,用于安装软件包等 - **COPY**: 复制文件到镜像中 - **ADD**: 更高级的复制文件(支持 URL 和自动解压) diff --git a/07_dockerfile/7.5_entrypoint.md b/07_dockerfile/7.5_entrypoint.md index 0cc427c..d9b7978 100644 --- a/07_dockerfile/7.5_entrypoint.md +++ b/07_dockerfile/7.5_entrypoint.md @@ -164,7 +164,7 @@ curl -s http://myip.ipip.net -i #### 实现方式 ```docker -# 建议使用 redis:7 或 redis:latest,具体版本号根据生产需求选择 +# 建议使用 redis:7 等具体版本标签,避免 latest,具体版本号根据生产需求选择 FROM redis:7-alpine COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/07_dockerfile/7.6_env.md b/07_dockerfile/7.6_env.md index f6eafb4..d97aa1b 100644 --- a/07_dockerfile/7.6_env.md +++ b/07_dockerfile/7.6_env.md @@ -5,12 +5,16 @@ ```docker ## 格式一:单个变量 -ENV +ENV = -## 格式二:多个变量(推荐) +## 格式二:多个变量 ENV = = ... ``` +> ⚠️ 用空格分隔的旧写法 `ENV `(`ARG` 同理)虽然仍能构建,但已被官方弃用。BuildKit 的 +> [LegacyKeyValueFormat](https://docs.docker.com/reference/build-checks/legacy-key-value-format/) 构建检查会报 +> `"ENV key=value" should be used instead of legacy "ENV key value" format`,`docker buildx build --check`(见 [10.2](../10_buildx/10.2_buildx.md))会直接把它标出来。一律用等号。 + --- ### 7.6.2 基本用法 @@ -18,8 +22,8 @@ ENV = = ... #### 设置单个变量 ```docker -ENV NODE_VERSION 20 -ENV APP_ENV production +ENV NODE_VERSION=20 +ENV APP_ENV=production ``` #### 设置多个变量 diff --git a/07_dockerfile/7.8_volume.md b/07_dockerfile/7.8_volume.md index 033ebd2..ead25bf 100644 --- a/07_dockerfile/7.8_volume.md +++ b/07_dockerfile/7.8_volume.md @@ -120,7 +120,7 @@ VOLUME /data #### 数据库持久化 ```docker -# 建议使用 postgres:16 或 postgres:latest,具体版本号根据数据库兼容性需求选择 +# 建议使用 postgres:16 等具体版本标签,避免 latest,具体版本号根据数据库兼容性需求选择 FROM postgres:16 VOLUME /var/lib/postgresql/data ``` diff --git a/07_dockerfile/summary.md b/07_dockerfile/summary.md index 3e652ad..1820311 100644 --- a/07_dockerfile/summary.md +++ b/07_dockerfile/summary.md @@ -4,7 +4,7 @@ | 指令 | 作用 | 关键要点 | |------|------|---------| -| **FROM** | 指定基础镜像 | 必须是第一条指令 | +| **FROM** | 指定基础镜像 | 必须是第一条构建指令;只有全局 `ARG` 能写在它之前 | | **RUN** | 在新层执行命令 | 合并命令、清理缓存以减小体积 | | **COPY** | 复制文件 | 优先使用,支持 `--from` | | **ADD** | 更高级的复制 | 自动解压 tar;公开远程 artifact 应配合 `--checksum` | diff --git a/11_compose/11.5_compose_file.md b/11_compose/11.5_compose_file.md index 3c9eddf..e3ffc1c 100644 --- a/11_compose/11.5_compose_file.md +++ b/11_compose/11.5_compose_file.md @@ -342,7 +342,7 @@ logging: options: syslog-address: "tcp://192.168.0.42:123" ``` -目前支持三种日志驱动类型。 +Docker 支持十余种日志驱动(`json-file`、`local`、`syslog`、`journald`、`gelf`、`fluentd`、`awslogs`、`splunk`、`gcplogs`、`none` 等,默认为 `json-file`),完整清单见[官方文档](https://docs.docker.com/engine/logging/configure/)。下面是几个常见取值: ```yaml driver: "json-file" diff --git a/12_implementation/summary.md b/12_implementation/summary.md index db319e7..a8daca3 100644 --- a/12_implementation/summary.md +++ b/12_implementation/summary.md @@ -4,7 +4,7 @@ | 技术 | 作用 | 要点 | |------|------|------| -| **Namespace** | 资源隔离 | 常见核心包括 PID、NET、MNT、UTS、IPC、USER、Cgroup;Time namespace 通常默认不启用 | +| **Namespace** | 资源隔离 | Docker 默认启用 PID、NET、MNT、UTS、IPC(cgroup v2 主机上还有 Cgroup);USER 默认**不**启用,Time 未被使用 | | **Cgroups** | 资源限制 | 限制 CPU、内存、磁盘 I/O、进程数 | | **Union FS** | 分层存储 | 镜像分层与 Copy-on-Write 是核心;Engine 29 新装默认 containerd image store,overlay2 是经典 graph driver 场景的主要后备 | @@ -15,7 +15,7 @@ | MNT | 文件系统 | 容器有自己的根目录 | | UTS | 主机名 | 容器有自己的 hostname | | IPC | 进程间通信 | 容器间 IPC 隔离 | -| USER | 用户 ID | 容器 root ≠ 宿主机 root | +| USER | 用户 ID | 启用 `userns-remap` 后容器 root 才 ≠ 宿主机 root;**默认不启用** | | 资源 | 限制参数 | 示例 | |------|---------|------| diff --git a/19_observability/summary.md b/19_observability/summary.md index b6466b9..52b6abe 100644 --- a/19_observability/summary.md +++ b/19_observability/summary.md @@ -1,9 +1,10 @@ ## 本章小结 -本章从两个维度介绍了容器可观测性: +本章从三个维度介绍了容器可观测性: * **指标监控**:以 Prometheus + Grafana 为主,完成指标采集、存储与可视化。 * **日志管理**:以 EFK/ELK 为例,完成容器日志的集中采集、检索与分析。 +* **性能优化与故障诊断**:把观测到的数据落到资源限制、瓶颈定位与线上排错上。 生产环境中,建议将“可观测性”当成一个完整闭环:**采集 -> 存储 -> 展示 -> 告警 -> 排错 -> 容量治理**。