Release v1.5.0: Restructure chapters and update for Docker v30.x
65
01_introduction/quickstart.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# 快速上手 (5分钟)
|
||||
|
||||
本节将通过一个简单的 Web 应用例子,带你快速体验 Docker 的核心流程:构建镜像、运行容器。
|
||||
|
||||
## 1. 准备代码
|
||||
|
||||
创建一个名为 `hello-docker` 的文件夹,并在其中创建一个 `index.html` 文件:
|
||||
|
||||
```html
|
||||
<h1>Hello, Docker!</h1>
|
||||
```
|
||||
|
||||
## 2. 编写 Dockerfile
|
||||
|
||||
在同级目录下创建一个名为 `Dockerfile` (无后缀) 的文件:
|
||||
|
||||
```dockerfile
|
||||
FROM nginx:alpine
|
||||
COPY index.html /usr/share/nginx/html/index.html
|
||||
```
|
||||
|
||||
## 3. 构建镜像
|
||||
|
||||
打开终端,进入该目录,执行构建命令:
|
||||
|
||||
```bash
|
||||
$ docker build -t my-hello-world .
|
||||
```
|
||||
|
||||
* `docker build`: 构建命令
|
||||
* `-t my-hello-world`: 给镜像起个名字(标签)
|
||||
* `.`: 指定上下文路径为当前目录
|
||||
|
||||
## 4. 运行容器
|
||||
|
||||
使用刚才构建的镜像启动一个容器:
|
||||
|
||||
```bash
|
||||
$ docker run -d -p 8080:80 my-hello-world
|
||||
```
|
||||
|
||||
* `docker run`: 运行命令
|
||||
* `-d`: 后台运行
|
||||
* `-p 8080:80`: 将宿主机的 8080 端口映射到容器的 80 端口
|
||||
|
||||
## 5. 访问测试
|
||||
|
||||
打开浏览器访问 [http://localhost:8080](http://localhost:8080),你应该能看到 "Hello, Docker!"。
|
||||
|
||||
## 6. 清理
|
||||
|
||||
停止并删除容器:
|
||||
|
||||
```bash
|
||||
# 查看正在运行的容器 ID
|
||||
$ docker ps
|
||||
|
||||
# 停止容器
|
||||
$ docker stop <CONTAINER_ID>
|
||||
|
||||
# 删除容器
|
||||
$ docker rm <CONTAINER_ID>
|
||||
```
|
||||
|
||||
恭喜!你已经完成了第一次 Docker 实战。接下来请阅读 [Docker 核心概念](../02_basic_concept/README.md) 做深入了解。
|
||||
@@ -47,13 +47,13 @@ Docker 做的事情类似:无论你的应用是用 Python、Java、Node.js 还
|
||||
|
||||
传统虚拟机技术是虚拟出一套完整的硬件,在其上运行一个完整的操作系统,再在该系统上运行应用:
|
||||
|
||||

|
||||

|
||||
|
||||
### Docker 容器
|
||||
|
||||
而 Docker 容器内的应用直接运行于宿主的内核,容器内没有自己的内核,也没有进行硬件虚拟:
|
||||
|
||||

|
||||

|
||||
|
||||
### 关键区别
|
||||
|
||||
@@ -75,7 +75,7 @@ Docker 使用 [Go 语言](https://golang.google.cn/) 开发,基于 Linux 内
|
||||
- **[Cgroups](https://zh.wikipedia.org/wiki/Cgroups)**:实现资源限制(CPU、内存、I/O 等)
|
||||
- **[Union FS](https://en.wikipedia.org/wiki/Union_mount)**:实现分层存储(如 OverlayFS)
|
||||
|
||||
> 如果你对这些底层技术感兴趣,可以阅读本书的[底层实现](../underly/README.md)章节。
|
||||
> 如果你对这些底层技术感兴趣,可以阅读本书的[底层实现](../13_implementation/README.md)章节。
|
||||
|
||||
### Docker 架构演进
|
||||
|
||||
@@ -95,7 +95,7 @@ LXC ──→ libcontainer ──→ runC ──→ containerd + runC
|
||||
- **runC**(2015,v1.11):捐献给 OCI 的标准容器运行时
|
||||
- **containerd**:高级容器运行时,管理容器生命周期
|
||||
|
||||

|
||||

|
||||
|
||||
> `runc` 是一个 Linux 命令行工具,用于根据 [OCI 容器运行时规范](https://github.com/opencontainers/runtime-spec) 创建和运行容器。
|
||||
|
||||
@@ -131,10 +131,10 @@ Docker 完美契合 DevOps 的工作流程:
|
||||
push build 运行测试 更新
|
||||
```
|
||||
|
||||
使用 [Dockerfile](../image/build.md) 定义镜像构建过程,使得:
|
||||
使用 [Dockerfile](../04_image/build.md) 定义镜像构建过程,使得:
|
||||
- 构建过程**可重复、可追溯**
|
||||
- 任何人都能从代码重建完全相同的镜像
|
||||
- 配合 [GitHub Actions](../cases/ci/actions/README.md) 等 CI 系统实现自动化
|
||||
- 配合 [GitHub Actions](../14_cases/ci/actions/README.md) 等 CI 系统实现自动化
|
||||
|
||||
### 5. 轻松迁移
|
||||
|
||||
@@ -205,4 +205,4 @@ Docker 的核心价值可以用一句话概括:**让应用的开发、测试
|
||||
|
||||
笔者认为,对于现代软件开发者来说,Docker 已经不是"要不要学"的问题,而是**必备技能**。无论你是前端、后端、运维还是全栈开发者,掌握 Docker 都能让你的工作更高效。
|
||||
|
||||
接下来,让我们学习 Docker 的[基本概念](../basic_concept/README.md)。
|
||||
接下来,让我们学习 Docker 的[基本概念](../02_basic_concept/README.md)。
|
||||
@@ -125,8 +125,8 @@ $ docker rm abc123
|
||||
|
||||
| 方式 | 说明 | 适用场景 |
|
||||
|------|------|---------|
|
||||
| **[数据卷(Volume)](../data_management/volume.md)** | Docker 管理的存储 | 数据库、应用数据 |
|
||||
| **[绑定挂载(Bind Mount)](../data_management/bind-mounts.md)** | 挂载宿主机目录 | 开发时共享代码 |
|
||||
| **[数据卷(Volume)](../07_data_network/data/volume.md)** | Docker 管理的存储 | 数据库、应用数据 |
|
||||
| **[绑定挂载(Bind Mount)](../07_data_network/data/bind-mounts.md)** | 挂载宿主机目录 | 开发时共享代码 |
|
||||
|
||||
```bash
|
||||
# 使用数据卷(推荐)
|
||||
@@ -209,7 +209,7 @@ $ docker run ubuntu
|
||||
$ docker run nginx
|
||||
```
|
||||
|
||||
详细解释请参考[后台运行](../container/daemon.md)章节。
|
||||
详细解释请参考[后台运行](../05_container/daemon.md)章节。
|
||||
|
||||
## 容器的隔离性
|
||||
|
||||
@@ -224,7 +224,7 @@ Docker 容器通过以下 Namespace 实现隔离:
|
||||
| **IPC** | 进程间通信 | 独立的信号量、消息队列 |
|
||||
| **USER** | 用户 | 独立的用户和组 ID |
|
||||
|
||||
> 想深入了解?请阅读[底层实现 - 命名空间](../underly/namespace.md)。
|
||||
> 想深入了解?请阅读[底层实现 - 命名空间](../13_implementation/namespace.md)。
|
||||
|
||||
## 本章小结
|
||||
|
||||
@@ -240,7 +240,7 @@ Docker 容器通过以下 Namespace 实现隔离:
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [启动容器](../container/run.md):详细的容器启动选项
|
||||
- [后台运行](../container/daemon.md):理解容器为什么会"立即退出"
|
||||
- [进入容器](../container/attach_exec.md):如何操作运行中的容器
|
||||
- [数据管理](../data_management/README.md):Volume 和数据持久化详解
|
||||
- [启动容器](../05_container/run.md):详细的容器启动选项
|
||||
- [后台运行](../05_container/daemon.md):理解容器为什么会"立即退出"
|
||||
- [进入容器](../05_container/attach_exec.md):如何操作运行中的容器
|
||||
- [数据管理](../07_data_network/README.md):Volume 和数据持久化详解
|
||||
@@ -216,7 +216,7 @@ Docker 镜像可以通过以下方式获取:
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [获取镜像](../image/pull.md):从 Registry 下载镜像
|
||||
- [使用 Dockerfile 定制镜像](../image/build.md):创建自己的镜像
|
||||
- [Dockerfile 最佳实践](../appendix/best_practices.md):构建高质量镜像的技巧
|
||||
- [底层实现 - 联合文件系统](../underly/ufs.md):深入理解分层存储的技术原理
|
||||
- [获取镜像](../04_image/pull.md):从 Registry 下载镜像
|
||||
- [使用 Dockerfile 定制镜像](../04_image/build.md):创建自己的镜像
|
||||
- [Dockerfile 最佳实践](../15_appendix/best_practices.md):构建高质量镜像的技巧
|
||||
- [底层实现 - 联合文件系统](../13_implementation/ufs.md):深入理解分层存储的技术原理
|
||||
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 660 KiB After Width: | Height: | Size: 660 KiB |
|
Before Width: | Height: | Size: 291 KiB After Width: | Height: | Size: 291 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -22,21 +22,21 @@ $ brew install --cask docker
|
||||
|
||||
如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可(其间需要输入用户密码)。
|
||||
|
||||

|
||||

|
||||
|
||||
## 运行
|
||||
|
||||
从应用中找到 Docker 图标并点击运行。
|
||||
|
||||

|
||||

|
||||
|
||||
运行之后,会在右上角菜单栏看到多了一个鲸鱼图标,这个图标表明了 Docker 的运行状态。
|
||||
|
||||

|
||||

|
||||
|
||||
每次点击鲸鱼图标会弹出操作菜单。
|
||||
|
||||

|
||||

|
||||
|
||||
之后,你可以在终端通过命令检查安装后的 Docker 版本。
|
||||
|
||||
@@ -53,7 +53,7 @@ $ docker run -d -p 80:80 --name webserver nginx
|
||||
|
||||
服务运行后,可以访问 [http://localhost](http://localhost),如果看到了 "Welcome to nginx!",就说明 Docker Desktop for Mac 安装成功了。
|
||||
|
||||

|
||||

|
||||
|
||||
要停止 Nginx 服务器并删除执行下面的命令:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
括号内的字母表示该操作需要在哪些服务器上执行
|
||||
|
||||

|
||||

|
||||
|
||||
## CentOS/Rocky/AlmaLinux 离线安装Docker
|
||||
|
||||
@@ -26,11 +26,11 @@ $ winget install Docker.DockerDesktop
|
||||
|
||||
在 Windows 搜索栏输入 **Docker** 点击 **Docker Desktop** 开始运行。
|
||||
|
||||

|
||||

|
||||
|
||||
Docker 启动之后会在 Windows 任务栏出现鲸鱼图标。
|
||||
|
||||

|
||||

|
||||
|
||||
等待片刻,当鲸鱼图标静止时,说明 Docker 启动成功,之后你可以打开 PowerShell 使用 Docker。
|
||||
|
||||
|
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
@@ -1,6 +1,6 @@
|
||||
# 利用 commit 理解镜像构成
|
||||
|
||||
> 注意:如果您是初学者,您可以暂时跳过后面的内容,直接学习 [容器](../container/) 一节。
|
||||
> 注意:如果您是初学者,您可以暂时跳过后面的内容,直接学习 [容器](../05_container/) 一节。
|
||||
|
||||
注意: `docker commit` 命令除了学习之外,还有一些特殊的应用场合,比如被入侵后保存现场等。但是,不要使用 `docker commit` 定制镜像,定制镜像应该使用 `Dockerfile` 来完成。如果你想要定制镜像请查看下一小节。
|
||||
|
||||
@@ -20,7 +20,7 @@ $ docker run --name webserver -d -p 80:80 nginx
|
||||
|
||||
直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。
|
||||
|
||||

|
||||

|
||||
|
||||
现在,假设我们非常不喜欢这个欢迎页面,我们希望改成欢迎 Docker 的文字,我们可以使用 `docker exec` 命令进入容器,修改其内容。
|
||||
|
||||
@@ -37,7 +37,7 @@ exit
|
||||
|
||||
现在我们再刷新浏览器的话,会发现内容被改变了。
|
||||
|
||||

|
||||

|
||||
|
||||
我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过 `docker diff` 命令看到具体的改动。
|
||||
|
||||
0
image/demo/multistage-builds/build.sh → 04_image/demo/multistage-builds/build.sh
Executable file → Normal file
@@ -218,4 +218,4 @@ RUN tar -xzf /tmp/app.tar.gz -C /app && \
|
||||
|
||||
- [COPY 复制文件](copy.md):基本复制操作
|
||||
- [多阶段构建](../multistage-builds.md):减少镜像体积
|
||||
- [最佳实践](../../appendix/best_practices.md):Dockerfile 编写指南
|
||||
- [最佳实践](../../15_appendix/best_practices.md):Dockerfile 编写指南
|
||||
@@ -234,5 +234,5 @@ FROM ${BASE_IMAGE}
|
||||
## 延伸阅读
|
||||
|
||||
- [ENV 设置环境变量](env.md):运行时环境变量
|
||||
- [FROM 指令](../../image/build.md):基础镜像指定
|
||||
- [FROM 指令](../../04_image/build.md):基础镜像指定
|
||||
- [多阶段构建](../multistage-builds.md):复杂构建场景
|
||||
@@ -264,5 +264,5 @@ CMD ["python", "app.py"]
|
||||
## 延伸阅读
|
||||
|
||||
- [ENTRYPOINT 入口点](entrypoint.md):固定的启动命令
|
||||
- [后台运行](../../container/daemon.md):容器前台/后台概念
|
||||
- [最佳实践](../../appendix/best_practices.md):Dockerfile 编写指南
|
||||
- [后台运行](../../05_container/daemon.md):容器前台/后台概念
|
||||
- [最佳实践](../../15_appendix/best_practices.md):Dockerfile 编写指南
|
||||
@@ -258,4 +258,4 @@ COPY . .
|
||||
- [ADD 指令](add.md):复制和解压
|
||||
- [WORKDIR 指令](workdir.md):设置工作目录
|
||||
- [多阶段构建](../multistage-builds.md):优化镜像大小
|
||||
- [最佳实践](../../appendix/best_practices.md):Dockerfile 编写指南
|
||||
- [最佳实践](../../15_appendix/best_practices.md):Dockerfile 编写指南
|
||||
@@ -302,5 +302,5 @@ wait $PID
|
||||
## 延伸阅读
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):默认命令
|
||||
- [最佳实践](../../appendix/best_practices.md):启动命令设计
|
||||
- [后台运行](../../container/daemon.md):前台/后台概念
|
||||
- [最佳实践](../../15_appendix/best_practices.md):启动命令设计
|
||||
- [后台运行](../../05_container/daemon.md):前台/后台概念
|
||||
@@ -245,4 +245,4 @@ ENV VAR3=value3
|
||||
|
||||
- [ARG 构建参数](arg.md):构建时变量
|
||||
- [Compose 环境变量](../../compose/compose_file.md):Compose 中的环境变量
|
||||
- [最佳实践](../../appendix/best_practices.md):Dockerfile 编写指南
|
||||
- [最佳实践](../../15_appendix/best_practices.md):Dockerfile 编写指南
|
||||
@@ -203,4 +203,4 @@ HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):启动主进程
|
||||
- [Compose 模板文件](../../compose/compose_file.md):Compose 中的健康检查
|
||||
- [Docker 调试](../../appendix/debug.md):容器排障
|
||||
- [Docker 调试](../../15_appendix/debug.md):容器排障
|
||||
@@ -151,4 +151,4 @@ $ docker rmi $(docker images -q --filter "label=stage=builder")
|
||||
## 延伸阅读
|
||||
|
||||
- [OCI 标签规范](https://github.com/opencontainers/image-spec/blob/main/annotations.md)
|
||||
- [Dockerfile 最佳实践](../../appendix/best_practices.md)
|
||||
- [Dockerfile 最佳实践](../../15_appendix/best_practices.md)
|
||||
@@ -148,4 +148,4 @@ python:3.12-onbuild
|
||||
## 延伸阅读
|
||||
|
||||
- [COPY 指令](copy.md):文件复制
|
||||
- [Dockerfile 最佳实践](../../appendix/best_practices.md):基础镜像设计
|
||||
- [Dockerfile 最佳实践](../../15_appendix/best_practices.md):基础镜像设计
|
||||
@@ -178,4 +178,4 @@ RUN --mount=type=secret,id=mysecret \
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):容器启动时的命令
|
||||
- [WORKDIR 指定工作目录](workdir.md):改变目录
|
||||
- [Dockerfile 最佳实践](../../appendix/best_practices.md)
|
||||
- [Dockerfile 最佳实践](../../15_appendix/best_practices.md)
|
||||
@@ -137,5 +137,5 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [RUN 指令](../../image/build.md):执行命令
|
||||
- [Dockerfile 最佳实践](../../appendix/best_practices.md):错误处理与调试
|
||||
- [RUN 指令](../../04_image/build.md):执行命令
|
||||
- [Dockerfile 最佳实践](../../15_appendix/best_practices.md):错误处理与调试
|
||||
@@ -270,4 +270,4 @@ RUN mkdir -p /app/data && chown appuser:appuser /app/data
|
||||
|
||||
- [安全](../../security/README.md):容器安全实践
|
||||
- [ENTRYPOINT](entrypoint.md):入口脚本中的用户切换
|
||||
- [最佳实践](../../appendix/best_practices.md):Dockerfile 安全
|
||||
- [最佳实践](../../15_appendix/best_practices.md):Dockerfile 安全
|
||||
@@ -242,6 +242,6 @@ VOLUME /var/lib/mysql
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [数据卷](../../data_management/volume.md):卷的管理和使用
|
||||
- [挂载主机目录](../../data_management/bind-mounts.md):Bind Mount
|
||||
- [数据卷](../../07_data_network/data/volume.md):卷的管理和使用
|
||||
- [挂载主机目录](../../07_data_network/data/bind-mounts.md):Bind Mount
|
||||
- [Compose 数据管理](../../compose/compose_file.md):Compose 中的卷配置
|
||||
@@ -192,5 +192,5 @@ $ docker run -w /tmp myimage pwd
|
||||
## 延伸阅读
|
||||
|
||||
- [COPY 复制文件](copy.md):文件复制
|
||||
- [RUN 执行命令](../../image/build.md):执行构建命令
|
||||
- [最佳实践](../../appendix/best_practices.md):Dockerfile 编写指南
|
||||
- [RUN 执行命令](../../04_image/build.md):执行构建命令
|
||||
- [最佳实践](../../15_appendix/best_practices.md):Dockerfile 编写指南
|
||||
@@ -255,4 +255,4 @@ $ docker images --format "{{.Repository}}:{{.Tag}}" > images.txt
|
||||
|
||||
- [获取镜像](pull.md):从 Registry 拉取镜像
|
||||
- [删除镜像](rm.md):清理本地镜像
|
||||
- [镜像](../basic_concept/image.md):理解镜像概念
|
||||
- [镜像](../02_basic_concept/image.md):理解镜像概念
|
||||
@@ -251,5 +251,5 @@ Build Cache 0 0 0B 0B
|
||||
## 延伸阅读
|
||||
|
||||
- [列出镜像](list.md):查看和过滤镜像
|
||||
- [删除容器](../container/rm.md):清理容器
|
||||
- [数据卷](../data_management/volume.md):清理数据卷
|
||||
- [删除容器](../05_container/rm.md):清理容器
|
||||
- [数据卷](../07_data_network/data/volume.md):清理数据卷
|
||||
@@ -213,6 +213,6 @@ $ docker attach mycontainer
|
||||
## 延伸阅读
|
||||
|
||||
- [进入容器](attach_exec.md):如何进入正在运行的容器执行命令
|
||||
- [容器日志](../appendix/best_practices.md):生产环境的日志管理最佳实践
|
||||
- [HEALTHCHECK 健康检查](../image/dockerfile/healthcheck.md):自动检测容器内服务是否正常
|
||||
- [容器日志](../15_appendix/best_practices.md):生产环境的日志管理最佳实践
|
||||
- [HEALTHCHECK 健康检查](../04_image/dockerfile/healthcheck.md):自动检测容器内服务是否正常
|
||||
- [Docker Compose](../compose/README.md):管理多个后台容器的更好方式
|
||||
@@ -234,5 +234,5 @@ $ docker system prune -a --volumes
|
||||
## 延伸阅读
|
||||
|
||||
- [终止容器](stop.md):优雅停止容器
|
||||
- [删除镜像](../image/rm.md):清理镜像
|
||||
- [数据卷](../data_management/volume.md):数据卷管理
|
||||
- [删除镜像](../04_image/rm.md):清理镜像
|
||||
- [数据卷](../07_data_network/data/volume.md):数据卷管理
|
||||
@@ -210,7 +210,7 @@ $ docker run -d -p 80:80 nginx
|
||||
$ docker run -v mydata:/app/data myapp
|
||||
```
|
||||
|
||||
详见[数据管理](../data_management/README.md)。
|
||||
详见[数据管理](../07_data_network/README.md)。
|
||||
|
||||
## 本章小结
|
||||
|
||||
@@ -226,4 +226,4 @@ $ docker run -v mydata:/app/data myapp
|
||||
- [后台运行](daemon.md):理解 `-d` 参数和容器生命周期
|
||||
- [进入容器](attach_exec.md):操作运行中的容器
|
||||
- [网络配置](../network/README.md):理解端口映射的原理
|
||||
- [数据管理](../data_management/README.md):数据持久化方案
|
||||
- [数据管理](../07_data_network/README.md):数据持久化方案
|
||||
6
07_data_network/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# 数据与网络管理
|
||||
|
||||
本章将介绍 Docker 中的数据管理与网络配置。
|
||||
|
||||
* [数据管理](data/README.md)
|
||||
* [网络配置](network/README.md)
|
||||
@@ -1,6 +1,6 @@
|
||||
# 数据管理
|
||||
|
||||

|
||||

|
||||
|
||||
这一章介绍如何在 Docker 内部以及容器之间管理数据,在容器中管理数据主要有两种方式:
|
||||
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
@@ -4,13 +4,11 @@
|
||||
|
||||
容器的存储层有一个关键问题:**容器删除后,数据就没了**。
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 容器存储层问题 │
|
||||
│ │
|
||||
│ 容器运行 ─────► 写入数据 ─────► 容器删除 ─────► 数据丢失! │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Run[容器运行] --> Write[写入数据]
|
||||
Write --> Delete[容器删除]
|
||||
Delete -->|数据都在容器 writable 层| Lost[DATA LOST! ❌]
|
||||
```
|
||||
|
||||
数据卷(Volume)解决了这个问题,它的生命周期独立于容器。
|
||||
@@ -31,24 +29,34 @@
|
||||
|
||||
## 数据卷 vs 容器存储层
|
||||
|
||||
#### 容器存储层(不推荐存储重要数据)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Container [容器]
|
||||
Writable[容器存储层<br>Writable]
|
||||
Image[镜像层<br>ReadOnly]
|
||||
Writable --- Image
|
||||
end
|
||||
|
||||
Lifecycle[生命周期 = 容器生命周期] -.-> Container
|
||||
Delete[容器删除] -->|导致| DataLost[数据丢失 ❌]
|
||||
```
|
||||
容器存储层(不推荐存储重要数据):
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 容器存储层(可读写) │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 镜像层(只读) │
|
||||
└─────────────────────────────────────────┘
|
||||
生命周期 = 容器生命周期
|
||||
容器删除 → 数据丢失
|
||||
|
||||
数据卷(推荐):
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 容器 │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ /app/data ──────────────────│────┼──► 数据卷 my-data
|
||||
│ └─────────────────────────────────┘ │ (独立于容器)
|
||||
└─────────────────────────────────────────┘
|
||||
容器删除 → 数据卷保留
|
||||
|
||||
#### 数据卷(推荐)
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Container [容器]
|
||||
AppDir["/app/data"]
|
||||
end
|
||||
|
||||
subgraph Volume [数据卷 my-data]
|
||||
Data[持久化数据]
|
||||
end
|
||||
|
||||
AppDir == 挂载 ==> Volume
|
||||
Delete[容器删除] -.->|不会影响| Volume
|
||||
```
|
||||
|
||||
---
|
||||
@@ -351,4 +359,4 @@ $ docker volume inspect my-vol
|
||||
|
||||
- [绑定挂载](bind-mounts.md):挂载宿主机目录
|
||||
- [tmpfs 挂载](tmpfs.md):内存中的临时存储
|
||||
- [存储驱动](../underly/ufs.md):Docker 存储的底层原理
|
||||
- [存储驱动](../13_implementation/ufs.md):Docker 存储的底层原理
|
||||
@@ -13,29 +13,27 @@ Docker 在安装时会自动配置网络基础设施,大多数情况下开箱
|
||||
|
||||
Docker 启动时自动创建以下网络组件:
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────┐
|
||||
│ 宿主机 │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ docker0 网桥 │ │
|
||||
│ │ (172.17.0.1/16) │ │
|
||||
│ │ ┌────────────┬────────────┬────────────┐ │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ └────┼────────────┼────────────┼────────────┼──────────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │
|
||||
│ │ veth │ │ veth │ │ veth │ │ veth │ │
|
||||
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │
|
||||
│ │ 容器 A │ │ 容器 B │ │ 容器 C │ │ 容器 D │ │
|
||||
│ │.17.0.2 │ │.17.0.3 │ │.17.0.4 │ │.17.0.5 │ │
|
||||
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
|
||||
│ │
|
||||
│ eth0 ◄──────────────────────────────────────────► 外部网络 │
|
||||
│ (192.168.1.100) │
|
||||
└────────────────────────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Host [宿主机]
|
||||
eth0[物理网卡 eth0<br>192.168.1.100]
|
||||
docker0[docker0 网桥<br>172.17.0.1]
|
||||
|
||||
subgraph Containers
|
||||
subgraph ContainerA [容器 A]
|
||||
eth0_A[eth0<br>172.17.0.2]
|
||||
end
|
||||
subgraph ContainerB [容器 B]
|
||||
eth0_B[eth0<br>172.17.0.3]
|
||||
end
|
||||
end
|
||||
|
||||
eth0 <--> docker0
|
||||
docker0 <--> eth0_A
|
||||
docker0 <--> eth0_B
|
||||
end
|
||||
|
||||
Internet((互联网)) <--> eth0
|
||||
```
|
||||
|
||||
### 核心组件
|
||||
@@ -145,5 +145,5 @@ iptables -t nat -A DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [EXPOSE 指令](../image/dockerfile/expose.md):在 Dockerfile 中声明端口
|
||||
- [EXPOSE 指令](../04_image/dockerfile/expose.md):在 Dockerfile 中声明端口
|
||||
- [网络模式](README.md):Host 模式不需要端口映射
|
||||