3 Commits

Author SHA1 Message Date
Baohua Yang
a9c4189c0c Remove duplicated content 2026-03-01 22:48:51 -08:00
Baohua Yang
56deeaee0f Use docker engine v29 2026-03-01 22:47:56 -08:00
Baohua Yang
0ff67cc893 Add security note 2026-02-28 14:28:38 -08:00
19 changed files with 130 additions and 50 deletions

View File

@@ -45,7 +45,7 @@ $ docker run -d -p 8080:80 my-hello-world
### 1.1.5 访问测试 ### 1.1.5 访问测试
打开浏览器访问 [http://localhost:8080](http://localhost:8080),你应该能看到 “HelloDocker”。 打开浏览器访问 [http://localhost:8080](http://localhost:8080),你应该能看到 “Hello, Docker!”。
### 1.1.6 清理 ### 1.1.6 清理

View File

@@ -2,13 +2,15 @@
本章将带领你进入 **Docker** 的世界 本章将带领你进入 **Docker** 的世界
> **版本提示**本书内容及示例基于 **Docker Engine v29.x** 及以上版本值得注意的是 Docker Engine v29 官方在全新安装场景下**默认启用了 `containerd image store` 作为镜像存储后端**取代了传统的经典存储引擎如 overlay2 graph driver这项底层革新极大增强了 Docker 对多架构镜像Multi-platform以及软件供应链安全元数据Attestations, SBOM, Provenance的本地支持原生性
## 本章内容 ## 本章内容
* [快速上手](1.1_quickstart.md) * [快速上手](1.1_quickstart.md)
* 通过一个简单的 Web 应用例子带你快速体验 Docker 的核心流程构建镜像运行容器 * 通过一个简单的 Web 应用例子带你快速体验 Docker 的核心流程构建镜像运行容器
* [什么是 Docker](1.2_what.md) * [什么是 Docker](1.2_what.md)
* 介绍 Docker 的起源发展历程以及其背后的核心技术 (CgroupsNamespacesUnionFS) * 介绍 Docker 的起源发展历程以及其背后的核心技术 (CgroupsNamespacesUnionFS以及 `containerd` 引擎的演进)
* 了解 Docker 是如何改变软件交付方式的 * 了解 Docker 是如何改变软件交付方式的
* [为什么要用 Docker](1.3_why.md) * [为什么要用 Docker](1.3_why.md)

View File

@@ -1,40 +1,18 @@
## 本章小结 ## 本章小结
本章介绍了 Docker 的三个核心概念镜像容器和仓库
| 概念 | 要点 | | 概念 | 要点 |
|------|------| |------|------|
| **镜像是什么** | 只读的应用模板包含运行所需的一切 | | **镜像是什么** | 只读的应用模板包含运行所需的一切 |
| **分层存储** | 多层叠加共享基础层节省空间 | | **分层存储** | 多层叠加共享基础层节省空间 |
| **只读特性** | 构建后不可修改保证一致性 | | **只读特性** | 构建后不可修改保证一致性 |
| **层的陷阱** | 删除操作只是标记不减小体积 | | **层的陷阱** | 删除操作只是标记不减小体积 |
理解了镜像接下来让我们学习[容器](2.2_container.md)镜像的运行实例
### 2.4.1 延伸阅读
- [获取镜像](../04_image/4.1_pull.md) Registry 下载镜像
- [使用 Dockerfile 定制镜像](../04_image/4.5_build.md)创建自己的镜像
- [Dockerfile 最佳实践](../appendix/best_practices.md)构建高质量镜像的技巧
- [底层实现 - 联合文件系统](../12_implementation/12.4_ufs.md)深入理解分层存储的技术原理
| 概念 | 要点 |
|------|------|
| **容器是什么** | 镜像的运行实例本质是隔离的进程 | | **容器是什么** | 镜像的运行实例本质是隔离的进程 |
| **容器 vs 虚拟机** | 共享内核更轻量但隔离性较弱 | | **容器 vs 虚拟机** | 共享内核更轻量但隔离性较弱 |
| **存储层** | 可写层随容器删除而消失 | | **存储层** | 可写层随容器删除而消失 |
| **数据持久化** | 使用 Volume Bind Mount | | **数据持久化** | 使用 Volume Bind Mount |
| **生命周期** | 与主进程 (PID 1) 绑定 | | **生命周期** | 与主进程 (PID 1) 绑定 |
理解了镜像和容器接下来让我们学习[仓库](2.3_repository.md)存储和分发镜像的服务
### 2.4.2 延伸阅读
- [启动容器](../05_container/5.1_run.md)详细的容器启动选项
- [后台运行](../05_container/5.2_daemon.md)理解容器为什么会 立即退出
- [进入容器](../05_container/5.4_attach_exec.md)如何操作运行中的容器
- [数据管理](../08_data/README.md)Volume 和数据持久化详解
| 概念 | 要点 |
|------|------|
| **Registry** | 存储和分发镜像的服务 | | **Registry** | 存储和分发镜像的服务 |
| **仓库 (Repository)** | 同一软件的镜像集合 | | **仓库 (Repository)** | 同一软件的镜像集合 |
| **标签 (Tag)** | 版本标识默认为 latest | | **标签 (Tag)** | 版本标识默认为 latest |
@@ -43,8 +21,16 @@
现在你已经了解了 Docker 的三个核心概念[镜像](2.1_image.md)[容器](2.2_container.md)和仓库接下来让我们开始[安装 Docker](../03_install/README.md)动手实践 现在你已经了解了 Docker 的三个核心概念[镜像](2.1_image.md)[容器](2.2_container.md)和仓库接下来让我们开始[安装 Docker](../03_install/README.md)动手实践
### 2.4.3 延伸阅读 ### 延伸阅读
- [获取镜像](../04_image/4.1_pull.md) Registry 下载镜像
- [使用 Dockerfile 定制镜像](../04_image/4.5_build.md)创建自己的镜像
- [Dockerfile 最佳实践](../appendix/best_practices.md)构建高质量镜像的技巧
- [底层实现 - 联合文件系统](../12_implementation/12.4_ufs.md)深入理解分层存储的技术原理
- [启动容器](../05_container/5.1_run.md)详细的容器启动选项
- [后台运行](../05_container/5.2_daemon.md)理解容器为什么会"立即退出"
- [进入容器](../05_container/5.4_attach_exec.md)如何操作运行中的容器
- [数据管理](../08_data/README.md)Volume 和数据持久化详解
- [Docker Hub](../06_repository/6.1_dockerhub.md)Docker Hub 的详细使用 - [Docker Hub](../06_repository/6.1_dockerhub.md)Docker Hub 的详细使用
- [私有仓库](../06_repository/6.2_registry.md)搭建私有 Registry - [私有仓库](../06_repository/6.2_registry.md)搭建私有 Registry
- [私有仓库高级配置](../06_repository/6.3_registry_auth.md)认证TLS 配置 - [私有仓库高级配置](../06_repository/6.3_registry_auth.md)认证TLS 配置

View File

@@ -122,7 +122,12 @@ $ sudo systemctl start docker
### 3.1.5 建立 docker 用户组 ### 3.1.5 建立 docker 用户组
默认情况下`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑一般 Linux 系统上不会直接使用 `root` 用户。因此,更好做法是将需要使用 `docker` 的用户加入 `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 守护进程和容器。
建立 `docker` 建立 `docker`

View File

@@ -113,7 +113,12 @@ $ sudo systemctl start docker
### 3.2.5 建立 docker 用户组 ### 3.2.5 建立 docker 用户组
默认情况下`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑一般 Linux 系统上不会直接使用 `root` 用户。因此,更好做法是将需要使用 `docker` 的用户加入 `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 守护进程和容器。
建立 `docker` 建立 `docker`

View File

@@ -121,7 +121,12 @@ $ sudo systemctl start docker
### 3.3.5 建立 docker 用户组 ### 3.3.5 建立 docker 用户组
默认情况下`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑一般 Linux 系统上不会直接使用 `root` 用户。因此,更好做法是将需要使用 `docker` 的用户加入 `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 守护进程和容器。
建立 `docker` 建立 `docker`

View File

@@ -126,7 +126,12 @@ $ sudo systemctl start docker
### 3.4.6 建立 docker 用户组 ### 3.4.6 建立 docker 用户组
默认情况下`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑一般 Linux 系统上不会直接使用 `root` 用户。因此,更好做法是将需要使用 `docker` 的用户加入 `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 守护进程和容器。
建立 `docker` 建立 `docker`

View File

@@ -140,7 +140,12 @@ $ sudo systemctl start docker
### 3.5.5 建立 docker 用户组 ### 3.5.5 建立 docker 用户组
默认情况下`docker` 命令会使用 [Unix socket](https://en.wikipedia.org/wiki/Unix_domain_socket) 与 Docker 引擎通讯。而只有 `root` 用户和 `docker` 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑一般 Linux 系统上不会直接使用 `root` 用户。因此,更好做法是将需要使用 `docker` 的用户加入 `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 守护进程和容器。
建立 `docker` 建立 `docker`

View File

@@ -93,14 +93,13 @@ $ docker push username/myapp:v1
Account Settings -> Security 中启用 2FA保护账号安全启用后CLI 登录需要使用 **Access Token** 而非密码 Account Settings -> Security 中启用 2FA保护账号安全启用后CLI 登录需要使用 **Access Token** 而非密码
#### 2. 使用 Access Token #### 2. 使用 Access Token
> ** 警告**绝不要在脚本或 CI/CD 系统中直接使用 `-p` 参数传递密码或 Token (类似 `docker login -p xxx`)这会导致凭证直接暴露在系统的命令历史进程列表和终端输出中
不要在脚本或 CI/CD 中直接使用登录密码 1. Docker Hub -> Account Settings -> Security -> Access Tokens 创建 Token (PAT)
2. Token 通过标准输入 (stdin) 安全传递给 Docker:
1. Docker Hub -> Account Settings -> Security -> Access Tokens 创建 Token
2. 使用 Token 作为密码登录
```bash ```bash
$ docker login -u username -p dckr_pat_xxxxxxx $ echo "dckr_pat_xxxxxxx" | docker login --username username --password-stdin
``` ```
#### 3. 关注镜像漏洞 #### 3. 关注镜像漏洞

View File

@@ -138,9 +138,11 @@ $ docker run -d \
| 特性 | --mount | -v | | 特性 | --mount | -v |
|------|---------|-----| |------|---------|-----|
| 语法 | 键值对更清晰 | 冒号分隔更简洁 | | 语法 | 键值对更清晰 | 冒号分隔更简洁 |
| 自动创建卷 | source 不存在会报错 | 自动创建 | | 自动创建卷 | source 不存在会自动创建 | 自动创建 |
| 推荐程度 | 推荐 (更明确)| 常用 (更简洁)| | 推荐程度 | 推荐 (更明确)| 常用 (更简洁)|
> **提示**很多人误以为 `--mount` 遇到目标不存在时总是报错实际上那仅适用于**绑定挂载 (Bind Mount)**对于**数据卷 (Volume)**只要 `source` 指定的卷名称不存在Docker 都会默默将其创建出来
#### 只读挂载 #### 只读挂载
```bash ```bash

View File

@@ -74,9 +74,11 @@ $ docker run -d \
| 特性 | --mount | -v | | 特性 | --mount | -v |
|------|---------|-----| |------|---------|-----|
| 语法 | 键值对更清晰 | 冒号分隔更简洁 | | 语法 | 键值对更清晰 | 冒号分隔更简洁 |
| 路径不存在时 | 报错 | 自动创建目录 | | 路径不存在时 | 直接报错 (Fail Fast) | 静默自动创建**目录** |
| 推荐程度 | 推荐 | 常用 | | 推荐程度 | 推荐 | 常用 |
> ** 陷阱**如果不小心挂载了一个不存在的宿主机路径使用 `-v` 会在宿主机上静默创建一个**空目录**即使你本来想挂载的是一个文件这常常会导致权限错误或应用无法正常读取这也正是为什么 Docker 官方更推荐使用 `--mount` 的原因它会遵循Fail Fast原则直接报错避免弄巧成拙
--- ---
### 8.2.4 使用场景 ### 8.2.4 使用场景

View File

@@ -4,7 +4,7 @@ Docker 1.10.0 以后,内建了一个 DNS 服务器,使得容器可以直接
但是使用 Docker DNS 有个前提条件就是它只能在 **自定义网络** 中使用也就是说如果使用的是默认的 `bridge` 网络是无法使用 DNS 所以我们就需要自定义网络 但是使用 Docker DNS 有个前提条件就是它只能在 **自定义网络** 中使用也就是说如果使用的是默认的 `bridge` 网络是无法使用 DNS 所以我们就需要自定义网络
### 9.2.1 容器的 DNS 机制 ### 9.1.1 容器的 DNS 机制
Docker 容器的 DNS 配置有两种情况 Docker 容器的 DNS 配置有两种情况
@@ -13,7 +13,7 @@ Docker 容器的 DNS 配置有两种情况:
--- ---
### 9.2.2 嵌入式 DNS ### 9.1.2 嵌入式 DNS
这是 Docker 网络最强大的功能之一在自定义网络中容器可以通过 名字 找到彼此而不需要知道对方的 IP (因为 IP 可能会变) 这是 Docker 网络最强大的功能之一在自定义网络中容器可以通过 名字 找到彼此而不需要知道对方的 IP (因为 IP 可能会变)
@@ -38,7 +38,7 @@ Docker 守护进程在 `127.0.0.11` 运行了一个 DNS 服务器。容器内的
--- ---
### 9.2.3 配置 DNS 参数 ### 9.1.3 配置 DNS 参数
如果你需要手动配置容器的 DNS (例如使用内网 DNS 服务器)可以在 `docker run` 中使用以下参数 如果你需要手动配置容器的 DNS (例如使用内网 DNS 服务器)可以在 `docker run` 中使用以下参数
@@ -69,7 +69,7 @@ $ docker run -h myweb nginx
--- ---
### 9.2.4 全局 DNS 配置 ### 9.1.4 全局 DNS 配置
如果希望所有容器都使用特定的 DNS 服务器 (而不是继承宿主机)可以修改 `/etc/docker/daemon.json` 如果希望所有容器都使用特定的 DNS 服务器 (而不是继承宿主机)可以修改 `/etc/docker/daemon.json`
@@ -86,7 +86,7 @@ $ docker run -h myweb nginx
--- ---
### 9.2.5 常见问题 ### 9.1.5 常见问题
以下是使用容器 DNS 时常见的问题及解决方法 以下是使用容器 DNS 时常见的问题及解决方法

View File

@@ -38,6 +38,15 @@ $ docker buildx build --sbom=true -t myimage .
该命令会在构建结果中包含 SPDX CycloneDX 格式的 SBOM 数据 该命令会在构建结果中包含 SPDX CycloneDX 格式的 SBOM 数据
> ** 注意与失败模式**
> 要使 SBOM (或其它 attestation 元数据) 成功附着并可见对底层的存储格式有前置要求默认的 classic image store 不支持 manifest list/index 这种存放 attestation 的结构
>
> 如果只简单运行上述命令你可能会面临**命令成功执行但本地镜像中看不到 SBOM**的体会落差
>
> **正确的解决路径有两条**
> 1. Docker 守护进程中启用 `containerd image store` 特性现代 Docker Desktop 默认推荐
> 2. 或者使用 `docker-container` driver 的构建器并直接**加上 `--push` 参数**将产物推送到远端支持 OCI 的镜像仓库仓库会正确保存这些元数据
### 10.2.2 官方文档 ### 10.2.2 官方文档
* https://docs.docker.com/engine/reference/commandline/buildx/ * https://docs.docker.com/engine/reference/commandline/buildx/

View File

@@ -2,6 +2,10 @@
`Docker Compose` Docker 官方编排 (Orchestration) 项目之一负责快速的部署分布式应用 `Docker Compose` Docker 官方编排 (Orchestration) 项目之一负责快速的部署分布式应用
> **重要提示Compose V1 已停止支持**
>
> 早期基于 Python 编写的 Compose V1命令为 `docker-compose`已于 2023 年中正式停止支持现已全面升级为基于 Go 编写的 Compose V2作为 Docker CLI 的官方插件提供命令为 `docker compose`中间为空格本书强烈推荐且后续章节均以 V2 为核心标准进行讲解
本章将介绍 `Compose` 项目情况以及安装和使用 本章将介绍 `Compose` 项目情况以及安装和使用
* [简介](11.1_introduction.md) * [简介](11.1_introduction.md)

View File

@@ -2,9 +2,13 @@
`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令作为快速创建 `Kubernetes` 集群的最佳实践 `kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令作为快速创建 `Kubernetes` 集群的最佳实践
> **重要说明** Kubernetes 1.24 内置 `dockershim` 已被移除Kubernetes 默认不再直接使用 Docker Engine 作为容器运行时 (CRI)因此**更推荐参考** 同目录下的[使用 kubeadm 部署 Kubernetes (CRI 使用 containerd)](14.1_kubeadm.md) > **强烈提示Docker Kubernetes 环境的时代分界**
> >
> 本文档主要用于历史环境/学习目的如果你确实需要在较新版本中继续使用 Docker Engine通常需要额外部署 `cri-dockerd` 并在 `kubeadm init/join` 中指定 `--cri-socket` > 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` 等参数约束
### 14.2.1 安装 Docker ### 14.2.1 安装 Docker

View File

@@ -58,8 +58,7 @@ build_image:
services: services:
- docker:20.10.16-dind - docker:20.10.16-dind
script: script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD \ - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
$CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA . - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
@@ -81,4 +80,10 @@ deploy_staging:
1. **不可变基础设施**一旦镜像构建完成在各个环境DevStagingProd中都应该使用同一个镜像 tag通常是 commit hash而不是重新构建 1. **不可变基础设施**一旦镜像构建完成在各个环境DevStagingProd中都应该使用同一个镜像 tag通常是 commit hash而不是重新构建
2. **配置分离**使用 ConfigMap Secret 管理环境特定的配置不要打包进镜像 2. **配置分离**使用 ConfigMap Secret 管理环境特定的配置不要打包进镜像
3. **GitOps**考虑引入 ArgoCD将部署配置也作为代码存储在 Git 实现 Git 驱动的部署同步 3. **应对 Docker Hub 限额 (Rate Limits)**
- Docker Hub 对匿名拉取实施了严格的限制 (6小时内约100次)若在 CI/CD 中频繁构建极易触发 `toomanyrequests` 错误
- **最佳策略**
- 在流水线开头始终执行安全的身份认证 (使用 PAT而非密码)
- 将常用的基础镜像缓存到自建的 Harbor/Nexus使用 Pull-Through Cache
- 开启 Docker 构建引擎 (BuildKit) inline registry 缓存功能以降低全量拉取频率
4. **GitOps**考虑引入 ArgoCD将部署配置也作为代码存储在 Git 实现 Git 驱动的部署同步

View File

@@ -2,7 +2,7 @@
[![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![图](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![图](https://img.shields.io/badge/Based-Docker%20Engine%20v29.x-blue.svg)](https://docs.docker.com/engine/release-notes/) [![图](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1] [![](https://img.shields.io/github/stars/yeasy/docker_practice.svg?style=social&label=Stars)](https://github.com/yeasy/docker_practice) [![图](https://img.shields.io/github/release/yeasy/docker_practice/all.svg)](https://github.com/yeasy/docker_practice/releases) [![图](https://img.shields.io/badge/Based-Docker%20Engine%20v29.x-blue.svg)](https://docs.docker.com/engine/release-notes/) [![图](https://img.shields.io/badge/Docker%20%E6%8A%80%E6%9C%AF%E5%85%A5%E9%97%A8%E4%B8%8E%E5%AE%9E%E6%88%98-jd.com-red.svg)][1]
**v1.6.0** **v1.6.1**
[Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker可以让应用的部署、测试和分发都变得前所未有的高效和轻松 [Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker可以让应用的部署、测试和分发都变得前所未有的高效和轻松

View File

@@ -11,3 +11,4 @@
* [**如何调试 Docker**](debug.md)介绍 Docker 调试技巧和工具 * [**如何调试 Docker**](debug.md)介绍 Docker 调试技巧和工具
* [**资源链接**](resources.md)推荐更多 Docker 相关的学习资源 * [**资源链接**](resources.md)推荐更多 Docker 相关的学习资源
* [**术语词表**](glossary.md)统一全书中英文术语缩写与命令写法 * [**术语词表**](glossary.md)统一全书中英文术语缩写与命令写法
* [**示例规范与写作公约**](example_guidelines.md)全书修改与贡献必须遵守的安全格式及内容基线要求

View File

@@ -0,0 +1,41 @@
# 附录八本书示例规范与写作公约
为了保证本书在漫长的技术迭代中保持高质量高安全性以及良好的可读性我们确立了以下项目写作规范所有的修改与贡献都必须遵循这些原则
## 1. 安全与凭据处理
任何示例文档中都**严禁出现将凭据以明文形式直接传递给命令参数**的做法
* **错误示例**`docker login -u myuser -p mysecretpassword` (这会导致密码泄露到历史记录及进程列表中)
* **正确示例交互式**推荐读者直接使用 `docker login` (优先使用官方 Device Code Flow)
* **正确示例自动化**使用标准输入流传递 Token`echo $PAT | docker login -u myuser --password-stdin`
## 2. 失败模式与前置条件说明
许多现代 Docker 功能 ( Buildx, SBOM, Kubernetes CRI 集成) 均需要特定的后端存储或者组件支持在介绍这些进阶命令时必须
* **明确声明前置条件**例如此功能需要开启 containerd image store 需要额外配置 `--push`
* **描述失败现象**明确告诉读者如果你不这么配置命令仍会提示成功但产物将不可见/被丢弃
## 3. 统一使用 "docker compose" 命令
早期 Python 编写的 `docker-compose` (V1) 已停止支持
* **全书统一标准**所有的编排命令必须书写为 `docker compose` (带空格的 V2 CLI 插件版)
* 不得在新的文档和案例中提及或使用旧版格式除非是为了特意说明 V1 V2 的迁移
## 4. 可复现性目标 (以可重建为目标)
本书中的所有实战和案例 (尤其 OS DevOps 章节) 应尽量给出最小可复现实验环境
* 提供明确的基础镜像版本要求 (不要盲目依赖 `latest`)
* 明确宿主机的生命周期窗口例如明确注出 Ubuntu 20.04 的支持结束时间
## 5. Markdown 格式纪律
我们使用自动化的格式检查工具 (`check_project_rules.py`) 进行 Lint以下是必须遵守的排版底线
* **加粗与空格**加粗符号内不得有空格`**错误 黑体**` `**正确黑体**`
* **标题间距**标题后必须跟恰好一个空行
* **中文标点**正文叙述部分的引号必须使用中文弯引号 `“”`不得使用英文直引号 `""`除了代码块或 Mermaid 图表中
* **层级与桥接**禁止跳跃级别使用标题 ( H2 后直接接 H4)且带有子标题的章节在进入第一个子标题前必须要有引导/过渡段落介绍该节内容