Update Docker_基础.md

This commit is contained in:
heibaiying 2019-12-30 17:19:46 +08:00 committed by GitHub
parent cc5869cbf5
commit 8b909e083c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -23,7 +23,7 @@ Docker 使用 Go 语言进行开发,基于 Linux 内核的 cgroupnamespace
## 二、Docker 架构与核心概念 ## 二、Docker 架构与核心概念
Docker 使用 client-server 架构, Docker 客户端将命令发送给 Docker 守护进程,后者负责构建,运行和分发 Docker 容器。 Docker客户端和守护程序使用 REST API通过 UNIX 套接字或网络接口进行通信。核心概念如下: Docker 使用 client-server 架构, Docker 客户端将命令发送给 Docker 守护进程,后者负责构建,运行和分发 Docker 容器。 Docker 客户端和守护程序使用 REST API通过 UNIX 套接字或网络接口进行通信。核心概念如下:
<div align="center"> <img src="../pictures/docker架构.png"/> </div> <div align="center"> <img src="../pictures/docker架构.png"/> </div>
@ -31,19 +31,19 @@ Docker 使用 client-server 架构, Docker 客户端将命令发送给 Docker
Docker 镜像Image是一个特殊的文件系统包含了程序运行时候所需要的资源和环境。镜像不包含任何动态数据其内容在构建之后也不会被改变。 Docker 镜像Image是一个特殊的文件系统包含了程序运行时候所需要的资源和环境。镜像不包含任何动态数据其内容在构建之后也不会被改变。
因为镜像包含操作系统完整的 `root` 文件系统,其体积往往是庞大的,因此在 Docker 设计时,充分利用 Union FS (联合文件系统)的技术,将其设计为分层存储的架构所以一个镜像实际上是由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。 因为镜像包含操作系统完整的 `root` 文件系统,其体积往往是庞大的,因此在 Docker 设计时,充分利用 Union FS (联合文件系统)的技术,将其设计为分层存储的架构所以一个镜像实际上是由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。 分层存储的特征使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
### 2.2 容器 ### 2.2 容器
镜像Image和容器Container的关系就像是面向对象程序设计中的 `类``实例` 一样,镜像是静态的定义,容器是镜像运行时的实体容器可以被创建、启动、停止、删除、暂停等。 镜像Image和容器Container的关系就像是面向对象程序设计中的 `类``实例` 一样,镜像是静态的定义,容器是镜像运行时的实体容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 `root` 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样,这种特性使得容器封装的应用比直接在宿主运行更加安全。 容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行在属于自己的、独立的命名空间中。因此容器可以拥有自己的 `root` 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样,这种特性使得容器封装的应用比直接在宿主运行更加安全。
前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层称为 **容器存储层**。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。 前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层称为 **容器存储层**。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照 Docker 最佳实践的要求容器不应该向其存储层内写入任何数据容器存储层要保持无状态化。所有的文件写入操作都应该使用数据卷Volume、或者绑定宿主目录在这些位置的读写会跳过容器存储层直接对宿主或网络存储发生读写其性能和稳定性更高。数据卷的生存周期独立于容器容器消亡数据卷不会消亡因此使用数据卷后容器删除或者重新运行之后数据不会丢失。 按照 Docker 最佳实践的要求容器不应该向其存储层内写入任何数据容器存储层要保持无状态化。所有的文件写入操作都应该使用数据卷Volume、或者绑定宿主目录在这些位置的读写会跳过容器存储层直接对宿主或网络存储发生读写其性能和稳定性更高。数据卷的生存周期独立于容器容器消亡数据卷不会消亡因此使用数据卷后容器删除或者重新运行之后数据不会丢失。
### 2.3 仓库 ### 2.3 仓库
@ -59,7 +59,7 @@ Docker 客户端docker是用户与 Docker 交互的主要方式。当你
## 三、Docker 常用命令 ## 三、Docker 常用命令
Docker 提供了大量命令用于管理镜像、容器和服务,命令的统一使用格式为:` docker [OPTIONS] COMMAND` ,其中 OPTIONS 代表可选参数。需要注意的是 Docker 命令的执行一般都需要获取 root 权限,这是因为 Docker 的命令行工具 docker 与 docker daemon 是同一个二进制文件docker daemon 负责接收并执行来自 docker 的命令,它的运行需要 root 权限。所有常用命令及其使用场景如下: Docker 提供了大量命令用于管理镜像、容器和服务,命令的统一使用格式为:`docker [OPTIONS] COMMAND` ,其中 OPTIONS 代表可选参数。需要注意的是 Docker 命令的执行一般都需要获取 root 权限,这是因为 Docker 的命令行工具 docker 与 docker daemon 是同一个二进制文件docker daemon 负责接收并执行来自 docker 的命令,它的运行需要 root 权限。所有常用命令及其使用场景如下:
<div align="center"> <img src="../pictures/docker常用命令.jpg"/> </div> <div align="center"> <img src="../pictures/docker常用命令.jpg"/> </div>
@ -73,7 +73,7 @@ Docker 提供了大量命令用于管理镜像、容器和服务,命令的统
#### 1. docker search 镜像名 #### 1. docker search 镜像名
从官方镜像仓库 Docker Hub 查找指定名称的镜像。常用参数为`--no-trunc`,代表显示完整的镜像信息。 从官方镜像仓库 Docker Hub 查找指定名称的镜像。常用参数为 `--no-trunc`,代表显示完整的镜像信息。
#### 2. docker images #### 2. docker images
@ -86,26 +86,26 @@ Docker 提供了大量命令用于管理镜像、容器和服务,命令的统
#### 3. docker pull 镜像名 [:TAG] #### 3. docker pull 镜像名 [:TAG]
从官方仓库下载镜像,`:TAG`为镜像版本,不加则默认下载最新版本。 从官方仓库下载镜像,`:TAG` 为镜像版本,不加则默认下载最新版本。
#### 4. docker rmi 镜像名或ID [:TAG] #### 4. docker rmi 镜像名或ID [:TAG]
删除指定版本的镜像,不加`:TAG`则默认删除镜像的最新版本。如果有基于该镜像的容器存在,则该镜像无法直接删除,此时可以使用参数`-f`代表强制删除。rmi 命令支持批量删除,多个镜像名之间使用空格分隔。如果想要删除所有镜像,则可以使用命令`docker rmi -f $(docker images -qa)` 删除指定版本的镜像,不加 `:TAG` 则默认删除镜像的最新版本。如果有基于该镜像的容器存在,则该镜像无法直接删除,此时可以使用参数 `-f`代表强制删除。rmi 命令支持批量删除,多个镜像名之间使用空格分隔。如果想要删除所有镜像,则可以使用命令 `docker rmi -f $(docker images -qa)`
## 3.3 容器相关命令 ## 3.3 容器相关命令
#### 1. docker run [OPTIONS] IMAGE [COMMAND] [ARG...] #### 1. docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
run 是 docker 中最为核心的一个命令,用于新建并启动容器,其拥有众多可用参数,可以使用`docker run --help`查看所有可用参数。常用参数如下: run 是 docker 中最为核心的一个命令,用于新建并启动容器,其拥有众多可用参数,可以使用 `docker run --help` 查看所有可用参数。常用参数如下:
+ **-i** :表示使用交互模式,始终保持输入流开放; + **-i** :表示使用交互模式,始终保持输入流开放;
+ **-t** :表示分配一个伪终端,通常和`-i`结合使用,表示使用伪终端与容器进行交互; + **-t** :表示分配一个伪终端,通常和 `-i` 结合使用,表示使用伪终端与容器进行交互;
+ **-d** :以后台方式运行容器; + **-d** :以后台方式运行容器;
+ **--name** :指定容器启动容器的名字,如果不指定,则由 docker 随机分配; + **--name** :指定容器启动容器的名字,如果不指定,则由 docker 随机分配;
+ **-c** :用于给运行在容器中的所有进程分配 CPU 的 shares 值,这是一个相对权重,实际的处理速度与宿主机的 CPU 相关; + **-c** :用于给运行在容器中的所有进程分配 CPU 的 shares 值,这是一个相对权重,实际的处理速度与宿主机的 CPU 相关;
+ **-m** 用于限制为容器中所有进程分配的内存总量以B、K、M、G为单位 + **-m** :用于限制为容器中所有进程分配的内存总量,以 B、K、M、G 为单位;
+ **-v** :用于挂载数据卷 volume可以用多个`-v`参数同时挂载多个 volume。volume 的格式为:`[host-dir]:[container-dir]:[rw:ro]``[rw:ro]`用于指定数据卷的模式,`rw`代表读写模式,`ro`代表只读模式。 + **-v** :用于挂载数据卷 volume可以用多个 `-v` 参数同时挂载多个 volume。volume 的格式为:`[host-dir]:[container-dir]:[rw:ro]` `[rw:ro]` 用于指定数据卷的模式,`rw` 代表读写模式,`ro` 代表只读模式。
+ **-p** :用于将容器的端口暴露给宿主机的端口,格式为:`hostPort:containerPort`,通过端口的暴露,可以让外部主机能够访问容器内的应用。 + **-p** :用于将容器的端口暴露给宿主机的端口,格式为:`hostPort:containerPort` ,通过端口的暴露,可以让外部主机能够访问容器内的应用。
#### 2. docker ps [OPTIONS] #### 2. docker ps [OPTIONS]
@ -118,7 +118,7 @@ run 是 docker 中最为核心的一个命令,用于新建并启动容器,
#### 3. 启动\重启\停止\强制停止容器 #### 3. 启动\重启\停止\强制停止容器
与容器启动、停止相关的命令为:`docker start|restart|stop|kill 容器名或ID`start 命令用于启动已有的容器restart 用于重启正在运行的容器stop 用于停止正在运行的容器kill 用于强制停止容器。 与容器启动、停止相关的命令为:`docker start|restart|stop|kill 容器名或ID` start 命令用于启动已有的容器restart 用于重启正在运行的容器stop 用于停止正在运行的容器kill 用于强制停止容器。
#### 4. 进入正在运行的容器 #### 4. 进入正在运行的容器
@ -136,11 +136,11 @@ run 是 docker 中最为核心的一个命令,用于新建并启动容器,
#### 6. docker rm 容器名或ID #### 6. docker rm 容器名或ID
删除已停止的容器,常用参数为`-f`,表示强制删除容器,即便容器还在运行。想要删除所有容器,可以使用`docker rm -f $(docker ps -aq)`命令。 删除已停止的容器,常用参数为`-f`,表示强制删除容器,即便容器还在运行。想要删除所有容器,可以使用 `docker rm -f $(docker ps -aq)` 命令。
#### 7. 查看容器信息 #### 7. 查看容器信息
可以使用`docker inspect [OPTIONS] NAME|ID [NAME|ID...]`查看容器或者镜像的详细信息,想要查看指定的信息,可以使用 `-- format`参数来指定输出的模板格式,示例如下: 可以使用 `docker inspect [OPTIONS] NAME|ID [NAME|ID...]` 查看容器或者镜像的详细信息,想要查看指定的信息,可以使用 `-- format` 参数来指定输出的模板格式,示例如下:
```shell ```shell
docker inspect --format='{{.NetworkSettings}}' 32cb3ace3279 docker inspect --format='{{.NetworkSettings}}' 32cb3ace3279
@ -148,7 +148,7 @@ docker inspect --format='{{.NetworkSettings}}' 32cb3ace3279
#### 8. 查看容器运行日志 #### 8. 查看容器运行日志
可以使用`docker logs [OPTIONS] CONTAINER`查看容器中进程的运行日志,常用参数如下: 可以使用 `docker logs [OPTIONS] CONTAINER` 查看容器中进程的运行日志,常用参数如下:
- **--details** :显示日志详情 - **--details** :显示日志详情
- **-f** :跟随日志输出显示 - **-f** :跟随日志输出显示
@ -177,14 +177,14 @@ LABEL 指令可以用于指定镜像相关的元数据信息。格式为:`LABE
### 4. ENV ### 4. ENV
ENV 指令用于声明环境变量,声明好的环境变量可以在后面的指令中引用,引用格式为`$variable_name``${variable_name}`。常用格式有以下两种: ENV 指令用于声明环境变量,声明好的环境变量可以在后面的指令中引用,引用格式为 `$variable_name` `${variable_name}` 。常用格式有以下两种:
+ `ENV <key> <value>` :用于设置单个环境变量; + `ENV <key> <value>` :用于设置单个环境变量;
+ `ENV <key>=<value> ...` :用于一次设置多个环境变量。 + `ENV <key>=<value> ...` :用于一次设置多个环境变量。
### 5. EXPOSE ### 5. EXPOSE
EXPOSE 用于指明容器对外暴露的端口号,格式为:`EXPOSE <port> [<port>/<protocol>...]`,您可以指定端口是侦听 TCP 还是 UDP如果未指定协议则默认为 TCP。 EXPOSE 用于指明容器对外暴露的端口号,格式为:`EXPOSE <port> [<port>/<protocol>...]` ,您可以指定端口是侦听 TCP 还是 UDP如果未指定协议则默认为 TCP。
### 6. WORKDIR ### 6. WORKDIR
@ -203,7 +203,7 @@ COPY 指令的常用格式为:`COPY <src>... <dest>`,用于将指定路径
### 8. ADD ### 8. ADD
ADD 指令的常用格式为:`COPY <src>... <dest>`,作用与 COPY 指令类似,但功能更为强大,例如`Src`支持文件的网络地址,且如果`Src`指向的是压缩文件ADD 在复制完成后还会自动进行解压。 ADD 指令的常用格式为:`COPY <src>... <dest>`,作用与 COPY 指令类似,但功能更为强大,例如 `Src` 支持文件的网络地址,且如果 `Src` 指向的是压缩文件ADD 在复制完成后还会自动进行解压。
### 9. RUN ### 9. RUN
@ -212,7 +212,7 @@ RUN 指令会在前一条命令创建出的镜像基础上再创建一个容器
- `RUN <command>` shell 格式) - `RUN <command>` shell 格式)
- `RUN ["executable", "param1", "param2"]` (*exec* 格式) - `RUN ["executable", "param1", "param2"]` (*exec* 格式)
使用 shell 格式时候,命令通过`/bin/sh -c`运行,而当使用 exec 格式时,命令是直接运行的,容器不调用 shell 程序,这意味着不会发生正常的 shell 处理。例如,`RUN ["echo","$HOME"]`不会对`$HOME`执行变量替换,此时正确的格式应为:`RUN ["sh","-c","echo $HOME"]`。下面的 CMD 指令也存在同样的问题。 使用 shell 格式时候,命令通过 `/bin/sh -c` 运行,而当使用 exec 格式时,命令是直接运行的,容器不调用 shell 程序,这意味着不会发生正常的 shell 处理。例如,`RUN ["echo","$HOME"]` 不会对 `$HOME` 执行变量替换,此时正确的格式应为:`RUN ["sh","-c","echo $HOME"]`。下面的 CMD 指令也存在同样的问题。
### 10. CMD ### 10. CMD
@ -236,7 +236,7 @@ ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"] CMD ["world"]
``` ```
当执行`docker run -it image`后,此时输出为`hello world`,而当你执行`docker run -it image spring`,此时 CMD 中的参数会被覆盖,此时输出为`hello spring` 当执行 `docker run -it image` 后,此时输出为 `hello world`,而当你执行 `docker run -it image spring` ,此时 CMD 中的参数会被覆盖,此时输出为`hello spring`
## 五、案例 ## 五、案例