Add new content and update versions

This commit is contained in:
yeasy
2026-04-19 22:35:33 -07:00
parent 1d780f70c5
commit b3d1508310
18 changed files with 122 additions and 31 deletions
+3 -3
View File
@@ -2,7 +2,9 @@
本节将通过一个简单的 Web 应用例子带你快速体验 Docker 的核心流程构建镜像运行容器 本节将通过一个简单的 Web 应用例子带你快速体验 Docker 的核心流程构建镜像运行容器
在学习 Docker 之前我们先来理解为什么这个例子适合初学者Docker 的核心价值在于 **一致性交付**无论你在本地云端还是他人的机器上运行容器应用的行为都应该保持一致这个 Nginx + 静态 HTML 的例子之所以被广泛采用是因为它展现了 Docker 工作流的三个核心阶段 ### 为什么选择 Nginx + HTML 作为入门例子
在学习 Docker 之前我们先来理解为什么这个例子是最适合初学者的Docker 的核心价值在于**一致性交付**无论你在本地云端还是他人的机器上运行容器应用的行为都是完全一致的这个 Nginx + 静态 HTML 的例子之所以被广泛采用是因为它展现了 Docker 工作流的三个核心阶段
1. **镜像定义Image Layer**通过 Dockerfile 描述如何把应用打包成一个自包含的单元 1. **镜像定义Image Layer**通过 Dockerfile 描述如何把应用打包成一个自包含的单元
2. **镜像构建Build**执行 `docker build`Docker 根据 Dockerfile 逐层构建镜像 2. **镜像构建Build**执行 `docker build`Docker 根据 Dockerfile 逐层构建镜像
@@ -27,8 +29,6 @@ FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html COPY index.html /usr/share/nginx/html/index.html
``` ```
这里的 `/usr/share/nginx/html/` Nginx 官方镜像默认提供静态页面的目录 `index.html` 复制到这个位置后Nginx 启动时就会直接对外提供该页面因此这个例子能把准备文件 -> 打包镜像 -> 启动服务的最短路径展示得很清楚
### 1.1.3 构建镜像 ### 1.1.3 构建镜像
打开终端进入该目录执行构建命令 打开终端进入该目录执行构建命令
+5 -3
View File
@@ -79,7 +79,9 @@ Docker 使用 [Go 语言](https://golang.google.cn/)开发,基于 Linux 内核
> 如果你对这些底层技术感兴趣可以阅读本书的[底层实现](../12_implementation/README.md)章节 > 如果你对这些底层技术感兴趣可以阅读本书的[底层实现](../12_implementation/README.md)章节
**Docker 架构演进**Docker 的底层实现经历了多次演进 #### Docker 架构演进
Docker 的底层实现经历了多次演进
```mermaid ```mermaid
flowchart LR flowchart LR
@@ -104,13 +106,13 @@ flowchart LR
### 1.2.5 Docker 的历史与生态 ### 1.2.5 Docker 的历史与生态
**Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 发起的一个公司内部项目,于 [2013 年 3 月以 Apache 2.0 授权协议开源](https://en.wikipedia.org/wiki/Docker_%28software%29)。 **Docker** 最初是 `dotCloud` 公司创始人 [Solomon Hykes](https://github.com/shykes) 在法国期间发起的一个公司内部项目,于 [2013 年 3 月以 Apache 2.0 授权协议开源](https://en.wikipedia.org/wiki/Docker_%28software%29)。
Docker 的发展历程 Docker 的发展历程
- **2013 3 **开源发布 - **2013 3 **开源发布
- **2013 年底**dotCloud 公司改名为 DockerInc - **2013 年底**dotCloud 公司改名为 DockerInc
- **2015 **成立[开放容器联盟 (OCI)](https://opencontainers.org/),推动容器标准化 - **2015 **成立[开放容器联盟 (OCI)](https://opencontainers.org/),推动容器标准化
- **截至 2026 4 **[GitHub 项目](https://github.com/moby/moby)超过 7 万星标 - **至今**[GitHub 项目](https://github.com/moby/moby)超过 7 万星标
Docker 的成功推动了整个容器生态的发展催生了 KubernetesPodman 等众多相关项目笔者认为Docker 最大的贡献不仅是技术本身更是它 **让容器技术从系统管理员的工具变成了每个开发者都能使用的标准工具** Docker 的成功推动了整个容器生态的发展催生了 KubernetesPodman 等众多相关项目笔者认为Docker 最大的贡献不仅是技术本身更是它 **让容器技术从系统管理员的工具变成了每个开发者都能使用的标准工具**
+12 -10
View File
@@ -45,7 +45,9 @@
### 1.3.2 Docker 如何解决这些问题 ### 1.3.2 Docker 如何解决这些问题
Docker 的出现为上述问题提供了系统性的解决方案它通过 一次构建到处运行 的核心理念从根本上改变了软件交付的方式 Docker 的出现为上述问题提供了完美的解决方案它通过 一次构建到处运行 的核心理念从根本上改变了软件交付的方式
#### 核心理念一次构建到处运行
```mermaid ```mermaid
flowchart LR flowchart LR
@@ -99,27 +101,27 @@ $ docker compose up
#### 3. 资源效率 #### 3. 资源效率
Docker 容器共享宿主机内核无需为每个应用运行完整的操作系统以一台 64GB 内存的物理服务器为例 Docker 容器共享宿主机内核无需为每个应用运行完整的操作系统以一台 64GB 内存的物理服务器为例
- **传统虚拟机方案**每个虚拟机都需要额外运行一套完整操作系统会带来持续的基础资源开销随着实例数增加可真正分配给业务进程的内存会被不断压缩 - **传统虚拟机方案**每个虚拟机都需要运行完整操作系统每个额外占用如 2GB 内存产生大量资源开销实际可用于应用的内存可能只有约 18GB
- **Docker 方案**容器直接共享宿主机系统保留宿主机和容器引擎的基础开销因此通常能把更多内存留给实际业务负载 - **Docker 方案**容器直接共享宿主机系统需付出很少的基础开销OS 及引擎约 4GB即可将约 60GB 的内存全部用于实际应用
```mermaid ```mermaid
flowchart TD flowchart TD
subgraph VM ["传统虚拟机方案 ❌"] subgraph VM ["传统虚拟机方案 ❌"]
direction TB direction TB
Server1["物理服务器 (64GB 内存)"] Server1["物理服务器 (64GB 内存)"]
subgraph VMs ["可用应用内存: 较少"] subgraph VMs ["可用应用内存: 约 18GB"]
direction LR direction LR
VM1["VM 1: 应用 1<br/>(含独立 OS 开销)"] VM1["VM 1: 应用 1<br/>(含 2GB OS)"]
VM2["VM 2: 应用 2<br/>(含独立 OS 开销)"] VM2["VM 2: 应用 2<br/>(含 2GB OS)"]
VM3["VM 3: 应用 3<br/>(含独立 OS 开销)"] VM3["VM 3: 应用 3<br/>(含 2GB OS)"]
end end
Server1 --- VMs Server1 --- VMs
end end
subgraph Docker ["Docker 方案 ✅"] subgraph Docker ["Docker 方案 ✅"]
direction TB direction TB
Server2["物理服务器 (64GB 内存)<br/>含宿主 OS 与引擎基础开销"] Server2["物理服务器 (64GB 内存)<br/>含约 4GB OS及引擎配置"]
subgraph Containers ["可用应用内存: 更多"] subgraph Containers ["可用应用内存: 约 60GB"]
direction LR direction LR
C1["容器 1: 应用 1<br/>(按需分配)"] C1["容器 1: 应用 1<br/>(按需分配)"]
C2["容器 2: 应用 2<br/>(按需分配)"] C2["容器 2: 应用 2<br/>(按需分配)"]
@@ -158,7 +160,7 @@ Docker 可以在几乎任何平台上运行:
#### 6. 微服务架构的基石 #### 6. 微服务架构的基石
现代微服务实践大量采用容器技术作为交付基础Docker 让你可以先把每个服务标准化封装而在更大规模场景下通常还需要配合编排服务发现网络治理和可观测性体系一起落地 现代微服务架构几乎都依赖容器技术Docker 让你可以
- **隔离服务**每个服务运行在独立容器中互不干扰 - **隔离服务**每个服务运行在独立容器中互不干扰
- **独立扩展**哪个服务负载高就单独扩展哪个 - **独立扩展**哪个服务负载高就单独扩展哪个
+1 -1
View File
@@ -2,7 +2,7 @@
本章将带领你进入 **Docker** 的世界 本章将带领你进入 **Docker** 的世界
> **版本提示**本书内容及示例基于 **Docker Engine v29.x** 及以上版本 Docker Engine v29 全新安装默认启用 `containerd image store` 作为镜像存储后端这意味着后续涉及多架构镜像本地镜像元数据和供应链安全能力的章节会以这一路径为背景展开说明 > **版本提示**本书内容及示例基于 **Docker Engine v29.x** 及以上版本值得注意的是 Docker Engine v29 官方在全新安装场景下 **默认启用 `containerd image store` 作为镜像存储后端**取代传统 classic store 路径下的 graph driver 体系这项底层革新极大增强了 Docker 对多架构镜像Multi-platform以及软件供应链安全元数据Attestations, SBOM, Provenance的本地支持原生性
## 本章内容 ## 本章内容
+2 -2
View File
@@ -251,9 +251,9 @@ someuser/myapp # ⚠️ 需要评估
#### 镜像签名 #### 镜像签名
当前更推荐使用 Sigstore / Notation 体系进行镜像签名与验证`Docker Content Trust (DCT)` 进入退场阶段不建议作为新项目方案 当前更推荐使用 Sigstore / Notation 体系进行镜像签名与验证`Docker Content Trust (DCT)` 2025 8 8 日开始停用官方 Docker 镜像已停止 DCT 签名2028 3 31 日将完全删除此功能不建议作为新项目方案
> 注意Cosign 默认会把签名回镜像所在仓库请使用你有推送权限的镜像地址 > 注意Cosign 默认会把签名推送回镜像所在仓库请使用你有推送权限的镜像地址
```bash ```bash
## 准备一个你有写权限的镜像地址 ## 准备一个你有写权限的镜像地址
+1 -1
View File
@@ -11,7 +11,7 @@ Docker 提供了 `docker init` 命令,可以根据项目类型自动生成 Doc
```bash ```bash
$ docker init $ docker init
``` ```
该命令会交互式地询问项目类型 ( GoNode.jsPythonRust )并生成符合最佳实践的配置文件对于新项目这是推荐的起步方式 该命令会交互式地询问项目类型支持 GoNode.jsPythonRustJavaASP.NET CorePHP 并生成符合最佳实践的配置文件对于新项目这是推荐的起步方式
### 4.5.2 手动创建 Dockerfile ### 4.5.2 手动创建 Dockerfile
+1 -1
View File
@@ -20,7 +20,7 @@ $ docker export 7691a814370e > ubuntu.tar
```bash ```bash
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0 $ cat ubuntu.tar | docker import - test/ubuntu:v1.0
$ docker image ls $ docker image ls
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE REPOSITORY TAG IMAGE ID CREATED SIZE
test/ubuntu v1.0 9d37a6082e97 About a minute ago 171.3 MB test/ubuntu v1.0 9d37a6082e97 About a minute ago 171.3 MB
``` ```
此外也可以通过指定 URL 或者某个目录来导入例如 此外也可以通过指定 URL 或者某个目录来导入例如
+1 -1
View File
@@ -112,7 +112,7 @@ $ echo "dckr_pat_xxxxxxx" | docker login --username username --password-stdin
#### 3. 关注镜像漏洞 #### 3. 关注镜像漏洞
Docker Hub 会对官方镜像和付费用户的镜像进行安全扫描在镜像标签页可以看到漏洞扫描结果 Docker Hub 提供 Docker Scout 安全扫描功能官方镜像的漏洞扫描结果对所有用户免费可见Docker Scout 的持续扫描功能在免费层可以覆盖 1 个私有仓库付费用户可以扫描更多仓库在镜像标签页可以看到漏洞扫描结果
--- ---
+1 -1
View File
@@ -4,7 +4,7 @@
本节介绍如何使用本地仓库 本节介绍如何使用本地仓库
[Docker Registry](https://docs.docker.com/registry/) 是官方提供的工具,可以用于构建私有的镜像仓库。本文内容基于 [docker/distribution](https://github.com/docker/distribution) v2.x 版本。 [Docker Registry](https://docs.docker.com/registry/) 是官方提供的工具,可以用于构建私有的镜像仓库。本文内容基于 [distribution/distribution](https://github.com/distribution/distribution) v2.x 版本。
### 6.2.1 安装运行 docker-registry ### 6.2.1 安装运行 docker-registry
+10
View File
@@ -186,4 +186,14 @@ HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1
健康检查应主要关注 **当前服务** 是否可用而不是检查其下游依赖 (数据库等)下游依赖的检查应由应用逻辑处理 健康检查应主要关注 **当前服务** 是否可用而不是检查其下游依赖 (数据库等)下游依赖的检查应由应用逻辑处理
#### 5. 与容器编排平台的关系
不同平台对 HEALTHCHECK 的支持有所不同
- **Docker Compose**直接使用 Dockerfile 中定义的 HEALTHCHECK也可在 `compose.yaml` 中覆盖
- **Docker Swarm**使用 HEALTHCHECK 进行服务健康判断和滚动更新决策
- **Kubernetes****忽略** Dockerfile 中的 HEALTHCHECK使用自己的 `livenessProbe` `readinessProbe` 机制
如果应用同时部署在 Docker Compose Kubernetes 环境中建议在 Dockerfile 中保留 HEALTHCHECK Compose 使用同时在 Kubernetes Pod 配置中定义对应的探针
--- ---
+37
View File
@@ -158,4 +158,41 @@ RUN --mount=type=cache,target=/go/pkg/mod \
RUN --mount=type=secret,id=mysecret \ RUN --mount=type=secret,id=mysecret \
cat /run/secrets/mysecret cat /run/secrets/mysecret
``` ```
#### 3. Heredoc 语法
BuildKit 支持使用 heredoc 语法编写多行脚本无需行末反斜杠 `\` 连接
```docker
RUN <<EOF
apt-get update
apt-get install -y \
build-essential \
curl \
git
rm -rf /var/lib/apt/lists/*
EOF
```
优势
- 可读性更强不需要在每行末尾添加 `\`
- 避免在脚本中转义引号
- 支持多个 heredoc 可指定不同的 Shell
```docker
RUN <<EOF
echo "使用默认 /bin/sh"
EOF
RUN <<'EOF'
#!/bin/bash
set -euo pipefail
echo "使用 bash"
wget http://example.com/file.tar.gz
EOF
```
> 💡 使用 heredoc 需要在 Dockerfile 首行声明 BuildKit 语法版本`# syntax=docker/dockerfile:1`
--- ---
+5
View File
@@ -203,6 +203,11 @@ COPY --link --from=builder /app/dist /usr/share/nginx/html
- 并行化构建过程 - 并行化构建过程
- 加速多阶段构建 - 加速多阶段构建
> **注意**使用 `--link` 需要满足以下条件
> - 启用 BuildKitDocker Engine 23.0+ 默认启用
> - Dockerfile 语法版本 1.4 或更高在首行声明 `# syntax=docker/dockerfile:1`
> - 目标路径在前序指令中应不存在或为空目录
--- ---
### 7.2.9 dockerignore ### 7.2.9 dockerignore
+2
View File
@@ -117,3 +117,5 @@ $ docker compose run web python app.py
$ docker compose config $ docker compose config
$ docker compose down $ docker compose down
``` ```
> 💡 `docker compose down` 默认会删除容器和网络 **保留数据卷**如需同时删除数据卷请使用 `docker compose down -v`
+35 -2
View File
@@ -493,7 +493,14 @@ mac_address: 08-00-27-00-0C-0A
```yaml ```yaml
privileged: true privileged: true
``` ```
指定容器退出后的重启策略为始终重启该命令对保持服务始终运行十分有效在生产环境中推荐配置为 `always` 或者 `unless-stopped` 指定容器退出后的重启策略该命令对保持服务始终运行十分有效在生产环境中推荐配置为 `always` 或者 `unless-stopped`
| 策略 | 说明 |
|------|------|
| `no` | 默认值不自动重启 |
| `always` | 无论退出码如何始终重启Docker 守护进程启动时也会重启 |
| `on-failure[:max-retries]` | 仅在非零退出码时重启可指定最大重试次数 |
| `unless-stopped` | 类似 `always`但手动停止的容器在守护进程重启后不会自动启动 |
```yaml ```yaml
restart: always restart: always
@@ -514,7 +521,33 @@ stdin_open: true
tty: true tty: true
``` ```
### 11.5.34 读取变量 ### 11.5.34 `profiles`
`profiles` 用于按场景选择性启动服务未指定 `profiles` 的服务默认始终启动标记了 `profiles` 的服务仅在激活对应 profile 时才启动
```yaml
services:
web:
image: nginx
debug:
image: busybox
profiles:
- debug
test:
image: node
profiles:
- test
```
启动时通过 `--profile` 激活
```bash
$ docker compose --profile debug up # 启动 web + debug
$ docker compose up # 仅启动 web
```
### 11.5.35 读取变量
Compose 模板文件支持动态读取主机的系统环境变量和当前目录下的 `.env` 文件中的变量 Compose 模板文件支持动态读取主机的系统环境变量和当前目录下的 `.env` 文件中的变量
+1 -1
View File
@@ -166,7 +166,7 @@ spec:
spec: spec:
containers: containers:
- name: nginx - name: nginx
image: nginx:1.27 image: nginx:1.30
ports: ports:
- containerPort: 80 - containerPort: 80
``` ```
+3 -3
View File
@@ -8,7 +8,7 @@
services: services:
node1: node1:
image: quay.io/coreos/etcd:v3.5.17 image: quay.io/coreos/etcd:v3.5.21
volumes: volumes:
- node1-data:/etcd-data - node1-data:/etcd-data
expose: expose:
@@ -40,7 +40,7 @@ services:
- docker-etcd - docker-etcd
node2: node2:
image: quay.io/coreos/etcd:v3.5.17 image: quay.io/coreos/etcd:v3.5.21
volumes: volumes:
- node2-data:/etcd-data - node2-data:/etcd-data
networks: networks:
@@ -72,7 +72,7 @@ services:
- docker-etcd - docker-etcd
node3: node3:
image: quay.io/coreos/etcd:v3.5.17 image: quay.io/coreos/etcd:v3.5.21
volumes: volumes:
- node3-data:/etcd-data - node3-data:/etcd-data
networks: networks:
+1 -1
View File
@@ -43,5 +43,5 @@ $ sudo coreos-installer install /dev/sda --ignition-file example.ign
```bash ```bash
$ ssh core@虚拟机IP $ ssh core@虚拟机IP
$ docker --version $ podman --version
``` ```
+1 -1
View File
@@ -35,7 +35,7 @@ Kubernetes 作为一个容器编排系统,为了屏蔽底层不同容器运行
- 早期版本中Kubernetes 默认使用 docker 作为运行时通过一个名为 `dockershim` 的桥接组件对接 DockerDocker 再对接 containerd - 早期版本中Kubernetes 默认使用 docker 作为运行时通过一个名为 `dockershim` 的桥接组件对接 DockerDocker 再对接 containerd
- 随着 containerd 原生支持了 CRI 插件Kubernetes 开始直接与 containerd 通信去掉了 `dockershim` `dockerd` 的中间层这就是为什么从 Kubernetes v1.24 开始弃用 Docker引发了广泛关注实际上 Kubernetes 只是弃用 `dockershim`底层依然在使用从 Docker 基因中诞生的 containerd - 随着 containerd 原生支持了 CRI 插件Kubernetes 开始直接与 containerd 通信去掉了 `dockershim` `dockerd` 的中间层这就是为什么从 Kubernetes v1.24 开始弃用 Docker引发了广泛关注实际上 Kubernetes 只是弃用 `dockershim`底层依然在使用从 Docker 基因中诞生的 containerd
- containerd 2.0 移除了已弃用的 CRI v1alpha2 接口仅保留 CRI v1Kubernetes v1.23 支持 CRI v1如果集群中仍有依赖 CRI v1alpha2 的组件升级 containerd 2.x 前需先完成迁移 - containerd 2.0 移除了已弃用的 CRI v1alpha2 接口仅保留 CRI v1Kubernetes v1.26 支持 CRI v1如果集群中仍有依赖 CRI v1alpha2 的组件升级 containerd 2.x 前需先完成迁移
### 为什么直接使用 containerd ### 为什么直接使用 containerd