diff --git a/03_install/3.1_ubuntu.md b/03_install/3.1_ubuntu.md index ad8fdf6..bf2aa1e 100644 --- a/03_install/3.1_ubuntu.md +++ b/03_install/3.1_ubuntu.md @@ -25,7 +25,6 @@ Ubuntu 是 Docker 最常用的运行环境之一。本节将介绍如何在 Ubun * Ubuntu Resolute Raccoon 26.04 (LTS) -* Ubuntu Questing Quokka 25.10 * Ubuntu Noble 24.04 (LTS) * Ubuntu Jammy 22.04 (LTS) diff --git a/03_install/3.2_debian.md b/03_install/3.2_debian.md index b092162..3a658a1 100644 --- a/03_install/3.2_debian.md +++ b/03_install/3.2_debian.md @@ -20,7 +20,7 @@ Docker 支持以下版本的 [Debian](https://www.debian.org/intro/about) 操作 * Debian Bookworm 12(oldstable,全面支持至 2026 年 6 月 10 日,LTS 至 2028 年 6 月 30 日) * Debian Bullseye 11(oldoldstable,LTS 支持至 2026 年 8 月 31 日) -> **注意**:Debian Bullseye 11 将于 2026 年 8 月底结束长期支持。建议新部署使用 Bookworm 12 或 Trixie 13。 +> **注意**:Debian Bullseye 11 已于 2026 年 8 月 31 日结束长期支持。建议新部署使用 Bookworm 12 或 Trixie 13。 #### 卸载旧版本 diff --git a/04_image/4.6_other.md b/04_image/4.6_other.md index 480db60..a8aefe8 100644 --- a/04_image/4.6_other.md +++ b/04_image/4.6_other.md @@ -53,7 +53,7 @@ REPOSITORY TAG IMAGE ID CREATED alpine latest baa5d63471ea 5 weeks ago 4.803 MB ``` -> **版本提示**:`alpine:latest` 为最新版本的 Alpine Linux。如果需要特定版本号(如 `alpine:3.20`),可以明确指定以确保可重现性。 +> **版本提示**:`alpine:latest` 为最新版本的 Alpine Linux。如果需要特定版本号(如 `alpine:3.24`),可以明确指定以确保可重现性;注意选一个仍在维护的版本,`alpine:3.20` 已于 2026-04 结束支持。 保存镜像的命令为: ```bash diff --git a/05_container/5.1_run.md b/05_container/5.1_run.md index 717e11b..2f9b002 100644 --- a/05_container/5.1_run.md +++ b/05_container/5.1_run.md @@ -29,7 +29,7 @@ Hello world ``` 这与直接执行 `/bin/echo 'Hello world'` 几乎没有区别,但实际上已经启动了一个完整的 Ubuntu 容器来执行这条命令。 -> **版本说明**:示例使用 `ubuntu:24.04`,这是最新 LTS 版本。如需其他版本,可替换为 `ubuntu:22.04`、`ubuntu:20.04` 等。 +> **版本说明**:示例使用 `ubuntu:24.04`,这是仍受 Docker 支持的 LTS 版本(当前最新 LTS 为 26.04)。如需其他版本,可替换为 `ubuntu:26.04`、`ubuntu:22.04` 等;不要用已不在支持列表中的 `ubuntu:20.04`(见 3.1 节)。 #### 交互式容器 diff --git a/06_repository/6.2_registry.md b/06_repository/6.2_registry.md index 9a9be89..e6184a4 100644 --- a/06_repository/6.2_registry.md +++ b/06_repository/6.2_registry.md @@ -15,9 +15,14 @@ 你可以使用官方 `registry` 镜像来运行。 ```bash -$ docker run -d -p 5000:5000 --restart=always --name registry registry:2 +$ docker run -d -p 127.0.0.1:5000:5000 --restart=always --name registry registry:2 ``` +> **注意**:这样启动的 registry **没有任何认证、也没有 TLS**,因此这里刻意绑定到 +> `127.0.0.1`,仅供本机实验。不要直接把它绑到 `0.0.0.0` 或内网地址——那等于允许同网段 +> 任意主机匿名推送镜像(镜像投毒:覆盖你的 `latest` 标签,下游全部拉到攻击者的镜像)。 +> 需要多机访问请直接用 [6.3 节](6.3_registry_auth.md) 的 TLS + 认证方案。 + > **版本说明**:使用 `registry:2` 表示 Docker Registry 2.x 兼容示例。Distribution 3.x 已发布稳定版本;不要直接把本章 v2 配置原样套到 v3 生产环境,升级前应阅读迁移说明并做兼容测试。旧版本 Registry 1.x 已停止维护,不建议使用。 这将使用官方的 `registry` 镜像来启动私有仓库。默认情况下,仓库会被创建在容器的 `/var/lib/registry` 目录下。你可以通过 `-v` 参数来将镜像文件存放在本地的指定路径。例如下面的例子将上传的镜像放到本地的 `/opt/data/registry` 目录。 @@ -96,6 +101,8 @@ REPOSITORY TAG IMAGE ID CREAT 这是因为 Docker 默认不允许非 `HTTPS` 方式推送镜像。我们可以通过 Docker 的配置选项来取消这个限制,或者查看下一节配置能够通过 `HTTPS` 访问的私有仓库。 +> **警告**:下面的 `insecure-registries` 会关闭该地址的 TLS 校验,推送和拉取都是明文、可被中间人篡改;再叠加上 registry 默认无认证,等于把「任意主机可匿名投毒」的仓库开在内网。**仅限隔离的实验网络**,生产一律走 [6.3 节](6.3_registry_auth.md) 的 TLS + 认证。 + #### Linux 默认情况下,Docker 强制使用 HTTPS 协议推送镜像。如果您搭建的私有仓库是 HTTP 协议,需要进行如下配置。 diff --git a/06_repository/6.3_registry_auth.md b/06_repository/6.3_registry_auth.md index ff4b13f..f95dcf1 100644 --- a/06_repository/6.3_registry_auth.md +++ b/06_repository/6.3_registry_auth.md @@ -201,7 +201,7 @@ $ docker image rm docker.domain.com/username/ubuntu:24.04 $ docker pull docker.domain.com/username/ubuntu:24.04 ``` -> **版本说明**:示例使用 `ubuntu:24.04`,这是最新 LTS 版本。推送到私有仓库时保持了原有的版本标签,建议生产环境明确指定镜像版本号。 +> **版本说明**:示例使用 `ubuntu:24.04`,这是仍受 Docker 支持的 LTS 版本(当前最新 LTS 为 26.04)。推送到私有仓库时保持了原有的版本标签,建议生产环境明确指定镜像版本号。 如果我们退出登录,尝试推送镜像。 ```bash diff --git a/07_dockerfile/7.6_env.md b/07_dockerfile/7.6_env.md index 0fcb656..023d004 100644 --- a/07_dockerfile/7.6_env.md +++ b/07_dockerfile/7.6_env.md @@ -182,10 +182,16 @@ RUN apt-get install nginx=1.30 ENV DB_PASSWORD=secret123 -## ✅ 正确:运行时传入 +## ⚠️ 好一些但仍会泄漏:-e 会进入 shell history、宿主机进程 argv(同机任何用户 ps 可见), +## 并永久固化在 docker inspect 的 Config.Env 里 ## docker run -e DB_PASSWORD=xxx myimage +## ✅ 正确:用文件传入,不进命令行 + +## docker run --env-file ./db.env myimage # 文件权限设为 600 +## 或使用 Compose secrets / *_FILE 约定,见 11.8 节 + ... ``` diff --git a/10_buildx/README.md b/10_buildx/README.md index cb40ee1..f6c5394 100644 --- a/10_buildx/README.md +++ b/10_buildx/README.md @@ -2,7 +2,7 @@ Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit](10.1_buildkit.md) 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。 -> Buildx 需要 Docker v23.0+(该版本起 BuildKit 成为默认构建引擎)。推荐使用 Docker v28 及以上版本以获得最完整的 Buildx 功能支持。 +> Buildx 需要 Docker v23.0+(该版本起 BuildKit 成为默认构建引擎)。推荐使用 Docker v29 及以上版本以获得最完整的 Buildx 功能支持。 ## 本章内容 diff --git a/14_kubernetes_setup/14.4_kind.md b/14_kubernetes_setup/14.4_kind.md index 679709c..0c50849 100644 --- a/14_kubernetes_setup/14.4_kind.md +++ b/14_kubernetes_setup/14.4_kind.md @@ -2,7 +2,7 @@ [Kind](https://kind.sigs.k8s.io/) (Kubernetes in Docker) 是一个使用 Docker 容器作为节点运行本地 Kubernetes 集群的工具。主要用于测试 Kubernetes 本身,也非常适合本地开发和 CI 环境。 -> **版本说明**:本文档基于 Kind v0.31.0 编写。Kind 会根据下载时的默认行为自动拉取对应的 Kubernetes 版本。建议定期更新 Kind 到最新版本以获得最新的 Kubernetes 支持。详见 [Kind Releases](https://github.com/kubernetes-sigs/kind/releases)。 +> **版本说明**:本文档基于 Kind v0.33.0 编写。Kind 会根据下载时的默认行为自动拉取对应的 Kubernetes 版本。建议定期更新 Kind 到最新版本以获得最新的 Kubernetes 支持。详见 [Kind Releases](https://github.com/kubernetes-sigs/kind/releases)。 ### 14.4.1 为什么选择 Kind @@ -29,10 +29,10 @@ brew install kind ```bash # Linux AMD64 -# 注意:v0.31.0 为编写本文档时的最新版本,请根据需要替换为当前版本 +# 注意:v0.33.0 为编写本文档时的最新版本,请根据需要替换为当前版本 # 参见 https://github.com/kubernetes-sigs/kind/releases -curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.31.0/kind-linux-amd64 +curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.33.0/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kind ``` diff --git a/15_etcd/15.2_install.md b/15_etcd/15.2_install.md index 84462b2..3424701 100644 --- a/15_etcd/15.2_install.md +++ b/15_etcd/15.2_install.md @@ -13,13 +13,13 @@ 例如,使用 `curl` 工具下载压缩包,并解压。 ```bash -# 下载 etcd v3.5.29 版本(请访问 https://github.com/etcd-io/etcd/releases 获取最新版本) -$ curl -L https://github.com/etcd-io/etcd/releases/download/v3.5.29/etcd-v3.5.29-linux-amd64.tar.gz -o etcd-v3.5.29-linux-amd64.tar.gz +# 下载 etcd v3.5.33 版本(请访问 https://github.com/etcd-io/etcd/releases 获取最新版本) +$ curl -L https://github.com/etcd-io/etcd/releases/download/v3.5.33/etcd-v3.5.33-linux-amd64.tar.gz -o etcd-v3.5.33-linux-amd64.tar.gz ## 国内用户可选择就近的网络加速方式(以可用镜像站为准) -$ tar xzvf etcd-v3.5.29-linux-amd64.tar.gz -$ cd etcd-v3.5.29-linux-amd64 +$ tar xzvf etcd-v3.5.33-linux-amd64.tar.gz +$ cd etcd-v3.5.33-linux-amd64 ``` 解压后,可以看到文件包括 @@ -61,15 +61,15 @@ hello world 镜像名称为 `quay.io/coreos/etcd`,可以通过下面的命令启动单机实验用 `etcd` 服务,并只把 `2379` 和 `2380` 映射到宿主机回环地址。 -> **版本说明:** 示例中使用 `v3.5.29` 标签。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新可用版本标签。 +> **版本说明:** 示例中使用 `v3.5.33` 标签。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新可用版本标签。 ```bash $ docker run \ -p 127.0.0.1:2379:2379 \ -p 127.0.0.1:2380:2380 \ --mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data \ ---name etcd-gcr-v3.5.29 \ -quay.io/coreos/etcd:v3.5.29 \ +--name etcd-gcr-v3.5.33 \ +quay.io/coreos/etcd:v3.5.33 \ /usr/local/bin/etcd \ --name s1 \ --data-dir /etcd-data \ diff --git a/15_etcd/15.3_cluster.md b/15_etcd/15.3_cluster.md index fbb86a8..7f49ba3 100644 --- a/15_etcd/15.3_cluster.md +++ b/15_etcd/15.3_cluster.md @@ -1,6 +1,6 @@ ## 15.3 集群 -> **版本说明:** 本节示例使用 etcd v3.5.29。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新版本信息。 +> **版本说明:** 本节示例使用 etcd v3.5.33。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新版本信息。 下面我们使用 [Docker Compose](../11_compose/README.md) 模拟启动一个 3 节点的 `etcd` 集群。 @@ -10,7 +10,7 @@ services: node1: - image: quay.io/coreos/etcd:v3.5.29 + image: quay.io/coreos/etcd:v3.5.33 volumes: - node1-data:/etcd-data expose: @@ -42,7 +42,7 @@ services: - docker-etcd node2: - image: quay.io/coreos/etcd:v3.5.29 + image: quay.io/coreos/etcd:v3.5.33 volumes: - node2-data:/etcd-data networks: @@ -74,7 +74,7 @@ services: - docker-etcd node3: - image: quay.io/coreos/etcd:v3.5.29 + image: quay.io/coreos/etcd:v3.5.33 volumes: - node3-data:/etcd-data networks: diff --git a/18_security/18.5_other_feature.md b/18_security/18.5_other_feature.md index 175fecf..7639b59 100644 --- a/18_security/18.5_other_feature.md +++ b/18_security/18.5_other_feature.md @@ -14,18 +14,25 @@ Docker 默认启用了 Seccomp,并使用预置的 [默认配置文件](https:/ #### 实战:禁用 chmod 系统调用过滤 -首先,编写一个 `no-chmod.json` 的策略文件: -```json -{ - "defaultAction": "SCMP_ACT_ALLOW", - "syscalls": [ - { - "name": "chmod", - "action": "SCMP_ACT_ERRNO" - } - ] -} +> **务必先读**:`--security-opt seccomp=` 是**整体替换**默认 profile,不是在默认之上叠加。 +> 如果自己写一个 `"defaultAction": "SCMP_ACT_ALLOW"` 的 blocklist,等于把上面那份 +> deny-by-default 的官方 allowlist 整个丢掉——你挡住了 `chmod`,却把默认被拦下的那 +> ~44 个高危调用(`unshare`、`keyctl`、`add_key`、`bpf`、`perf_event_open`、 +> `init_module`、`reboot` 等)全部放行,**净效果比不加这个参数还危险**。 +> 正确做法是**以官方默认 profile 为基线派生**。 + +先取官方默认 profile,再在它之上把 `chmod` 改成拒绝: + +```bash +$ curl -fsSL -o default.json \ + https://raw.githubusercontent.com/moby/moby/master/profiles/seccomp/default.json + +## 在 default.json 中找到包含 "chmod" 的那条 syscalls 记录,把它从 allow 列表中移除; +## 或追加一条更靠前的显式拒绝规则: +## { "names": ["chmod", "fchmod", "fchmodat"], "action": "SCMP_ACT_ERRNO" } +$ cp default.json no-chmod.json && "$EDITOR" no-chmod.json ``` + 在启动时告诉 Docker 载入这套过滤配置: ```bash @@ -36,7 +43,8 @@ $ docker run --rm -it \ / # chmod 777 /etc/passwd chmod: /etc/passwd: Operation not permitted ``` -应用只要被劫持进行越界尝试,其操作系统层命令便会立刻吃瘪。 +应用只要被劫持进行越界尝试,其操作系统层命令便会立刻吃瘪——同时默认 profile 原有的 +~44 项拦截仍然生效。 ### 18.5.2 强制访问控制:AppArmor / SELinux diff --git a/18_security/18.6_image_security.md b/18_security/18.6_image_security.md index b502faf..8008095 100644 --- a/18_security/18.6_image_security.md +++ b/18_security/18.6_image_security.md @@ -418,6 +418,12 @@ jobs: security-events: write id-token: write + # 注意:本示例其余 action 为便于阅读使用了可变标签(@v7 等),这与下面 Trivy 那条 + # 注释里「务必使用不可变 commit SHA」的要求并不一致——真正部署时**每一条 uses 都应 + # 钉死 40 位 commit SHA**,尤其是持有凭据的 docker/login-action 与能推镜像的 + # docker/build-push-action:标签一旦被劫持,攻击者拿到的就是本 job 的 + # packages: write 与 id-token: write 权限,可以推送恶意镜像并为其签名。 + # 本书仓库自己的 .github/workflows/ 即全部按 SHA 钉死,可作为参照。 steps: - name: Checkout code uses: actions/checkout@v7