@@ -16,12 +16,12 @@ icon: simple/docker
1616
1717Docker 能够利用 Linux 内核的容器特性,隔离出一个轻便的环境来运行程序。这有什么意义呢?试想以下这些情况:
1818
19- - 你运行的 Linux 发行版很老,而你需要运行一个更新版本的 Linux 发行版,或者完全不同的 Linux 发行版设计的程序。
19+ - 你运行的 Linux 发行版很老,而你需要运行一个更新版本的 Linux 发行版,或者完全不同的 Linux 发行版设计的程序。基于 Docker 的实现方式,与虚拟机(VM)不同,它们都共用同一个 Linux 内核(虚拟机是完全的虚拟化,包括内核和用户空间)。
2020- 你和朋友在设计一个大型的程序,而因为你们配置的环境不同,有时候在某个人的机器上正常运行的程序,在另一台机器上没法正常运行。
2121- 你希望在多台服务器上部署一个项目,但是项目需要非常复杂的配置,一个一个配置服务器的成本非常大。
2222- …………
2323
24- Docker 就可以帮助解决这些问题。它可以快速配置不同的环境(比如说,通过 Docker,你可以在 Ubuntu 上使用 CentOS 的环境 ),部署应用。
24+ Docker 就可以帮助解决这些问题。它可以快速配置不同的环境(比如说,通过 Docker,你可以在 Ubuntu 发行版上使用 CentOS 发行版的环境 ),部署应用。
2525
2626## 安装 Docker {#install-docker}
2727
@@ -70,7 +70,7 @@ Docker 可以在 Windows, Linux 和 macOS 上安装。下面我们讨论内容
7070$ sudo adduser 用户名 docker
7171```
7272
73- 将需要使用 Docker 的用户[ 加入] ( ../Ch05/index.md#adduser ) ` docker ` 用户组。** 注意:` docker ` 用户组中的用户拥有与 root 等效的权限。**
73+ 将需要使用 Docker 的用户[ 加入] ( ../Ch05/index.md#adduser ) ` docker ` 用户组,以便使用命令行方式操作 Docker 。** 注意:` docker ` 用户组中的用户拥有与 root 等效的权限。**
7474
7575### 配置 Registry Mirror(可选,推荐) {#setup-registry-mirror}
7676
@@ -115,13 +115,13 @@ For more examples and ideas, visit:
115115
116116### 在 Ubuntu 容器中使用 shell {#use-ubuntu-bash}
117117
118- - ` docker run -it --rm --name ubuntu-container ubuntu:20.04 `
118+ - ` docker run -it --rm --name ubuntu-container ubuntu:latest `
119119
120120这里,` --rm ` 代表容器停止运行(退出)之后,会被立刻删除;` --name ` 参数代表给容器命名,如果没有加这个参数,那么 docker 会给容器随机起一个格式类似于 gracious_brahmagupta 的名字。
121121
122122` -it ` 是为了获得可交互的 Shell 所必须的。` -i ` 会将容器的 init(主进程,这里是 ` /bin/bash ` )的标准输入与 ` docker ` 这个程序的标准输入相连接;而 ` -t ` 会告知主进程输入为终端(TTY)设备。
123123
124- 在执行以上命令之后,你会获得一个 Ubuntu 20.04 的容器环境,退出 Shell 之后容器就会被销毁。
124+ 在执行以上命令之后,你会获得一个 Ubuntu(版本为 ` latest ` 即最新的 LTS;如果需要指定版本,可以使用类似 ` 20.04 ` 的版本号替换 ` latest ` ,推荐在生产环境中这么做,因为 ` latest ` 指定的最新版本可能随时间变化) 的容器环境,退出 Shell 之后容器就会被销毁。
125125
126126如果没有加上 ` --rm ` ,退出后可以使用 ` docker ps -a ` 查看系统中所有的容器。
127127
@@ -191,6 +191,27 @@ $ sudo docker rm ubuntu-container
191191
192192## 构建自己的 Docker 镜像 {#build-docker-image}
193193
194+ ### Docker 的关键概念
195+
196+ 在继续之前,我们来梳理一下 Docker 中的几个关键概念:** 容器(container)** 、** 镜像(image)** 、** 镜像仓库(registry)** 。
197+
198+ - ** 镜像仓库** 是存储镜像的地方
199+ - ** 镜像** 是 Docker 容器内文件系统的一份快照
200+ - ** Dockerfile** 包含生成镜像的指令序列,可以理解为构建镜像的脚本
201+ - ** 容器** 是一个(隔离)的运行环境
202+
203+ 它们之间的关系可以用下图表示,其中括号中的命令是查看相应对象列表的命令。
204+
205+ ``` mermaid
206+ flowchart TD
207+ Registry -->|pull| Image["Image (images)"]
208+ Image -->|run| Container["Container (ps)"]
209+ Container -->|commit| Image
210+ Image -->|push| Registry["Registry (search)"]
211+
212+ Dockerfile -->|build| Image
213+ ```
214+
194215### 手工构建镜像 {#build-manually}
195216
196217` docker commit ` 命令可以从当前运行的容器新建镜像。以下是一个简单的例子:
@@ -246,7 +267,7 @@ CMD ["fish"]
246267sudo docker build -t riscv-cross:example .
247268```
248269
249- ` -t riscv-cross:example ` 代表为这个镜像打上 ` riscv-cross:example ` 的标签。构建完成后,使用 ` docker run ` 执行即可:
270+ ` -t riscv-cross:example ` 代表为这个镜像打上 ` riscv-cross:example ` 的标签, ` . ` 表示从当前目录下寻找 Dockerfile 并以当前目录作为构建过程的“工作路径” 。构建完成后,使用 ` docker run ` 执行即可:
250271
251272``` console
252273$ sudo docker run -v ${PWD} /workspace:/workspace -it riscv-cross:example
@@ -303,7 +324,7 @@ Docker 在根据 Dockerfile 构建时,会从上到下执行这些指令,每
303324 RUN yum clean all
304325 ```
305326
306- 当然,这不等于说必须要把所有命令都写在一条 `RUN` 里面。对于执行时间很长的命令,可以考虑放在 Dockerfile 的开头,并且使用单独的 `RUN` 运行,因为 Docker 在构建镜像时,可以重复使用之前构建好的层。这么做可以节约构建与调试 Dockerfile 的时间。
327+ 当然,这不等于说必须要把所有命令都写在一条 `RUN` 里面。对于执行时间很长的命令,可以考虑放在 Dockerfile 的开头,并且使用单独的 `RUN` 运行,因为 Docker 在构建镜像时,** 可以重复使用之前构建好的层** 。这么做可以节约构建与调试 Dockerfile 的时间。
307328
308329#### 在生产环境中运行使用 Flask 编写的简单网站 {#flask-production-example}
309330
0 commit comments