mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-11 12:21:17 +00:00
Compare commits
3 Commits
v1.6.0
...
a9c4189c0c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9c4189c0c | ||
|
|
56deeaee0f | ||
|
|
0ff67cc893 |
@@ -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),你应该能看到 “Hello,Docker!”。
|
打开浏览器访问 [http://localhost:8080](http://localhost:8080),你应该能看到 “Hello, Docker!”。
|
||||||
|
|
||||||
### 1.1.6 清理
|
### 1.1.6 清理
|
||||||
|
|
||||||
|
|||||||
@@ -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 的起源、发展历程以及其背后的核心技术 (Cgroups,Namespaces,UnionFS)。
|
* 介绍 Docker 的起源、发展历程以及其背后的核心技术 (Cgroups,Namespaces,UnionFS,以及 `containerd` 引擎的演进)。
|
||||||
* 了解 Docker 是如何改变软件交付方式的。
|
* 了解 Docker 是如何改变软件交付方式的。
|
||||||
|
|
||||||
* [为什么要用 Docker](1.3_why.md)
|
* [为什么要用 Docker](1.3_why.md)
|
||||||
|
|||||||
@@ -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 配置
|
||||||
|
|||||||
@@ -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` 组:
|
||||||
|
|
||||||
|
|||||||
@@ -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` 组:
|
||||||
|
|
||||||
|
|||||||
@@ -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` 组:
|
||||||
|
|
||||||
|
|||||||
@@ -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` 组:
|
||||||
|
|
||||||
|
|||||||
@@ -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` 组:
|
||||||
|
|
||||||
|
|||||||
@@ -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. 关注镜像漏洞
|
||||||
|
|||||||
@@ -138,9 +138,11 @@ $ docker run -d \
|
|||||||
| 特性 | --mount | -v |
|
| 特性 | --mount | -v |
|
||||||
|------|---------|-----|
|
|------|---------|-----|
|
||||||
| 语法 | 键值对,更清晰 | 冒号分隔,更简洁 |
|
| 语法 | 键值对,更清晰 | 冒号分隔,更简洁 |
|
||||||
| 自动创建卷 | source 不存在会报错 | 自动创建 |
|
| 自动创建卷 | source 不存在会自动创建 | 自动创建 |
|
||||||
| 推荐程度 | ✅ 推荐 (更明确)| 常用 (更简洁)|
|
| 推荐程度 | ✅ 推荐 (更明确)| 常用 (更简洁)|
|
||||||
|
|
||||||
|
> **提示**:很多人误以为 `--mount` 遇到目标不存在时总是报错。实际上,那仅适用于**绑定挂载 (Bind Mount)**。对于**数据卷 (Volume)**,只要 `source` 指定的卷名称不存在,Docker 都会默默将其创建出来。
|
||||||
|
|
||||||
#### 只读挂载
|
#### 只读挂载
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -74,9 +74,11 @@ $ docker run -d \
|
|||||||
| 特性 | --mount | -v |
|
| 特性 | --mount | -v |
|
||||||
|------|---------|-----|
|
|------|---------|-----|
|
||||||
| 语法 | 键值对,更清晰 | 冒号分隔,更简洁 |
|
| 语法 | 键值对,更清晰 | 冒号分隔,更简洁 |
|
||||||
| 路径不存在时 | 报错 | 自动创建目录 |
|
| 路径不存在时 | 直接报错 (Fail Fast) | 静默自动创建**目录** |
|
||||||
| 推荐程度 | ✅ 推荐 | 常用 |
|
| 推荐程度 | ✅ 推荐 | 常用 |
|
||||||
|
|
||||||
|
> **⚠️ 陷阱**:如果不小心挂载了一个不存在的宿主机路径,使用 `-v` 会在宿主机上静默创建一个**空目录**(即使你本来想挂载的是一个文件),这常常会导致权限错误或应用无法正常读取。这也正是为什么 Docker 官方更推荐使用 `--mount` 的原因:它会遵循“Fail Fast”原则直接报错,避免弄巧成拙。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 8.2.4 使用场景
|
### 8.2.4 使用场景
|
||||||
|
|||||||
@@ -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 时常见的问题及解决方法:
|
||||||
|
|
||||||
|
|||||||
@@ -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/
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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. **不可变基础设施**:一旦镜像构建完成,在各个环境(Dev、Staging、Prod)中都应该使用同一个镜像 tag(通常是 commit hash),而不是重新构建。
|
1. **不可变基础设施**:一旦镜像构建完成,在各个环境(Dev、Staging、Prod)中都应该使用同一个镜像 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 驱动的部署同步。
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://github.com/yeasy/docker_practice) [](https://github.com/yeasy/docker_practice/releases) [](https://docs.docker.com/engine/release-notes/) [][1]
|
[](https://github.com/yeasy/docker_practice) [](https://github.com/yeasy/docker_practice/releases) [](https://docs.docker.com/engine/release-notes/) [][1]
|
||||||
|
|
||||||
**v1.6.0**
|
**v1.6.1**
|
||||||
|
|
||||||
[Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松!
|
[Docker](https://www.docker.com) 是个划时代的开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松!
|
||||||
|
|
||||||
|
|||||||
@@ -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):全书修改与贡献必须遵守的安全、格式及内容基线要求。
|
||||||
|
|||||||
41
appendix/example_guidelines.md
Normal file
41
appendix/example_guidelines.md
Normal 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);且带有子标题的章节,在进入第一个子标题前,必须要有引导/过渡段落介绍该节内容。
|
||||||
Reference in New Issue
Block a user