diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..6323b108e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,27 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" + groups: + dependencies: + patterns: + - "*" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + commit-message: + prefix: "chore(deps)" + labels: + - "dependencies" + groups: + dependencies: + patterns: + - "*" diff --git a/.github/workflows/check-link.yml b/.github/workflows/check-link.yml index 67c5a7f1e..3d8fcaae2 100644 --- a/.github/workflows/check-link.yml +++ b/.github/workflows/check-link.yml @@ -8,7 +8,7 @@ jobs: name: check-link runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v6.0.2 # search Issues :-( - run: | docker run -i --rm \ diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f2f9dfad4..ee8f8e0b2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,7 +14,7 @@ jobs: name: Build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.1 + - uses: actions/checkout@v6.0.2 - name: Build Gitbook uses: docker://yeasy/docker_practice with: diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml new file mode 100644 index 000000000..26d5ddf41 --- /dev/null +++ b/.github/workflows/dependabot-automerge.yml @@ -0,0 +1,27 @@ +name: Dependabot auto-merge +on: pull_request + +permissions: + contents: write + pull-requests: write + +jobs: + dependabot: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v2 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + - name: Approve a PR + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Enable auto-merge for Dependabot PRs + run: gh pr merge --auto --merge "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GH_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/02_basic_concept/2.2_container.md b/02_basic_concept/2.2_container.md index b10e505d4..46cd9b1d4 100644 --- a/02_basic_concept/2.2_container.md +++ b/02_basic_concept/2.2_container.md @@ -12,22 +12,26 @@ ### 2.2.2 容器的本质 -> 💡 **笔者认为,理解这一点是理解 Docker 的关键:** **容器的本质是一个特殊的进程。** +> 💡 笔者认为,理解这一点是理解 Docker 的关键:**容器的本质是一个特殊的进程**。 ```mermaid flowchart TD subgraph NormalProcess ["普通进程"] direction TB - N1["• 与其他进程共享系统资源
• 可以看到其他进程
• 共享网络和文件系统"] + N1["• 共享系统资源
• 共享网络
• 共享文件系统"] end subgraph ContainerProcess ["容器进程 (运行在宿主机内核上)"] direction TB - C1["• 有自己的进程空间(看不到宿主机上的其他进程)
• 有自己的网络(独立 IP、端口)
• 有自己的文件系统(独立的 root 目录)
• 有自己的用户(容器内的 root ≠ 宿主机的 root)"] + C1["• 独立进程空间
• 独立网络环境
• 独立文件系统
• 独立用户空间"] end ``` -这种隔离是通过 Linux 内核的 **Namespace** 技术实现的。 +这种隔离是通过 Linux 内核的 **Namespace** 技术实现的。具体表现为: +- **进程空间**:容器看不到宿主机上的其他进程。 +- **网络**:容器拥有独立的 IP、端口等网络资源。 +- **文件系统**:容器拥有独立的 root 目录。 +- **用户**:容器内的 root 用户不等于宿主机的 root 用户。 ### 2.2.3 容器 vs 虚拟机:核心区别 diff --git a/03_install/3.7_mac.md b/03_install/3.7_mac.md index 090429be0..6ce583280 100644 --- a/03_install/3.7_mac.md +++ b/03_install/3.7_mac.md @@ -27,13 +27,13 @@ $ brew install --cask docker 如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可 (其间需要输入用户密码)。 -![图](../_images/install-mac-dmg.png) +![图](../_images/install-mac-dmg.jpg) ### 3.7.3 运行 从应用中找到 Docker 图标并点击运行。 -![图](../_images/install-mac-apps.png) +![图](../_images/install-mac-apps.jpg) 运行之后,会在右上角菜单栏看到多了一个鲸鱼图标,这个图标表明了 Docker 的运行状态。 diff --git a/04_image/4.5_build.md b/04_image/4.5_build.md index f10fa9400..2f8dd6b68 100644 --- a/04_image/4.5_build.md +++ b/04_image/4.5_build.md @@ -64,7 +64,7 @@ FROM scratch RUN echo '

Hello, Docker!

' > /usr/share/nginx/html/index.html ``` -* *exec* 格式:`RUN ["可执行文件", "参数1", "参数2"]`,这更像是函数调用中的格式。 +* *exec* 格式:`RUN [“可执行文件”, “参数1”, “参数2”]`,这更像是函数调用中的格式。 Dockerfile 中每一个指令都会建立一层,`RUN` 也不例外。每一个 `RUN` 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,`commit` 这一层的修改,构成新的镜像。 diff --git a/07_dockerfile/7.4_cmd.md b/07_dockerfile/7.4_cmd.md index f5070a484..83588ef80 100644 --- a/07_dockerfile/7.4_cmd.md +++ b/07_dockerfile/7.4_cmd.md @@ -14,9 +14,9 @@ CMD 有三种格式: | 格式 | 语法 | 推荐程度 | |------|------|---------| -| **exec 格式**| `CMD ["可执行文件", "参数1", "参数2"]` | ✅**推荐** | +| **exec 格式**| `CMD [“可执行文件”, “参数1”, “参数2”]` | ✅**推荐** | | **shell 格式** | `CMD 命令 参数1 参数2` | ⚠️ 简单场景 | -| **参数格式** | `CMD ["参数1", "参数2"]` | 配合 ENTRYPOINT | +| **参数格式** | `CMD [“参数1”, “参数2”]` | 配合 ENTRYPOINT | #### exec 格式 (推荐) diff --git a/07_dockerfile/7.5_entrypoint.md b/07_dockerfile/7.5_entrypoint.md index 9daabfd42..f93a86a30 100644 --- a/07_dockerfile/7.5_entrypoint.md +++ b/07_dockerfile/7.5_entrypoint.md @@ -12,7 +12,7 @@ | 格式 | 语法 | 推荐程度 | |------|------|---------| -| **exec 格式**| `ENTRYPOINT ["可执行文件", "参数1"]` | ✅**推荐** | +| **exec 格式**| `ENTRYPOINT [“可执行文件”, “参数1”]` | ✅**推荐** | | **shell 格式** | `ENTRYPOINT 命令 参数` | ⚠️ 不推荐 | ```docker diff --git a/07_dockerfile/summary.md b/07_dockerfile/summary.md index 68ba6f596..ad17158cc 100644 --- a/07_dockerfile/summary.md +++ b/07_dockerfile/summary.md @@ -127,7 +127,7 @@ | 要点 | 说明 | |------|------| | **作用** | 指定容器启动时的默认命令 | -| **推荐格式** | exec 格式 `CMD ["程序", "参数"]` | +| **推荐格式** | exec 格式 `CMD [“程序”, “参数”]` | | **覆盖方式** | `docker run image 新命令` | | **与 ENTRYPOINT** | CMD 作为 ENTRYPOINT 的默认参数 | | **核心原则** | 应用必须在前台运行 | diff --git a/08_data/8.2_bind-mounts.md b/08_data/8.2_bind-mounts.md index 94ead63f4..dcbe234a9 100644 --- a/08_data/8.2_bind-mounts.md +++ b/08_data/8.2_bind-mounts.md @@ -7,18 +7,24 @@ Bind Mount (绑定挂载) 将 **宿主机的目录或文件** 直接挂载到容 ```mermaid flowchart LR subgraph Host ["宿主机"] - direction TB - Dir1["/home/user/code/
├── index.html
├── style.css
└── app.js"] + Dir1["/home/user/code/"] end subgraph Container ["容器"] - direction TB - Dir2["/usr/share/nginx/html/
(同一份文件)"] + Dir2["/usr/share/nginx/html/"] end Dir1 <-->|Bind Mount| Dir2 ``` +目录结构(同一份文件): +```text +/home/user/code/ (或 /usr/share/nginx/html/) +├── index.html +├── style.css +└── app.js +``` + --- ### 8.2.2 Bind Mount vs Volume diff --git a/14_kubernetes_setup/14.1_kubeadm.md b/14_kubernetes_setup/14.1_kubeadm.md index 6d3594861..d9a00c016 100644 --- a/14_kubernetes_setup/14.1_kubeadm.md +++ b/14_kubernetes_setup/14.1_kubeadm.md @@ -228,7 +228,7 @@ oom_score = 0 async_remove = false ``` -### 14.1.3 安装 **kubelet****kubeadm****kubectl****cri-tools****kubernetes-cni** +### 14.1.3 安装 **kubelet**、**kubeadm**、**kubectl**、**cri-tools**、**kubernetes-cni** 需要在每台机器上安装以下的软件包: diff --git a/14_kubernetes_setup/14.2_kubeadm-docker.md b/14_kubernetes_setup/14.2_kubeadm-docker.md index 0498c7618..6b89af142 100644 --- a/14_kubernetes_setup/14.2_kubeadm-docker.md +++ b/14_kubernetes_setup/14.2_kubeadm-docker.md @@ -10,7 +10,7 @@ 参考[安装 Docker](../03_install/README.md) 一节安装 Docker。 -### 14.2.2 安装 **kubelet****kubeadm****kubectl** +### 14.2.2 安装 **kubelet**、**kubeadm**、**kubectl** 需要在每台机器上安装以下的软件包: diff --git a/17_ecosystem/17.4_buildah.md b/17_ecosystem/17.4_buildah.md new file mode 100644 index 000000000..2c798c62d --- /dev/null +++ b/17_ecosystem/17.4_buildah.md @@ -0,0 +1,88 @@ +## 17.4 Buildah - 容器镜像构建工具 + +本节介绍 Buildah,包括其基础概念、应用场景以及基本指令。 + +### Buildah 简介 + +Buildah 是一个用于构建 OCI(Open Container Initiative)兼容格式容器镜像的开源命令行工具。与 Docker 需要一直运行的守护进程(daemon)不同,Buildah 的设计初衷是无需守护进程(daemonless)即可工作,并且也不强制要求 root 权限(rootless)。这使得在持续集成/持续部署(CI/CD)环境中构建镜像时能够更加轻量且安全。 + +Buildah 由 Red Hat 主导开发,通常和 Podman、Skopeo 一起使用,被认为是构建、运行和管理容器的一套现代化工具链。在很多需要增强安全性和无需依赖守护进程的场景中,Buildah 是 `docker build` 命令的最佳替代方案。 + +### 核心特性 + +- **无守护进程(Daemonless)**:Buildah 直接通过系统调用拉取、构建和推送镜像,减少了单点故障的风险和资源开销。 +- **构建效率高**:可以挂载镜像的根文件系统到本地,并直接利用宿主机的工具对其进行操作,非常灵活。 +- **兼容性**:不仅支持处理传统的 Dockerfile,还能完全兼容 OCI(Open Container Initiative)标准和 Docker 格式。 +- **与 Podman 集成**:Podman 自身构建镜像的命令 `podman build` 底层实际上也是依赖 Buildah 库来实现的。 + +### 安装 Buildah + +在许多主流的 Linux 发行版中都可以通过包管理器直接安装 Buildah。 + +以 Fedora/CentOS/RHEL 为例: + +```bash +$ sudo dnf install -y buildah +``` + +以 Ubuntu/Debian 为例(需引入官方源后): + +```bash +$ sudo apt-get update +$ sudo apt-get -y install buildah +``` + +### 基础用法示例 + +#### 1. 从现有的 Dockerfile 构建镜像 + +Buildah 最常见的用法就是像 Docker 一样根据 `Dockerfile` 来构建镜像,可以直接使用 `buildah bud`(或者 `buildah build-using-dockerfile`)命令: + +```bash +$ buildah bud -t my-app:latest . +``` + +可以看到在这点上,它与 `docker build` 的体验完全一致。 + +#### 2. 交互式从空镜像开始构建 + +除了使用 Dockerfile,Buildah 最强大的功能来自于它的交互式和脚本化构建机制。我们可以从一个极简的镜像(或基础镜像)开始构建: + +```bash +# 获取一个基础镜像 +$ container=$(buildah from alpine:latest) + +# 获取挂载点,并查看其路径 +$ mnt=$(buildah mount $container) +$ echo $mnt +/var/lib/containers/storage/overlay/xxx/merged + +# 利用宿主机直接创建文件,而不需要在容器内部运行命令 +$ echo "Hello Buildah" > $mnt/hello.txt + +# 添加一些配置和命令 +$ buildah config --cmd "cat /hello.txt" $container + +# 将容器提交为镜像 +$ buildah commit $container my-hello-image:latest + +# 构建完成后可以卸载并清理容器上下文 +$ buildah unmount $container +$ buildah rm $container +``` + +这种模式在自动化流水线中极为有用,因为我们可以将上述过程编写成标准的 bash 脚本,无需为了构建镜像而撰写只在其独立语法中运行的 Dockerfile 指令。 + +#### 3. 查看和推送镜像 + +通过 `buildah images` 可以查看当前环境中的镜像。推送镜像到外部 Registry 也十分安全方便: + +```bash +# 查看本地构建的镜像 +$ buildah images + +# 推送镜像到 Docker Hub(注意需要先登录) +$ buildah push my-hello-image:latest docker://docker.io/username/my-hello-image:latest +``` + +结合其无需特权和灵活脚本的优点,Buildah 正变得越来越受到构建和分发 OCI 镜像的用户喜爱。 diff --git a/17_ecosystem/17.5_skopeo.md b/17_ecosystem/17.5_skopeo.md new file mode 100644 index 000000000..f6b0b3baa --- /dev/null +++ b/17_ecosystem/17.5_skopeo.md @@ -0,0 +1,79 @@ +## 17.5 Skopeo - 容器镜像管理工具 + +本节介绍 Skopeo,包括其基础概念、应用场景以及基本指令。 + +### Skopeo 简介 + +Skopeo 是一个由 Red Hat 赞助开源的命令行工具,它可以在不需要运行容器守护进程(如 Docker Daemon)的前提下,对容器镜像进行极其高效的操作和管理,包括:检查、复制、删除和签名等操作。 + +Skopeo 最大的特点是其可以在“不将镜像拉取到本地”的情况下,直接在远端 Registry(镜像仓库)之间完成检查和搬运,从而大幅度节省带宽和磁盘空间。这也是它在容器运维和分发领域非常受欢迎的原因。 + +### 核心特性 + +- **远程巡检**:通过 `skopeo inspect` 可以查看远端仓库中镜像的元数据(例如包含哪些层、环境变量信息、入口命令等),而完全无需拉取该镜像。 +- **镜像复制与同步**:支持各种格式之间的相互传输,如在不同的容器仓库之间、或者从仓库拉取到本地的目录、或者存储为 OCI 布局结构等。 +- **镜像删除**:可以远程删除仓库中的镜像(需要拥有权限)。 +- **签名验证**:支持在分发镜像前进行数字签名以保障安全性。 + +### 安装 Skopeo + +类似于 Buildah,Skopeo 也直接包含在大部分主流的 Linux 源中。 + +在 Fedora/CentOS/RHEL 等发行版中: + +```bash +$ sudo dnf install -y skopeo +``` + +在 Ubuntu/Debian 中: + +```bash +$ sudo apt-get update +$ sudo apt-get -y install skopeo +``` + +如果是 macOS 环境,可以通过 Homebrew 安装: + +```bash +$ brew install skopeo +``` + +### 基础用法示例 + +#### 1. 远程检查镜像 + +有时候我们只想知道远端镜像的详细信息,并不想拉取它。下面是检查 Docker Hub 上的 Alpine 镜像的例子: + +```bash +$ skopeo inspect docker://docker.io/library/alpine:latest +``` + +这个命令会返回一段 JSON 格式的数据,其中包含了诸如镜像摘要(Digest)、创建时间、架构(Architecture)、标签(Tags)等丰富信息。在自动化的工具和系统审查环境中,这是一个不可或缺的利器。 + +#### 2. 同步与复制镜像 + +`skopeo copy` 是使用最为广泛的命令。它可以在不同的仓库、不同的格式之间无缝搬运镜像。 + +例如,从一个公共仓库直接搬运镜像到一个私有企业仓库(无需将其先 `docker pull` 到本地,再 `docker push`): + +```bash +$ skopeo copy docker://docker.io/library/alpine:latest docker://registry.example.com/library/alpine:latest +``` + +又或者,你可以将远程镜像拉取到本地,只为了检查其拆解后的格式,比如将镜像解压到本地某个目录下以 OCI 规范存放: + +```bash +$ skopeo copy docker://docker.io/library/alpine:latest oci:alpine-oci +``` + +如果我们要将本地的某个目录下的打包好的镜像再次推向 Registry 或转换为其它存储类型也是完全支持的,诸如: +- `docker://` 远端 Registry +- `docker-archive:` / `docker-daemon:` Docker 对应的归档文件或本地守护进程 +- `oci:` / `oci-archive:` OCI 相关文件格式 +- `dir:` 本地纯目录 + +#### 3. 校验机制与安全 + +如果你不信任公开仓库上的镜像,或是需要通过特定的 TLS 证书和鉴权,Skopeo 的功能也是能很好的支持的,比如它可以直接传递诸如 `--src-creds` 或 `--dest-tls-verify=false` 等参数,这在进行网络隔离的复杂镜像搬运操作中常常会用到。 + +对于复杂的容器环境或那些纯粹用于镜像资产管理的节点来说,Skopeo 提供了一个直接而强大的数据“搬运工”。 diff --git a/17_ecosystem/17.6_containerd.md b/17_ecosystem/17.6_containerd.md new file mode 100644 index 000000000..d36551612 --- /dev/null +++ b/17_ecosystem/17.6_containerd.md @@ -0,0 +1,69 @@ +## 17.6 containerd - 核心容器运行时 + +本节介绍 containerd,它是现代容器技术栈中最为核心的基础组件之一。了解 containerd 有助于更深入地理解 Docker 和 Kubernetes 的底层运行机制。 + +### containerd 简介 + +[containerd](https://containerd.io/) 是一个行业标准的容器运行时,它最初是由 Docker 引擎中剥离出来的一个核心组件,后来 Docker 将其捐赠给了云原生计算基金会(CNCF),目前已经是一个 CNCF 毕业(Graduated)项目。 + +它的主要职责是管理单个宿主机上完整的容器生命周期,包括: +- 镜像的传输和存储 +- 容器执行和管理 +- 存储和网络接口的管理 + +简单来说,当你在使用 Docker 或者 Kubernetes 时,真正去底层调用操作系统接口(如 Linux 的 Namespace 和 Cgroups)来启动和管理容器进程的,往往是 containerd(及它所调用的 runc 组件)。 + +### 与 Docker 和 Kubernetes 的关系 + +理解 containerd,首先要理清它与用户日常操作的 Docker 以及 Kubernetes 的关系。 + +#### Docker 的架构 + +在早期,Docker 引擎是一个包含了所有功能的单体架构。随着技术的发展和标准化要求,Docker 将底层关于容器运行时的部分解耦出来,形成了 `containerd` 和 `runc`。 + +当你执行一个 `docker run` 命令时,调用链路大致如下: +1. Docker Client 发送请求给 Docker Daemon(`dockerd`)。 +2. `dockerd` 将请求转发给 `containerd`。 +3. `containerd` 准备好镜像和容器的必要环境,然后调用 `runc`。 +4. `runc` 负责按照 OCI(Open Container Initiative)标准,拉起并运行真正的容器进程。 + +因此,Docker 现在实际上是构建在 containerd 之上的一个包含更多开发者友好特性(如构建镜像、Compose 管理等)的增强平台。 + +#### Kubernetes 与 CRI + +Kubernetes 作为一个容器编排系统,为了屏蔽底层不同容器运行时的实现差异,引入了 CRI(Container Runtime Interface)标准。 + +- 早期版本中,Kubernetes 默认使用 docker 作为运行时,通过一个名为 `dockershim` 的桥接组件对接 Docker,Docker 再对接 containerd。 +- 随着 containerd 原生支持了 CRI 插件,Kubernetes 开始直接与 containerd 通信,去掉了 `dockershim` 和 `dockerd` 的中间层。这就是为什么从 Kubernetes v1.24 开始“弃用 Docker”引发了广泛关注,实际上 Kubernetes 只是弃用 `dockershim`,底层依然在使用从 Docker 基因中诞生的 containerd。 + +### 为什么直接使用 containerd? + +对普通应用开发者来说,Docker 依然是本地开发和测试的首选。但对于构建云平台、自动化流水线或深度管理 Kubernetes 集群的系统工程师来说,直接使用 containerd 可以带来: +- **更高的性能与更少的开销**:去掉了 Docker Daemon 等附加组件的资源占用,链路更短。 +- **更强的稳定性**:作为专注于运行时的底层组件,它的核心功能极为稳定且更新受控。 +- **直接符合 Kubernetes CRI 标准**:在生产级 Kubernetes 集群中作为标准配置。 + +### 基础用法与工具介绍 + +不同于 `docker` 命令行工具,containerd 提供了不同的客户端来满足不同的使用场景: + +- **ctr**:containerd 自带的调试用客户端。它功能比较基础,主要用于开发者在开发 containerd 时进行快速调试,一般不作为最终用户的日常管理工具。 +- **crictl**:Kubernetes 提供的 CRI 命令行工具。它用于排查 Kubernetes 节点上的容器和沙箱(Pod)问题。 +- **nerdctl**:这是一个由系统社区成员(主要是 containerd 项目的维护者)开发的,完全兼容 Docker CLI 体验的 containerd 命令行客户端。对于习惯了 `docker run/ps/build` 命令的用户来说,`nerdctl` 可以作为直接操作 containerd 的理想替代品,并且它还支持直接构建镜像(依赖 BuildKit)。 + +#### nerdctl 使用示例 + +安装完 containerd 和 nerdctl 后,你可以体验到几乎与 Docker 完全一致的命令行: + +```bash +# 启动一个 nginx 容器 +$ nerdctl run -d -p 8080:80 --name my-nginx nginx:alpine + +# 查看运行中的容器 +$ nerdctl ps + +# 查看本地镜像 +$ nerdctl images +``` + +对于那些希望在生产服务器上剥离 Docker 庞大体积,但又想要保留类似 Docker 方便的命令行体验的用户,`containerd` + `nerdctl` 是一个极佳的组合。 diff --git a/17_ecosystem/17.7_secure_runtime.md b/17_ecosystem/17.7_secure_runtime.md new file mode 100644 index 000000000..af2563cfc --- /dev/null +++ b/17_ecosystem/17.7_secure_runtime.md @@ -0,0 +1,53 @@ +## 17.7 安全容器运行时 + +本节介绍容器技术生态中的安全运行时机制,主要探讨在隔离性和安全性上比标准 Linux 容器更进一步的方案,重点介绍 Kata Containers 和 gVisor。 + +### 为什么需要安全容器? + +标准的 Linux 容器(如 Docker、Podman 或基础的 containerd/runc 所提供的)依赖于 Linux 内核的 **Namespace(命名空间)** 和 **Cgroups(控制组)** 来实现进程级别的隔离与资源限制。这种轻量级的虚拟化方式共享同一个宿主机的内核。 + +尽管这种方式在性能和启动速度上拥有巨大优势,但也带来了一个显著的缺点:**隔离性(Isolation)不足**。如果某个容器内的恶意进程利用了宿主机内核的漏洞完成了越狱(Privilege Escalation),它将对整个宿主机以及其上运行的所有其他容器造成毁灭性威胁。 + +如果在公有云环境(多租户场景)或运行不可信的第三方代码时,共享内核显然是不够安全的。为了解决这一问题,社区推出了“安全容器(Secure Containers/Sandboxed Containers)”的概念。安全容器的核心理念是:提供类似虚拟机的强隔离性,同时保持类似容器的轻量、快速启动和标准化管理。 + +### 什么是 Kata Containers? + +[Kata Containers](https://katacontainers.io/) 是一个开源项目,由 OpenStack Foundation(现更名为 OpenInfra Foundation)托管。它将早期的两个项目——Intel Clear Containers 和 Hyper runV 结合而成。 + +Kata Containers 的核心思路是:**使用轻量级的虚拟机(Lightweight VM)来运行每一个容器或者 Pod**。 + +#### 工作原理 + +当使用 Kata Containers 时,它不是在宿主机上启动一个普通的独立进程,而是调用一个精简高度优化的虚拟机管理程序(如 QEMU、Firecracker 或 Cloud Hypervisor)启动一个小型的虚拟机。容器内的应用进程运行在这个虚拟机拥有独立特制内核的沙箱中。 + +- **高度隔离**:因为拥有自己的独立内核,即使容器内的应用利用内核漏洞溢出,它也只能破坏虚拟机虚拟出来的内核,根本无法触及宿主机真正的内核。 +- **兼容性**:Kata Containers 完全实现了 OCI(Open Container Initiative)规范和 CRI(Container Runtime Interface)标准。这意味着它可以作为 `containerd` 或 `Docker` 的底层运行时无缝替换默认的 `runc`。 +- **与 Kubernetes 集成**:在 Kubernetes 中,你可以为一个特定的 Pod 指定 `runtimeClassName: kata`,让高敏感的任务自动运行在虚拟机级别的隔离环境中。 + +### 什么是 gVisor? + +[gVisor](https://gvisor.dev/) 是由 Google 开发并开源的一种不同流派的沙箱容器运行时方案。 + +它采取了与 Kata Containers 完全不同的技术路线,它不是启动完整的虚拟机,而是提供了一个 **应用态内核(User-space Kernel)**。 + +#### 工作原理 + +gVisor 的核心组件是一个名为 **Sentry** 的用户空间进程。Sentry 扮演了一个“内核代理”的角色。 + +- 当容器内的应用想要进行系统调用(System Call,比如读写文件、网络通信)时,这些调用会被 Sentry 拦截并进行一层虚拟化处理,然后再由 Sentry 把经过安全过滤和转换的请求转发给宿主机内核。 +- 因为 Sentry 在用户态实现了一套 Linux 系统调用接口,它极大减少了应用直接接触底层操作系统内核的表面积。这样就有效防御了利用底层内核漏洞突破隔离的攻击方式。 +- gVisor 同样兼容 OCI 规范,其核心运行时组件称为 `runsc`,可以作为底层运行时与 Docker 或 Kubernetes 进行集成。 + +### 总结与对比 + +| 特性 | 标准 Linux 容器 (runc) | Kata Containers | gVisor (runsc) | +| :--- | :--- | :--- | :--- | +| **隔离技术** | Namespace & Cgroups | 轻量级虚拟机 (独立内核) | 用户态内核 (系统调用拦截) | +| **安全性** | 较低(共享宿主机内核) | 极高(硬件级虚拟化隔离) | 高(减少内核攻击面) | +| **性能开销** | 极小(原生进程) | 中等(因轻量化而优于传统 VM) | 中等到较高(取决于系统调用频率开销) | +| **启动速度** | 极快(毫秒/秒级) | 快(秒级之内) | 快(接近原生容器) | +| **兼容性** | 完美(所有系统调用均支持原始实现) | 极好(拥有完整内核) | 好(但在极少数复杂的未被拦截支持的系统调用中可能报错) | + +如今,诸如 AWS 这样的云厂商也推出了针对无服务器容器功能(Serverless Containers)的高度优化的轻量级虚拟机管理器 **Firecracker**,可以看作是安全容器生态中与 Kata 类似方案的底层基石。 + +对于普通的微服务开发来说可能不需要考虑使用安全容器,但在提供多租户平台即服务(PaaS)、运行无状态边缘计算函数(FaaS)等对安全隔离要求极高的场景中,以 Kata Containers 和 gVisor 为代表的安全容器技术展现出了巨大的价值。 diff --git a/17_ecosystem/17.8_wasm.md b/17_ecosystem/17.8_wasm.md new file mode 100644 index 000000000..cc7e6b7b7 --- /dev/null +++ b/17_ecosystem/17.8_wasm.md @@ -0,0 +1,43 @@ +## 17.8 WebAssembly 与容器 + +本节介绍 WebAssembly (简写为 Wasm) 以及它为何成为现代容器生态中备受瞩目的前沿技术路线。 + +### 什么是 WebAssembly? + +[WebAssembly (Wasm)](https://webassembly.org/) 最初是由 W3C 主导的一项为了解决网页中 JavaScript 性能瓶颈而发明的技术标准。它是一种小体积的、加载极快的、提供安全沙盒的高效二进制格式的指令集架构。通过将 C/C++、Rust、Go 等高级语言编译成 `.wasm` 格式,这些程序可以直接在所有现代的浏览器中以接近原生代码的速度安全地运行。 + +然而,一项原本用于前端领域的技术,为何如今却与容器云计算生态产生了强烈的化学反应? + +因为开源社区很快意识到,Wasm 所具备的核心特性完美契合了云原生后端的诉求。人们制定了诸如 **WASI (WebAssembly System Interface)** 这样的标准,将其能力从浏览器扩展到了服务器端操作系统上。 + +### Wasm 与容器特性的完美契合 + +将 Wasm 应用于服务端时,它展现出了一些可能比传统 Linux 容器更为优异的特性: + +1. **极速的冷启动性能**: + 传统 Linux 容器虽然比虚拟机轻量很多,但它启动依然需要建立 Namespace 和 Cgroups 以及一整套文件系统,通常需要近百毫秒到几秒。而 Wasm 模块不需要这样庞杂的环境初始化,能够在几毫秒之内完成从加载到执行,这对于无服务器函数(Serverless Functions)而言是巨大的提升。 + +2. **跨平台性 (Write Once, Run Anywhere)**: + 我们知道 Docker 等容器通常是绑定架构的。如果是 x86_64 平台上打出的镜像,通常无法直接在基于 ARM 的系统(如苹果 M 系列芯片甚至树莓派)上直接运行原生代码,除非使用 QEMU 进行低效转译或者专门构建多架构(Multi-arch)镜像和 manifests。 + 而 Wasm 二进制本身是平台无关的平台中间语言代码形式!你编译出来的一份 `.wasm` 可执行模块,不用做任何修改,就可以在 x86 的 Linux 服务器、ARM 的边缘设备、甚至是 Windows 和 macOS 上直接通过 Wasm 运行时来驱动和执行。真正做到了“编写一次,到处运行”。 + +3. **天然的安全沙箱机制**: + Wasm 设计之初就是在不被信任的浏览器沙盒环境中运行未知代码的,因此执行环境非常安全,采用了极好的能力导向安全模型。应用只能访问它被明确授予权限的文件或能力。其默认安全隔离性比起依靠 Namespaces 机制的共享内核的 Linux 容器更加坚固。 + +4. **极小的包体积**: + Linux 容器需要打包一整套依赖甚至是简化的 OS 根目录结构。而一个编译好的功能完善的 Wasm 模块体积常常不到几兆甚至仅仅几十 Kb,极大地加快了存储及网络利用效率。 + +### 当 Docker 遇上 WebAssembly + +在现代的容器生态系统中,Wasm 并不被看作是要被取代传统的 Docker 或者 Kubernetes 的技术,而是成为了一种 **与 Linux 容器互补并且共生** 的全新工作负载类型。 + +目前,这通过 OCI (Open Container Initiative) 和 CRI 标准实现了集成上的统一: + +1. **将 Wasm 打包为 OCI 镜像**:虽然内容并非传统的 Linux RootFS,但是通过标准化的打包工具同样可以将应用程序及其 `.wasm` 构建结果转化为一个可以被推送至 Docker Hub 或其他 registry 的标准化镜像规范。 +2. **通过容器运行时直接执行**:Docker 已经与如 [WasmEdge](https://wasmedge.org/) 和 [Spin](https://developer.fermyon.com/spin) 等高性能的企业级 Wasm 运行时进行了官方集成合作。 + +如今在 Docker Desktop 或者集成了 `containerd` 的环境中,我们可以十分简易地以类似普通镜像的形式去拉取并运行一个基于 Wasm 编译的后端服务(通过指定相应的 `--platform` 或者是特别的 `--runtime=io.containerd.wasmedge.v1` 设置),将其如同对待一个标准应用进程一样让 Docker 为其接管日志、配置相关的网络端口映射,甚至通过 Docker Compose 将一个普通的数据库容器实例与一个 Wasm 微服务实例协同起来混布。 + +### 总结 + +随着技术底座如 WASI 规范不断的成熟完善(例如提供完备的套接字网络支持以及系统资源访问支持),我们有理由相信不仅是边缘计算与无服务器调用,会有越来越多对于速度和安全性有极高指标要求的云原生后端微服务开始采用这一颠覆传统边界的轻量级“微型智能体”架构。在可见的将来,Wasm 势必成为云原生与 Docker 生态的重要拼图。 diff --git a/17_ecosystem/README.md b/17_ecosystem/README.md index dd7079df7..783bfc2d5 100644 --- a/17_ecosystem/README.md +++ b/17_ecosystem/README.md @@ -4,3 +4,8 @@ - **Fedora CoreOS**:专为容器化工作负载设计的操作系统。 - **Podman**:兼容 Docker CLI 的下一代无守护进程容器引擎。 +- **Buildah**:无需守护进程的 OCI 容器镜像构建工具。 +- **Skopeo**:远程检查和管理容器镜像的利器。 +- **containerd**:作为现代容器生态基石的核心容器运行时。 +- **安全容器运行时**:通过提供更强隔离性来保证安全的技术方案(如 Kata Containers、gVisor)。 +- **WebAssembly**:一种极具潜力的轻量级跨平台二进制指令格式。 diff --git a/17_ecosystem/summary.md b/17_ecosystem/summary.md index de1bcb325..d9e84050a 100644 --- a/17_ecosystem/summary.md +++ b/17_ecosystem/summary.md @@ -5,9 +5,14 @@ Docker 并非容器生态的唯一选择,了解其他工具有助于根据场 | 项目 | 定位 | 特点 | |------|------|------| | **Fedora CoreOS** | 容器化操作系统 | 自动更新、不可变基础设施、专为运行容器设计 | -| **Podman** | 容器引擎 | 无守护进程、兼容 Docker CLI、支持 Rootless 模式 | +| **Podman** | 容器管理引擎 | 无守护进程、兼容 Docker CLI、支持 Rootless 模式、支持原生 Pod | +| **Buildah** | 镜像构建工具 | Daemonless 工作模式、灵活的脚本化构建能力 | +| **Skopeo** | 镜像仓库管理 | 无需拉取即可检查远端镜像、跨仓库/格式无缝迁移镜像 | +| **containerd** | 核心底层运行时 | 稳定高效、符合 CRI 规范、是 Docker 的基石之一 | +| **安全容器** | 强隔离沙箱运行 | 利用轻量级虚拟机 (Kata) 或用户态内核 (gVisor) 防止越狱,极其安全 | +| **Wasm** | 新型工作负载 | 体积极小、冷启动超快且具备跨平台及高度特征化沙盒能力的后端架构新方向 | -### 17.4.1 Podman vs Docker +### Podman vs Docker 两者的主要区别: @@ -19,7 +24,7 @@ Docker 并非容器生态的唯一选择,了解其他工具有助于根据场 | **Pod 支持** | 不支持 | 原生支持 Pod 概念 | | **Compose** | docker compose | podman-compose 或兼容模式 | -### 17.4.2 延伸阅读 +### 延伸阅读 - [底层实现](../12_implementation/README.md):容器技术的内核基础 - [安全](../18_security/README.md):容器安全实践 diff --git a/19_observability/summary.md b/19_observability/summary.md index 3415d26f0..202a99963 100644 --- a/19_observability/summary.md +++ b/19_observability/summary.md @@ -1,4 +1,4 @@ -# 本章小结 +## 本章小结 本章从两个维度介绍了容器可观测性: diff --git a/21_case_devops/21.2_github_actions.md b/21_case_devops/21.2_github_actions.md index 273aea164..c99dfa354 100644 --- a/21_case_devops/21.2_github_actions.md +++ b/21_case_devops/21.2_github_actions.md @@ -1,4 +1,4 @@ -# 21.2 GitHub Actions +## 21.2 GitHub Actions GitHub [Actions](https://github.com/features/actions) 是 GitHub 推出的一款 CI/CD 工具。 diff --git a/21_case_devops/21.3_drone.md b/21_case_devops/21.3_drone.md index cb00eee07..51d53ce44 100644 --- a/21_case_devops/21.3_drone.md +++ b/21_case_devops/21.3_drone.md @@ -1,4 +1,4 @@ -# 21.3 Drone +## 21.3 Drone 基于 `Docker` 的 `CI/CD` 工具 `Drone`,所有编译、测试的流程都在容器中进行。 diff --git a/21_case_devops/21.4_drone_demo.md b/21_case_devops/21.4_drone_demo.md index 5efe2acfd..b31f79935 100644 --- a/21_case_devops/21.4_drone_demo.md +++ b/21_case_devops/21.4_drone_demo.md @@ -1,4 +1,4 @@ -# 21.4 Drone Demo +## 21.4 Drone Demo ## 21.4.1 Demo 项目说明 diff --git a/21_case_devops/21.5_ide.md b/21_case_devops/21.5_ide.md index b217ff00e..972d5e1e1 100644 --- a/21_case_devops/21.5_ide.md +++ b/21_case_devops/21.5_ide.md @@ -1,4 +1,4 @@ -# 21.5 在 IDE 中使用 Docker +## 21.5 在 IDE 中使用 Docker 使用 IDE 进行开发,往往要求本地安装好工具链。一些 IDE 支持 Docker 容器中的工具链,这样充分利用了 Docker 的优点,而无需在本地安装。 diff --git a/SUMMARY.md b/SUMMARY.md index c14ff91cd..b53f77454 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -148,6 +148,11 @@ * [17.1 Fedora CoreOS 简介](17_ecosystem/17.1_coreos_intro.md) * [17.2 Fedora CoreOS 安装](17_ecosystem/17.2_coreos_install.md) * [17.3 podman - 下一代 Linux 容器工具](17_ecosystem/17.3_podman.md) + * [17.4 Buildah - 容器镜像构建工具](17_ecosystem/17.4_buildah.md) + * [17.5 Skopeo - 容器镜像管理工具](17_ecosystem/17.5_skopeo.md) + * [17.6 containerd - 核心容器运行时](17_ecosystem/17.6_containerd.md) + * [17.7 安全容器运行时](17_ecosystem/17.7_secure_runtime.md) + * [17.8 WebAssembly 与容器](17_ecosystem/17.8_wasm.md) * [本章小结](17_ecosystem/summary.md) ## 第四部分:实战篇 @@ -199,3 +204,4 @@ * [附录四:Dockerfile 最佳实践](appendix/best_practices.md) * [附录五:如何调试 Docker](appendix/debug.md) * [附录六:资源链接](appendix/resources.md) + * [附录七:术语表](appendix/glossary.md) diff --git a/_images/cmd_logic.jpg b/_images/cmd_logic.jpg new file mode 100644 index 000000000..d686f2894 Binary files /dev/null and b/_images/cmd_logic.jpg differ diff --git a/_images/cmd_logic.png b/_images/cmd_logic.png deleted file mode 100644 index d8deeb255..000000000 Binary files a/_images/cmd_logic.png and /dev/null differ diff --git a/_images/install-mac-apps.jpg b/_images/install-mac-apps.jpg new file mode 100644 index 000000000..4388f41b1 Binary files /dev/null and b/_images/install-mac-apps.jpg differ diff --git a/_images/install-mac-apps.png b/_images/install-mac-apps.png deleted file mode 100644 index 206ecd130..000000000 Binary files a/_images/install-mac-apps.png and /dev/null differ diff --git a/_images/install-mac-dmg.jpg b/_images/install-mac-dmg.jpg new file mode 100644 index 000000000..d7839ceb6 Binary files /dev/null and b/_images/install-mac-dmg.jpg differ diff --git a/_images/install-mac-dmg.png b/_images/install-mac-dmg.png deleted file mode 100644 index 5c251db3b..000000000 Binary files a/_images/install-mac-dmg.png and /dev/null differ diff --git a/appendix/README.md b/appendix/README.md index 7159afff4..a0c0fce25 100644 --- a/appendix/README.md +++ b/appendix/README.md @@ -10,5 +10,4 @@ * [**Dockerfile 最佳实践**](best_practices.md):提供编写高效、安全 Dockerfile 的指导原则。 * [**如何调试 Docker**](debug.md):介绍 Docker 调试技巧和工具。 * [**资源链接**](resources.md):推荐更多 Docker 相关的学习资源。 -* **术语词表 (出版统一版)**:统一全书中英文术语、缩写与命令写法。(本仓库暂未收录对应文件) -* **出版清稿规范 (图号与章节风格)**:统一图号命名、图题写法与章节风格。(本仓库暂未收录对应文件) +* [**术语词表**](glossary.md):统一全书中英文术语、缩写与命令写法。 diff --git a/appendix/best_practices.md b/appendix/best_practices.md index 9a79822f6..b20c007fe 100644 --- a/appendix/best_practices.md +++ b/appendix/best_practices.md @@ -174,9 +174,9 @@ RUN apt-get update && apt-get install -y \ #### CMD -`CMD` 指令用于执行目标镜像中包含的软件,可以包含参数。`CMD` 大多数情况下都应该以 `CMD ["executable", "param1", "param2"...]` 的形式使用。因此,如果创建镜像的目的是为了部署某个服务 (比如 `Apache`),你可能会执行类似于 `CMD ["apache2", "-DFOREGROUND"]` 形式的命令。我们建议任何服务镜像都使用这种形式的命令。 +`CMD` 指令用于执行目标镜像中包含的软件,可以包含参数。`CMD` 大多数情况下都应该以 `CMD ['executable', 'param1', 'param2'...]` 的形式使用。因此,如果创建镜像的目的是为了部署某个服务 (比如 `Apache`),你可能会执行类似于 `CMD ['apache2', '-DFOREGROUND']` 形式的命令。我们建议任何服务镜像都使用这种形式的命令。 -多数情况下,`CMD` 都需要一个交互式的 `shell` (bash,Python,perl 等),例如 `CMD ["perl", "-de0"]`,或者 `CMD ["PHP", "-a"]`。使用这种形式意味着,当你执行类似 `docker run -it python` 时,你会进入一个准备好的 `shell` 中。`CMD` 应该在极少的情况下才能以 `CMD ["param", "param"]` 的形式与 `ENTRYPOINT` 协同使用,除非你和你的镜像使用者都对 `ENTRYPOINT` 的工作方式十分熟悉。 +多数情况下,`CMD` 都需要一个交互式的 `shell` (bash,Python,perl 等),例如 `CMD ['perl', '-de0']`,或者 `CMD ['PHP', '-a']`。使用这种形式意味着,当你执行类似 `docker run -it python` 时,你会进入一个准备好的 `shell` 中。`CMD` 应该在极少的情况下才能以 `CMD ['param', 'param']` 的形式与 `ENTRYPOINT` 协同使用,除非你和你的镜像使用者都对 `ENTRYPOINT` 的工作方式十分熟悉。 #### EXPOSE diff --git a/appendix/command/docker.md b/appendix/command/docker.md index 397c5c1ef..44ace7187 100644 --- a/appendix/command/docker.md +++ b/appendix/command/docker.md @@ -66,7 +66,7 @@ 如图 16-1 所示,Docker 常用客户端命令可按功能分组理解。 -![Docker 命令总结](../../_images/cmd_logic.png) +![Docker 命令总结](../../_images/cmd_logic.jpg) 图 16-1 Docker 客户端命令分类示意图 diff --git a/appendix/glossary.md b/appendix/glossary.md new file mode 100644 index 000000000..091dc16e6 --- /dev/null +++ b/appendix/glossary.md @@ -0,0 +1,82 @@ +# 附录七:术语表 + +本附录整理了本书中常见的一些专业术语及其解释。 + +## A + +* **Alpine**:一个轻量级的 Linux 发行版,常作为基础镜像用于构建体积较小的 Docker 镜像。 +* **API (Application Programming Interface)**:应用程序编程接口,Docker Daemon 提供 RESTful API 供客户端或外部程序与之交互。 + +## B + +* **Base Image (基础镜像)**:没有父镜像的镜像,通常是操作系统的最小安装集合(如 `ubuntu` 或 `alpine`)。 +* **BuildKit**:Docker 下一代的构建引擎,提供了更高的构建性能、更好的缓存处理和并发构建支持。 +* **Buildx**:Docker CLI 的一个插件,扩展了构建功能,支持 BuildKit 的所有高级特性,例如多系统架构镜像构建。 + +## C + +* **Cgroups (Control Groups)**:控制组,Linux 内核特性,用于限制、记录、隔离进程组使用的物理资源(如 CPU、内存、磁盘 I/O 等)。 +* **Cluster (集群)**:一组协同工作的节点(如主机、虚拟机等),在容器领域常指 Kubernetes 集群。 +* **Compose (Docker Compose)**:用于定义和运行多容器 Docker 应用程序的工具,通过 YAML 文件配置应用服务。 +* **Container (容器)**:镜像的运行实例,带有额外的可写文件层,具有独立性。 +* **Containerd**:行业标准的容器运行时,核心功能是管理宿主机上容器的生命周期(创建、启动、停止、销毁)。 + +## D + +* **Daemon (守护进程)**:Docker 的后台守护进程,负责接收和处理 Docker API 请求,并管理镜像、容器、网络和数据卷等对象。 +* **Docker**:开源的应用容器引擎,让开发者可以打包应用程序及其依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 或 Windows 机器上。 +* **Docker Desktop**:包含 Docker Engine、Docker CLI 客户端、Docker Compose 和 Kubernetes 等的桌面应用程序,适用于 macOS 和 Windows。 +* **Docker Hub**:Docker 官方的公共镜像仓库服务,提供容器镜像的存储和分发。 +* **Dockerfile**:包含用于组合镜像的命令的文本文件,Docker 通过读取 `Dockerfile` 中的指令即可自动完成镜像构建。 + +## E + +* **Etcd**:一个高可用、强一致性的分布式键值存储系统,常用于容器集群(如 Kubernetes)的服务发现和状态配置管理。 + +## I + +* **Image (镜像)**:Docker 镜像是一个只读模板,带有创建 Docker 容器的说明。 + +## K + +* **Kubernetes (K8s)**:开源的容器编排引擎,用于自动化容器化应用程序的部署、扩展和管理。 + +## L + +* **Layer (镜像层)**:Docker 镜像由多个只读层叠合而成,每一层通常代表 Dockerfile 中的一条指令的操作结果,通过联合文件系统(UFS)叠加在一起形成完整的文件系统。 + +## M + +* **Multistage Build (多阶段构建)**:Dockerfile 中的特性,允许在同一个 Dockerfile 中使用多个 `FROM` 语句,从一个阶段复制所需的构建产物到另一个阶段,从而大幅减小最终镜像的体积。 + +## N + +* **Namespace (命名空间)**:Linux 内核特性,用于隔离各种系统资源,如进程、网络、挂载点等,使容器看起来就像是一个独立的操作系统。 +* **Node (节点)**:容器集群(如 Kubernetes)中的一台工作机器,可以是物理机或虚拟机。 + +## O + +* **OCI (Open Container Initiative)**:开放容器规范,由多家行业领头企业共同制定的容器运行时和镜像格式的行业标准。 +* **Orchestration (编排)**:自动化部署、管理、扩展和网络配置容器的系统和技术(如 Kubernetes)。 + +## P + +* **Pod**:Kubernetes 中最小的、可部署的计算单元,包含一个或多个紧密相关的容器,共享相同的网络命名空间和存储。 +* **Prometheus**:开源的系统监控和告警工具包,广泛应用于云原生的监控体系中。 + +## R + +* **Registry (注册服务器)**:提供 Docker 镜像下载和上传等存储分发服务的服务器。 +* **Repository (仓库)**:集中存放某个应用的所有镜像的地方,通常由镜像名定义。一个 Registry 中可以包含多个 Repository。 + +## S + +* **Swarm (Docker Swarm)**:Docker 原生的集群和编排管理工具,可将多个 Docker 主机组合成一个统一的虚拟 Docker 主机池。 + +## U + +* **UFS (Union File System)**:联合文件系统,一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改一层层叠加。 + +## V + +* **Volume (数据卷)**:专为绕过联合文件系统而设计的特殊目录,用于实现容器数据的持久化,或在多个容器之间提供文件共享。 diff --git a/book.json b/book.json index d31db4d7b..49e499f90 100644 --- a/book.json +++ b/book.json @@ -11,7 +11,7 @@ "-livereload", "image-captions", "github", - "page-treeview@2.9.8", + "page-treeview", "editlink" ], "pluginsConfig": { diff --git a/format_report.txt b/format_report.txt deleted file mode 100644 index 6e41aff9b..000000000 --- a/format_report.txt +++ /dev/null @@ -1 +0,0 @@ -Total issues found: 0 diff --git a/package.json b/package.json index e564b4137..76e16e144 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "description": "docker_practice", "main": "index.js", "devDependencies": { - "chalk": "^4.1.1", - "commander": "^7.2.0", + "chalk": "^5.6.2", + "commander": "^14.0.3", "esm": "^3.0.0", - "honkit": "^5.1.0", - "vuepress": "1.8.2", + "honkit": "^6.1.6", + "vuepress": "1.9.10", "vuepress-plugin-container": "^2.1.5", "vuepress-theme-hope": "^1.0.0" },