amazing! Millions of people are learning Docker!(Chinese)
Tags: docker, awscommunitybuilder
Published: 2022-08-10 16:29:54

<a name="KgInc"></a>
# 1、环境简介
<a name="jKZWA"></a>
## 1.1、系统简介
<a name="k6tyW"></a>
### 1.1.1、Docker简介
:::info
💡Docker 是一个开源的应用容器引擎，让开发者可以打包他们的应用以及依赖包到一个可移植的容器中，然后发布到任何流行的Linux机器上，也可以实现虚拟化，容器是完全使用沙箱机制，相互之间不会有任何接口。
:::
一个完整的Docker有以下几个部分组成：

   1. dockerClient客户端
   1. Docker Daemon守护进程
   1. Docker Image镜像
   1. DockerContainer容器

Docker引擎Docker Engine是C/S架构，主要有以下部件组成：<br />**服务器（Docker daemon）**：后台运行的Docker daemon进程。Daemon进程用于管理Docker对象，包括镜像（images）、容器（containers）、网络（networks）、数据卷（data volumes）。<br />**REST接口**：同daemon交互的REST API接口。<br />**客户端（Docker client）**：命令行（CLI）交互客户端。客户端使用REST API接口同Docker daemon进行访问。Docker服务的架构图如图1-1所示。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659508191752-9cc837a5-e6a7-4994-8c53-8978f7ba4191.png#clientId=u5a83b8b4-d6d0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=482&id=w25ip&margin=%5Bobject%20Object%5D&name=image.png&originHeight=602&originWidth=769&originalType=binary&ratio=1&rotation=0&showTitle=false&size=113708&status=done&style=none&taskId=u3caca3b0-f6bb-4538-ba88-a1d38537a5e&title=&width=615.2)<br />图1-1  Docker服务的架构图
<a name="YkQ2e"></a>
### 1.1.2、Docker平台组成

![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659508375884-d18532a1-e15b-4b51-8889-792e6356a7b4.png#clientId=u5a83b8b4-d6d0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=353&id=u9a63529f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=441&originWidth=864&originalType=binary&ratio=1&rotation=0&showTitle=false&size=100940&status=done&style=none&taskId=u636d6ba8-f40b-4365-8c17-788ba3a78c0&title=&width=691.2)<br />图1-2  Docker服务组成图<br />运行一个Docker服务，组成包括Docker daemon服务器、Docker Client客户端、Docker Image镜像、Docker Registry库、Docker Contrainer容器，如图1-2所示。<br />**（1）Docker镜像：**<br />是一个只读模板，用于创建Docker容器，由Dockerfile文本描述镜像的内容。镜像定义类似“面对对象的类”，从一个基础镜像（Base Image）开始。构建一个镜像实际就是安装、配置和运行的过程，Docker镜像基于UnionFS把以上过程进行分层（Layer）存储，这样更新镜像可以只更新变化的层。Docker的描述文件为Dockerfile，Dockerfile是一个文本文件，基本指令包括：<br />FROM：定义基础镜像。<br />MAINTAINER ：作者或维护者。<br />RUN：运行linux 命令。<br />ADD：增加文件或目录。<br />EVN：定义环境变量。<br />CMD：运行进程。<br />**（2）Docker容器：**<br />是一个镜像的运行实例。容器有镜像创建，运行过程例如：<br />运行ubuntu操作系统镜像，-i 前台交互模型，运行命令为/bin/bash

```bash
$ docker run -i -t ubuntu /bin/bash
```
拉（pull）镜像，Docker Engine 检查ubuntu  镜像是否存在，如果本地已经存在，使用该镜像创建容器，如果不存在，Docker Engine从镜像库拉镜像。<br />使用该镜像创建新容器。<br />分配文件系统，挂载一个读写层，在读写从加载镜像。<br />分配网络/网桥接口，创建一个网络接口，让容器和主机通信。<br />从可用的IP池选择IP地址，分配给容器。<br />执行命令/bin/bash。<br />捕获和提供执行结果。<br />**（3）Docker 仓库：**<br />Docker仓库是Docker镜像库。Docker Registry也是一个容器。Docker Hub是Docker公司提供的互联网公共镜像仓库。可以构建自己本地的镜像仓库，国内有些公司也构建了镜像仓库。包括阿里云、新浪等。Docker 集群服务：Docker集群服务运行承租的Docker节点一起工作。目前支持swarm模式。<br />一个 Docker Registry 节点中可以包含多个仓库（Repository）；每个仓库可以包含多个标签（Tag）；每个标签对应一个镜像。<br />一般而言，一个仓库包含的是同一个软件的不同版本的镜像，而标签则用于对应于软件的的不同版本。<br />可以通过 <仓库名>:<标签> 的格式来指定具体是哪个版本的镜像。如果不给出标签，将以 latest 作为默认标签。<br />以[Ubuntu镜像](https://hub.docker.com/_/ubuntu/)为例，ubuntu 是仓库的名字，其内包含有不同的版本标签，如，14.04, 16.04。可以通过 ubuntu:14.04，或者 ubuntu:16.04 来具体指定所需哪个版本的镜像。如果忽略了标签，比如ubuntu，那将视为 ubuntu:latest。
```bash
docker pull ubuntu:16:04
docker pull ubuntu:14:04
docker pull ubuntu  #这里指代  ubuntu:latest
```

<a name="dbvjO"></a>
## 1.2、预装环境说明
<a name="IfDPV"></a>
### 1.2.1、软件版本说明
宿主机系统:CentOS 7.9<br />Docker版本: 1.13.1

<a name="MNQdY"></a>
### 1.2.2、基础环境配置
:::info
💡本次实验环境采用下面的基础环境1-4步骤进行基础设置，请勿遗漏
:::
**1.关闭selinux**
```bash
# vi /etc/sysconfig/selinux
SELINUX=disabled # 修改enforcing为disabled
# getenforce
Disabled
```
2.关闭防火墙
```bash
systemctl stop firewalld
```
3.删除iptables防火墙规则
```bash
iptables –F
iptables –X
iptables –Z
/usr/sbin/iptables-save
```

4.修改系统内核
```bash
打开内核转发功能。
vi /etc/sysctl.conf
编辑配置文件/etc/sysctl.conf，将以下内容添加,添加完后在命令模式下 :wq 保存退出：
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0

#修改完成后使用命令生效。
sysctl –p
```




<a name="YFDTc"></a>
# 2、服务安装
<a name="ml3iB"></a>
## 2.1、安装Docker服务
<a name="o9pEx"></a>
### 2.1.1、CentOS安装Docker
```bash
yum install -y docker  #安装docker服务
systemctl restart docker #启动docker服务
systemctl enable docker #设置开机启动
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659544916107-e0d4bf98-00df-47f5-8d73-43f25173a09c.png#clientId=u96e9434f-4c8c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=310&id=u2918bcab&margin=%5Bobject%20Object%5D&name=image.png&originHeight=387&originWidth=627&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8969&status=done&style=none&taskId=ud9e657d0-bd6a-48b2-a7f1-0a554d2c14a&title=&width=501.6)
<a name="jagMK"></a>
### 2.1.2、Ubuntu安装Docker
```bash
sudo apt-get update
sudo apt-get install -y docker.io
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659532641801-0dfd6a77-2f44-4ac4-b37f-d025288fef19.png#clientId=u5a83b8b4-d6d0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=225&id=u4aa98cab&margin=%5Bobject%20Object%5D&name=image.png&originHeight=281&originWidth=891&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7383&status=done&style=none&taskId=u9ded8361-2ab2-432f-8c37-6b564117c2f&title=&width=712.8)
<a name="nsRZT"></a>
# 3、镜像
:::info
在之前的介绍中，我们知道镜像是 Docker 的三大组件之一。 Docker 运行容器前需要本地存在对应的镜像，如果镜像不存在本地，Docker 会从镜像仓库下载（默认是 Docker Hub 公共 注册服务器中的仓库）。 本章将介绍更多关于镜像的内容，包括： 从仓库获取镜像； 管理本地主机上的镜像； 介绍镜像实现的基本原理。  
:::
  本节将介绍更多关于镜像的内容，包括： 

1. 从仓库获取镜像； 
1. 管理本地主机上的镜像； 
1. 介绍镜像实现的基本原理。  

<a name="QdH6S"></a>
## 3.1、设置镜像加速（阿里云）
[点击此处设置阿里云镜像加速服务](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors):[https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors](https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659694661235-5474305b-e84a-4fec-b241-9c2551201243.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=667&id=ubc5de466&margin=%5Bobject%20Object%5D&name=image.png&originHeight=834&originWidth=1160&originalType=binary&ratio=1&rotation=0&showTitle=false&size=59639&status=done&style=none&taskId=u7e0ca459-f361-4d65-8ba9-d739df03509&title=&width=928)<br />修改为阿里云镜像加速<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659694291869-6a880758-7ebf-4964-ade2-54b6e270911b.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=174&id=StHVJ&margin=%5Bobject%20Object%5D&name=image.png&originHeight=217&originWidth=629&originalType=binary&ratio=1&rotation=0&showTitle=false&size=13054&status=done&style=none&taskId=u272e915b-dc58-420b-a163-7a96afdb536&title=&width=503.2)
<a name="YqXjj"></a>
## 3.2、拉取镜像(pull)  
 可以使用 docker pull 命令来从仓库获取所需要的镜像。  <br />这里使用nginx镜像作为演示
```bash
# 以nginx为例

docker pull nginx
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659605061782-5704e715-a461-4313-a09a-f7b5f8363eb8.png#clientId=u69928ef9-8d99-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=226&id=ufad1302a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=283&originWidth=920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=37412&status=done&style=none&taskId=u782ad60d-a3f2-4e88-a4d5-6876ffa9c5d&title=&width=736)
<a name="XgdEi"></a>
## 3.3、列出镜像(images)
```bash
# 列出本地所有镜像
docker images 
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659617996251-388e4409-fc1f-492e-b738-1fcd1b60fe8e.png#clientId=u2ec06010-83bd-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=100&id=uc3a07f84&margin=%5Bobject%20Object%5D&name=image.png&originHeight=125&originWidth=590&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8580&status=done&style=none&taskId=u2bf514b5-fa72-4f42-bf79-ddc5bb01be5&title=&width=472)<br /> 在列出信息中，可以看到几个字段信息 <br />来自于**哪个仓库(REPOSITORY)---> docker.io/nginx**<br />比如 nginx 镜像的**标记(TAG)**，比如 latest  <br />它的 ID 号（唯一）--->  b692a91e4e15<br /> 创建时间  ---> 2 days ago<br />镜像大小  ---> 142 MB
<a name="N3LMM"></a>
## 3.4、创建镜像(commit/import/Dockerfile)
<a name="mKklG"></a>
### 3.4.1、使用commit创建镜像
:::info
💡其中， -m 来指定提交的说明信息，跟我们使用的版本控制工具一样； -a 可以指定更新的用户信息；之后是用来创建镜像 的容器的 ID；最后指定目标镜像的仓库名和 tag 信息。创建成功后会返回这个镜像的 ID 信息。
:::
  
```bash
# 运行一个名为nginx的容器 映射宿主机 8081到80端口
docker run -dit --name nginx -p 8081:80 nginx
# 查看所有容器
docker ps -a
# 使用exec 命令进入 nginx容器内
docker exec -it nginx bash

# 使用echo 替换 index.html页面显示内容
echo "this is v2 website" > /usr/share/nginx/html/index.html


# 此处的 ee9d263ea0f7 为之前创建的 nginx 容器 id
docker commit -m "this is v2 web" -a "UniStars" ee9d263ea0f7 nginx:v2

# 使用新构建的镜像运行容器
docker run -dit --name nginx2 nginx:v2
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659620488487-4bd77453-daaf-4f24-be71-fc2e1a07c630.png#clientId=u2ec06010-83bd-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=498&id=u07d0e884&margin=%5Bobject%20Object%5D&name=image.png&originHeight=622&originWidth=1205&originalType=binary&ratio=1&rotation=0&showTitle=false&size=65276&status=done&style=none&taskId=ud2a5681c-4be1-4eee-9d84-ba1e79c31a2&title=&width=964)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659620663621-c62ab07b-1e3a-4e0e-9e8d-24c6afbaede5.png#clientId=u2ec06010-83bd-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=208&id=u4034880a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=260&originWidth=1171&originalType=binary&ratio=1&rotation=0&showTitle=false&size=27795&status=done&style=none&taskId=uc85f9dc9-3ee4-4f15-ac3f-87739e1fae6&title=&width=936.8)

<a name="hI0cs"></a>
### 3.4.2、使用Dockerfile创建镜像
Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在[命令行](https://so.csdn.net/so/search?q=%E5%91%BD%E4%BB%A4%E8%A1%8C&spm=1001.2101.3001.7020)中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。<br /> <br />  
```bash
# 使用mkdir 命令在当前目录下创建一个dockerfile目录
mkdir dockerfile
# 使用vi命令 创建并编写 Dockerfile 文件
vi Dockerfile

# 添加如下内容
FROM centos:7
RUN yum -y install httpd
RUN echo "Build By Dockerfile" > /var/www/html/index.html
RUN echo "ServerName localhost:80" >> /etc/httpd/conf/httpd.conf
EXPOSE 80
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]

# 运行docker build 命令来构建该镜像，这里的-t 后面跟的是这个镜像的TAG
 docker build -t httpd:v1 .
# 运行 docker images 查看构建成功的镜像
docker images

# 使用docker run 来运行刚刚构建的镜像
docker run -dit --name http -p 8088:80 httpd:v1
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659681554035-55c786a5-8c7b-4d96-82e7-bba3d9b570cd.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=124&id=u54849306&margin=%5Bobject%20Object%5D&name=image.png&originHeight=155&originWidth=605&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9396&status=done&style=none&taskId=uc412b5c8-a19a-40a0-8d3b-b3bf1a5667b&title=&width=484)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659681620391-e9ef090d-7ba7-4728-979f-3971e29f797d.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=329&id=u1440bb32&margin=%5Bobject%20Object%5D&name=image.png&originHeight=411&originWidth=655&originalType=binary&ratio=1&rotation=0&showTitle=false&size=40829&status=done&style=none&taskId=ud311d912-26b0-4b1e-9aac-52c6437b9b2&title=&width=524)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659681675208-ee22d90f-57a2-4936-9964-aae2459bb992.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=174&id=u63db84ea&margin=%5Bobject%20Object%5D&name=image.png&originHeight=218&originWidth=735&originalType=binary&ratio=1&rotation=0&showTitle=false&size=26761&status=done&style=none&taskId=ud9336979-05b0-44a4-a4de-00b047865c3&title=&width=588)
<a name="tjF1m"></a>
### 3.4.3、Dockerfile详解
Dockerfile 由一行行命令语句组成，并且支持以 # 开头的注释行。  <br />Dockerfile 基本的语法如下

1.  使用 # 来注释  
1. MAINTAINER 镜像作者信息
1. FROM 指令告诉 Docker 使用哪个镜像作为基础  
1. RUN 开头的指令会在创建中运行，比如安装一个软件包，在这里使用 yum 来安装了一些软件  
1. COPY 从 Docker 宿主机复制文件至创建的新镜像文件
1. ADD 类似于 COPY 指令，ADD 支持 tar 文件和 URL 路径
1. WORKDIR 用于为 Dockerfile 中所有的 RUN、CMD、ENTRYPOINT、COPY、ADD 指定设定工作目录
1. VOLUME 数据卷，用于在 image 中创建挂载点目录，以挂载 Docker host 上的卷或者其他容器上的卷
1. EXPOSE 为容器打开指定的监听端口以实现与外部通信
1. ENV 用于为镜像定义所需的环境变量，可以被 Dockerfile 文件中其他命令调用(ENV、ADD、COPY、RUN、CMD)
1. CMD 启动容器指定默认要运行的程序或命令，默认"/bin/sh -c"运行
1. ENTRYPOINT 类型 CMD 指令的功能，用于为容器指定默认运行程序或命令
1. USER 指定当前用户


<a name="vqdqc"></a>
#### 3.4.3.1、FROM
格式为 FROM  <IMAGE> 或 FROM <IMAGE>:TAG。<br />第一条指令必须为 FROM 指令。并且，如果在同一个Dockerfile中创建多个镜像时，可以使用多个 FROM 指令（每个镜像 一次）。 
```bash
FROM centos:7
```
<a name="Jxl0a"></a>
#### 3.4.3.2、MAINTAINER  
格式为 MAINTAINER <AUTHOR_NAME>  ，指定维护者信息。 
```bash
MAINTAINER FengLei
```
<a name="dqfG6"></a>
#### 3.4.3.3、RUN  
格式为:

1. RUN <Command>
1. RUN  ["executable", "param1", "param2"] 
```bash
RUN yum -y install httpd
```
前者将在 shell 终端中运行命令，即 /bin/sh -c ；后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实 现，例如 RUN ["/bin/bash", "-c", "echo Build_Dockerfile"] 。<br />每条 RUN 指令将在当前镜像基础上执行指定命令，并提交为新的镜像。当命令较长时可以使用 \ 来换行。 
```bash
RUN yum clean all; \
    yum install -y httpd; \
    mkdir -p /var/www/html/;
```
 
<a name="XOMNh"></a>
#### 3.4.3.4、COPY
格式：

1. COPY <src>... <dest>
1. COPY ["<src1>",... "<dest>"]

和 RUN 指令一样，也有两种格式，一种类似于命令行，一种类似于函数调用。<br />复制本地主机的  <src>.（为 Dockerfile 所在目录的相对路径）到容器中的<dest>。<br />当使用本地目录为源目录时，推荐使用 COPY 。 <br />COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像 内的 <目标路径> 位置。比如： 
```bash
COPY index /usr/share/nginx/html
```
<源路径> 可以是多个，甚至可以是通配符，其通配符规则要满足 Go 的 filepath.Match 规则，如：<br />COPY /root/* /mnt/<br />COPY /root/*.html /usr/share/nginx/html/<br />**<目标路径>** 可以是容器内的绝对路径，也可以是相对于工作目录的相对路径（工 作目录可以用 WORKDIR 指令来指定）。目标路径不需要事先创建，如果目录不存 在会在复制文件前先行创建缺失目录。 此外，还需要注意一点，使用 COPY 指令，源文件的各种元数据都会保留。比如 读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建 相关文件都在使用 Git 进行管理的时候。 
<a name="hPMQw"></a>
#### 3.4.3.5、ADD
格式为 ADD  <src> <dest>。<br />该命令将复制指定的 <drc> 到容器中的<Dest>   。<br />其中<drc>可以是Dockerfile所在目录的一个相对路径；也可以是 一个 URL；还可以是一个 tar 文件（自动解压为目录）。 
```bash
FROM centos:7
ADD httpd-2.4.tar.gz /
```
<a name="hDPZs"></a>
#### 3.4.3.6、WORKDIR  
格式为 WORKDIR <Your_Work_Dir> <br />为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。<br />可以使用多个 WORKDIR 指令，后续命令如果参数是相对路径，则会基于之前命令指定的路径。例如  
```bash
WORKDIR /mnt/
WORKDIR dir1
WORKDIR dir2
```
  最终路径为  **/mnt/dir1/dir2**


<a name="K4N2c"></a>
#### 3.4.3.7、USER
格式为 USER <用户名><br />USER 指令和 WORKDIR 相似，都是改变环境状态并影响以后的层。 WORKDIR 是改变工作目录， USER 则是改变之后层的执行 RUN , CMD 以及 ENTRYPOINT 这类命令的身份。<br />**注意: USER只是切换用户，该用户必须事先存在**
```bash
RUN groupadd -r ug && useradd -r -g ug user1
USER user1
```

<a name="ZVPzC"></a>
#### 3.4.3.8、VOLUME
格式为 VOLUME ["/data"] 。<br />创建一个可以从本地主机或其他容器挂载的挂载点，一般用来存放数据库和需要保持的数据等。 

<a name="XDngK"></a>
#### 3.4.3.9、EXPOSE
格式为 EXPOSE  [...] 。<br />告诉 Docker 服务端容器暴露的端口号，供互联系统使用。<br />这只是一个声明，在运行时并不 会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有 两个好处，一个是帮助镜像使用者理解这个镜像服务的守护端口，以方便配置映 射；另一个用处则是在运行时使用随机端口映射时，也就是 docker run -P 时，会自动随机映射 EXPOSE 的端口。  
```bash
FROM centos:7
EXPOSE 80,22
```

<a name="d3dyg"></a>
#### 3.4.3.10、ENV
格式有两种：

1. ENV <KEY> <VALUE>
1. ENV <KEY>=<VALUE>

这个指令就是设置环境变量，无论是后面的其它指令，如 RUN ，还是运行时的应用，都可以直接使用这里定义的环境变量。定义了环境变量，那么在后续的指令中，就可以使用这个环境变量。 <br />这里的例子演示了定义MYSQL的用户和密码
```bash
ENV MYSQL_USER docker_user
ENV MYSQL_PASS docker_password
```

<a name="MfBv3"></a>
#### 3.4.3.11、CMD
支持三种格式，分别是:

1. CMD ["executable","param1","param2"] 使用 exec 执行（推荐）；
1. CMD command param1 param2 在 /bin/sh 中执行，提供给需要交互的应用；
1. CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数；  

指定启动容器时执行的命令，每个 Dockerfile 只能有一条 CMD 命令。<br />如果指定了多条命令，只有最后一条会被执行。<br />如果用户启动容器时候指定了运行的命令，则会覆盖掉 CMD 指定的命令。  <br />在运行时可以指定新的命令来替代镜像设置中的这个默认命令，比如， centos 镜像默认的 CMD 是 /bin/bash ，如果我们直接 docker run -it centos ,会直接进入 bash 。<br />也可以在运行时指定运行别的命令，如 docker run -it centos cat /etc/redhat-release。这就是用 cat /etc/redhat-release 命令替换了默认的 /bin/bash 命令<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659776519682-0b3b8545-5d01-4b12-aaf4-33a6dd17c966.png#clientId=u73d06e87-6ff8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=158&id=u1e5d7bdc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=197&originWidth=1502&originalType=binary&ratio=1&rotation=0&showTitle=false&size=22751&status=done&style=none&taskId=uf82e1695-2590-4468-9475-609a0072af1&title=&width=1201.6)<br />在指令格式上，一般推荐使用** exec **格式，这类格式在解析时会被解析为 JSON 数组，因此一定要使用双引号 " ，而不要使用单引号。 <br />如果使用 shell 格式的话，实际的命令会被包装为 sh -c 的参数的形式进行 执行。比如：<br />CMD echo $USERNAME在实际执行中，会将其变更为： CMD [ "sh", "-c", "echo $USERNAME" ]
```bash
CMD [ "sh", "-c", "echo $USERNAME" ]
```
这就是为什么我们可以使用环境变量的原因，因为这些环境变量会被 shell 进行解 析处理。 提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出 现的一个混淆。  

<a name="BfCsy"></a>
#### 3.4.3.12、ENTRYPOINT
ENTRYPOINT  成为 入口点<br />ENTRYPOINT 的格式和 RUN 指令格式一样，分为 exec 格式和 shell 格 式。  <br /> 拥有两种格式：

1. ENTRYPOINT ["executable", "param1", "param2"]
1. ENTRYPOINT command param1 param2 （shell中执行）。

配置容器启动后执行的命令，并且不可被 docker run 提供的参数覆盖。 每个 Dockerfile 中只能有一个 ENTRYPOINT ，当指定多个时，只有最后一个起效。  <br />ENTRYPOINT 的目的和 CMD 一样，都是在指定容器启动程序及参 数。 ENTRYPOINT 在运行时也可以替代，不过比 CMD 要略显繁琐，需要通过 docker run 的参数 --entrypoint 来指定。 当指定了 ENTRYPOINT 后， CMD 的含义就发生了改变，不再是直接的运行其命令，而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令，换句话说实际执行 时，将变为：  <br /><ENTRYPOINT> "CMD"

<a name="B60VQ"></a>
### 3.4.4、Dockerfile演示
<a name="ETdgd"></a>
#### 3.4.4.1、构建带有openssh-server功能的容器镜像
centos-7 镜像为基础镜像,安装openssh-server服务，暴露端口 22，容器开机运行 sshd
```bash
FROM centos:7

RUN yum install -y openssh-server sudo
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config 

#RUN useradd admin
#RUN echo "admin:admin" | chpasswd
RUN echo "root:123456" | chpasswd
#RUN echo "admin  ALL=(ALL)    ALL" >> /etc/sudoers

RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key

RUN mkdir /var/run/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659780138975-1100db04-41b8-4438-9fde-419efc72604e.png#clientId=u8f254822-3363-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=337&id=u3526e3df&margin=%5Bobject%20Object%5D&name=image.png&originHeight=421&originWidth=682&originalType=binary&ratio=1&rotation=0&showTitle=false&size=41707&status=done&style=none&taskId=u0f918358-af4f-4583-95e9-3a26592bb6c&title=&width=545.6)<br />编写完成 Dockerfile 后可以使用 docker build 来生成镜像。<br />其中 -t 标记来添加 tag，指定新的镜像的用户信息。<br />“.” 是 Dockerfile 所在的路径（当前目录），也可以替换为一个具体的 Dockerfile 的路径  <br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659780169279-0501ba8d-f9bf-4660-aec8-6059a7c80d72.png#clientId=u8f254822-3363-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=226&id=u32c67fe8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=283&originWidth=666&originalType=binary&ratio=1&rotation=0&showTitle=false&size=28304&status=done&style=none&taskId=u57cfe638-e02d-4889-95c5-cfc370ca16f&title=&width=532.8)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659780270468-d9d1d6a2-eedf-4b2b-893a-169c35f56858.png#clientId=u8f254822-3363-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=366&id=u570f14c5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=457&originWidth=1471&originalType=binary&ratio=1&rotation=0&showTitle=false&size=87251&status=done&style=none&taskId=u505ec317-c0e2-4da7-9f97-d45c4ae4e40&title=&width=1176.8)

<a name="eGW87"></a>
## 3.5、标记(tag)
:::info
以阿里云为例,稍后会在仓库小节进行详细描述
:::
```bash
docker tag 镜像id 远程/本地仓库/镜像名称:版本号

例如:
docker tag 37bb9c63c8b2 registry-vpc.cn-hangzhou.aliyuncs.com/acs/agent:0.7-dfb6816

37bb9c63c8b2 为镜像id
registry-vpc.cn-hangzhou.aliyuncs.com/acs/  为仓库地址
agent 为镜像名称
0.7-dfb6816 为版本号


```
<a name="vYTbz"></a>
## 3.6、上传镜像(push)
:::info
以阿里云为例,稍后会在仓库小节进行详细描述
:::

<a name="LFVNg"></a>
## 3.7、导出/导入(save/load)
 如果要导出镜像到本地文件，可以使用 docker save 命令。  <br /> 可以使用 docker load 从导出的本地文件中再导入到本地镜像库
```bash
# 列出镜像,找出要导出
docker images

# 导出镜像
docker save -o nginx_sv2.tar nginx:v2

# 查看
ls -l

```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659684898808-aa784241-242b-4481-842c-7767abd8f7f9.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=204&id=u651dd389&margin=%5Bobject%20Object%5D&name=image.png&originHeight=255&originWidth=650&originalType=binary&ratio=1&rotation=0&showTitle=false&size=27762&status=done&style=none&taskId=u2929d671-8e1c-412c-8a0c-a74b4fa5821&title=&width=520)

```bash
# 查看准备导入的镜像包
ls -l

# 先删除已存在的 nginx:v2
docker rmi 2ee0ee0dc960

# 导入镜像,2种语法

docker load --input nginx_v2.tar
docker load < nginx_v2.tar

```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659684960314-a968ac9c-8557-4c86-b8f9-f78e6f295971.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=289&id=ub2994a50&margin=%5Bobject%20Object%5D&name=image.png&originHeight=361&originWidth=785&originalType=binary&ratio=1&rotation=0&showTitle=false&size=47344&status=done&style=none&taskId=ucd3efa71-30ac-4e6d-961b-645d8f839bf&title=&width=628)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659685008394-8a6212e4-d0b4-4d5a-83fa-4e3ef2692202.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=321&id=u3b78c831&margin=%5Bobject%20Object%5D&name=image.png&originHeight=401&originWidth=1005&originalType=binary&ratio=1&rotation=0&showTitle=false&size=56345&status=done&style=none&taskId=udfbfa860-a04f-493d-a3a1-f5d1ef8d271&title=&width=804)

<a name="avTIs"></a>
## 3.8、使用supermin5构建镜像
使用 supermin5 命令构建 centos7系统的 docker 镜像，镜像名称为 centos-7，镜像预装 yum、net-tools、initscripts 和 vi 命令
```bash
# 安装supermin
yum -y install supermin*

# supermin5 添加预装工具 yum net-tools initscripts vi
supermin5 -v --prepare bash coreutils  yum  net-tools initscripts vim-minial  -o supermin.d
# supermin5 构建
supermin5 -v --build --format chroot supermin.d -o appliance.d

echo 7 >  appliance.d/etc/yum/vars/releasever
# 镜像打包
tar --numeric-owner -cpf centos-7.tar -C appliance.d .

# 导入镜像
cat centos-7.tar | docker import - centos-7
# 运行
docker run -dit --name centos7 centos-7 /bin/bash
cat /etc/redhat-release

```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659781187405-049f3717-c300-4897-8b88-af660d0c5c63.png#clientId=udea96b3d-a287-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=173&id=u467df879&margin=%5Bobject%20Object%5D&name=image.png&originHeight=216&originWidth=755&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29203&status=done&style=none&taskId=u699daf3a-e38e-46d6-a0b2-b79f5c6ea69&title=&width=604)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659781308272-6350cb1e-263c-4495-bda0-0b17c8ceb024.png#clientId=udea96b3d-a287-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=170&id=u98265c12&margin=%5Bobject%20Object%5D&name=image.png&originHeight=212&originWidth=954&originalType=binary&ratio=1&rotation=0&showTitle=false&size=25841&status=done&style=none&taskId=ubc2d94b3-52af-4f10-96c6-ac7c2bfa838&title=&width=763.2)

<a name="YzKmT"></a>
## 3.9、删除镜像(rmi)
```bash
docker rmi 镜像iD

例:
docker rmi b692a91e4e15
docker rmi b6
b692a91e4e15 代表nginx镜像的id 也可以只写 前两位

```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659685040300-ffac5bb7-e8f7-4bce-90ca-e2ce0cc01d49.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=242&id=u2469fa56&margin=%5Bobject%20Object%5D&name=image.png&originHeight=302&originWidth=895&originalType=binary&ratio=1&rotation=0&showTitle=false&size=39963&status=done&style=none&taskId=uaefa1282-490a-471e-ba7b-cf2919d54d3&title=&width=716)

<a name="Sg0MY"></a>
# 4、容器
:::info
 容器是 Docker 又一核心概念。 <br />简单的说，容器是独立运行的一个或一组应用，以及它们的运行态环境。对应的，虚拟机可以理解为模拟运行的一整套操作 系统（提供了运行态环境和其他系统环境）和跑在上面的应用。 <br />本节将具体介绍如何来管理一个容器，包括创建、启动和停止等  
:::
<a name="dpJUx"></a>
## 4.1、查看容器
```bash
# 查看正在运行的容器
docker ps 

# 查看所有容器
docker ps -a


```
<a name="GUBoF"></a>
## 4.2、启动/停止容器
<a name="ZbVM9"></a>
### 4.2.1、创建并启动新容器
常用附加参数:<br />-d 在后台运行容器并打印容器ID<br />-t 选项让Docker分配一个伪终端（pseudo-tty）并绑定到容器的标准输入上<br />-i 则让容器的标准输入保持打开。<br />-p 映射端口 宿主机端口:容器端口<br />-P 随机映射端口 <br />-v 绑定卷<br />-w 设置工作目录<br />--rm 退出容器自动删除<br />--restart 重启条件，若宿主机开机要求该容器也运行 那么请设置 --restart=always<br />--name 设置容器名称<br />  
```bash
# 启动一个随宿主机启动,并映射宿主机80端口到容器80端口 的 nginx 容器
docker run -dit --name nginx -p 80:80 --restart=always nginx
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659689063558-ca23e9e0-6708-468f-be44-76dac8d2c970.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=333&id=u7c25b7ea&margin=%5Bobject%20Object%5D&name=image.png&originHeight=416&originWidth=1170&originalType=binary&ratio=1&rotation=0&showTitle=false&size=44514&status=done&style=none&taskId=u249b2040-9453-4379-8815-9fbf97c3d82&title=&width=936)
<a name="rxAzz"></a>
### 4.2.2、启动已停止的容器
```bash
docker start 容器名称/容器id
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659689109417-48840972-40ef-4052-85c2-7e2fd6e77011.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=194&id=ub7fb76c1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=243&originWidth=1220&originalType=binary&ratio=1&rotation=0&showTitle=false&size=24680&status=done&style=none&taskId=ud4e218c2-283b-4748-be64-3bd94be20ec&title=&width=976)
<a name="WQmki"></a>
### 4.2.3、停止正在运行的容器
```bash
docker stop 容器名称/容器id
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659689092330-7cf1783f-b434-400f-ada5-9a14b017ec03.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=163&id=u8bca38d6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=204&originWidth=1029&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18689&status=done&style=none&taskId=u80954046-7713-44e9-97ea-672c6c597a8&title=&width=823.2)
<a name="XCOm5"></a>
## 4.3、删除容器
```bash
# 删除已停止的容器
docker rm 容器名称/容器id

# 删除正在运行的容器  -f 代表 强制
docker rm -f 容器名称/容器id

# 删除所有停止的容器
docker container prune

```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659689132430-72a6a53b-050e-4562-93db-d8cc3d87812a.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=142&id=u8cb3d17c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=177&originWidth=679&originalType=binary&ratio=1&rotation=0&showTitle=false&size=12393&status=done&style=none&taskId=u0115ddff-730c-4dca-9904-11998a0f08a&title=&width=543.2)

<a name="SACY2"></a>
## 4.4、连接容器
在使用 -d 参数时，容器启动后会进入后台。 某些时候需要进入容器进行操作，包括使用 docker attach 命令或 docker exec 命令，推荐使用 docker exec 命令  
<a name="PcYTh"></a>
### 4.4.1、attach命令
 使用 attach 命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候，所有窗口都会同步显示。当某个窗 口因命令阻塞时,其他窗口也无法执行操作了。  <br />当使用attach退出时，容器也会退出
```bash
docker attach centos7
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659781523628-054b0496-0f12-4904-937d-115aea4a784b.png#clientId=udea96b3d-a287-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=152&id=u2427e195&margin=%5Bobject%20Object%5D&name=image.png&originHeight=190&originWidth=1423&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18970&status=done&style=none&taskId=u014d2f6b-c375-4da8-b724-0e93ad9ca3f&title=&width=1138.4)
<a name="hVIzn"></a>
### 4.4.2、exec命令
docker exec 后边可以跟多个参数，一般使用 -i -t参数。 只用 -i 参数时，由于没有分配伪终端，界面没有我们熟悉的 Linux 命令提示 符，但命令执行结果仍然可以返回。 当 -i -t 参数一起使用时，则可以看到我们熟悉的 Linux 命令提示符。  
```bash
docker exec -it centos7 bash
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659781644575-17cb28b2-91e1-4c43-852d-f8bd6433c0a0.png#clientId=udea96b3d-a287-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=165&id=u67b7e0a3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=206&originWidth=1316&originalType=binary&ratio=1&rotation=0&showTitle=false&size=22388&status=done&style=none&taskId=u8c9cd536-92b8-45fb-875c-89e2c0dea5a&title=&width=1052.8)
<a name="fI8JS"></a>
## 4.5、导入导出容器
<a name="AbDVn"></a>
### 4.5.1、导出容器
```bash
docker export 容器id > tar包名

例如
docker export 82be49d3c283 > nginx.tar
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659689257155-8b2c9533-0be3-46ec-b6a0-c57283759cbe.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=182&id=u7b78528b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=227&originWidth=1188&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32338&status=done&style=none&taskId=u59eb2bbc-2eaf-4fd5-a774-e6b0cd5c24e&title=&width=950.4)
<a name="y1eur"></a>
### 4.5.2、导入容器
```bash
# cat tar包 | docker import - 仓库/镜像名:tag
# 例：
cat nginx.tar | docker import - unistars/nginx:v1
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659689623470-b58af43a-36a5-4c79-b7aa-0fd8ffbe8913.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=239&id=udf1edf50&margin=%5Bobject%20Object%5D&name=image.png&originHeight=299&originWidth=794&originalType=binary&ratio=1&rotation=0&showTitle=false&size=38741&status=done&style=none&taskId=u62dacdd3-cdf8-4a40-853c-b5aedb241f8&title=&width=635.2)

<a name="hy9Xu"></a>
# 5、仓库
 仓库（Repository）是集中存放镜像的地方。<br /> 一个容易混淆的概念是注册服务器（Registry）。实际上注册服务器是管理仓库的具体服务器，每个服务器上可以有多个仓 库，而每个仓库下面有多个镜像。从这方面来说，仓库可以被认为是一个具体的项目或目录。<br />例如对于仓库地址 registry.cn-hangzhou.aliyuncs.com/fl_test/docker_demo 来说

   1. registry.cn-hangzhou.aliyuncs.com 是注册服务器地址
   1. fl_test 是仓库名
   1. docker_demo为镜像名称
<a name="YXndf"></a>
## 5.1、远程仓库
:::info
 目前 Docker 官方维护了一个公共仓库 Docker Hub，其中已经包括了超过 15,000 的镜像。大部分需求，都可以通过在 Docker Hub 中直接下载镜像来实现。 <br />下面以阿里云容器镜像服务为大家演示
:::

<a name="tjpT6"></a>
### 5.1.1、创建阿里云镜像仓库
[点击创建阿里云镜像仓库(杭州站)](https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard)：[https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard](https://cr.console.aliyun.com/cn-hangzhou/instance/dashboard)

1. 仓库信息---设置 命名空间   仓库名称  仓库类型 以及 说明
1. 设置代码源 ----  本地仓库

![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659697497666-d00df137-62e8-4685-812b-aedd59e79b0d.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=623&id=u3341635a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=779&originWidth=1878&originalType=binary&ratio=1&rotation=0&showTitle=false&size=69585&status=done&style=none&taskId=u9361f90f-ea2d-44af-b29a-b953902d8f0&title=&width=1502.4)![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659697509594-f0d638ae-032d-484b-89a7-d3c127d03926.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=384&id=uaca14dac&margin=%5Bobject%20Object%5D&name=image.png&originHeight=480&originWidth=1031&originalType=binary&ratio=1&rotation=0&showTitle=false&size=28092&status=done&style=none&taskId=ud65e549f-7789-48b2-b183-c59fe758cc0&title=&width=824.8)
<a name="dChrx"></a>
### 5.1.2、登录远程仓库
 可以通过执行 docker login 命令来输入用户名、密码和邮箱来完成注册和登录。 注册成功后，本地用户目录的 .dockercfg 中将保存用户的认证信息。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659694482768-8168b196-1a14-4085-b450-9a871f0e1de8.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=164&id=tgICe&margin=%5Bobject%20Object%5D&name=image.png&originHeight=205&originWidth=1041&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17752&status=done&style=none&taskId=ua937fa97-cb2a-4fcd-8ac3-1cdb7210f5d&title=&width=832.8)<br />  

<a name="mT6zj"></a>
## 5.2、本地私有仓库
有时候出于安全和网络情况考虑，云上仓库并不方便，那么，用户可以创建一个本地仓库供私人使用。 本节介绍如何使用本地仓库。 docker-registry 是官方提供的工具，可以用于构建私有的镜像仓库。  

<a name="Q6H5E"></a>
### 5.2.1、安装并运行本地  registry  仓库
```bash
# 运行本地仓库容器
docker run -dit --name registry --restart=always -p 5000:5000 registry

# 修改docker配置文件
vi /etc/sysconfig/docker
# 添加
# 172.31.36.113 为宿主机局域网IP地址，请自行更改为自己的IP地址
ADD_REGISTRY='--add-registry 172.31.36.113:5000'
INSECURE_REGISTRY='--insecure-registry 172.31.36.113:5000'

vi /etc/docker/daemon.json
# 添加
# 注意上一行后面需增加 , 
"insecure-registries":["172.31.36.113:5000"]
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659704968501-7a86ec38-d2a2-4c2d-9ee7-89cd7a3cc4a8.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=266&id=u2da86c62&margin=%5Bobject%20Object%5D&name=image.png&originHeight=332&originWidth=1332&originalType=binary&ratio=1&rotation=0&showTitle=false&size=36740&status=done&style=none&taskId=u10ee9956-691c-4785-852f-a94c701bb63&title=&width=1065.6)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659705827454-cc291392-2df0-491d-b2a6-6af38bb22050.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=364&id=u5955c63c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=455&originWidth=806&originalType=binary&ratio=1&rotation=0&showTitle=false&size=48146&status=done&style=none&taskId=u9c950d7f-bb5e-42b9-834f-939be2971c9&title=&width=644.8)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659705886073-e7711fd8-1d78-47a6-9a06-796fef3022c9.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=294&id=u603131c4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=368&originWidth=966&originalType=binary&ratio=1&rotation=0&showTitle=false&size=47833&status=done&style=none&taskId=u0e19f409-ae07-4a27-8638-88bdfef1fe3&title=&width=772.8)
<a name="JuZXY"></a>
### 5.2.2、查看仓库中镜像
```bash
curl 172.31.36.113:5000/v2/_catalog
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659712305561-88b8a726-aa52-4979-a69f-09de56275723.png#clientId=u28d579b0-9e04-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=461&id=u5c3a5b28&margin=%5Bobject%20Object%5D&name=image.png&originHeight=576&originWidth=983&originalType=binary&ratio=1&rotation=0&showTitle=false&size=80300&status=done&style=none&taskId=uc6952b73-b2ba-4b9f-929a-79ada187b04&title=&width=786.4)


<a name="TxiXp"></a>
# 6、数据管理

<a name="lz5Gt"></a>
## 6.1、数据卷
 数据卷是一个可供一个或多个容器使用的特殊目录，它绕过 UFS，可以提供很多有用的特性：

1. 数据卷可以在容器之间共享和重用
1. 对数据卷的修改会立马生效
1. 对数据卷的更新，不会影响镜像
1. 卷会一直存在，直到没有容器使用

数据卷的使用，类似于 Linux 下对目录或文件进行 mount。  

<a name="tce3F"></a>
### 6.1.1、创建数据卷
```bash
# 创建一个名为 new-volume 的数据卷
docker volume create new-volume
# 列出
docker volume ls

# 查看卷信息
docker volume inspect new-volume
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659717050603-5d036fae-e90e-46b6-8ae9-172c28ece15c.png#clientId=uaa7488e7-d8e1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=276&id=u8a455dcf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=345&originWidth=767&originalType=binary&ratio=1&rotation=0&showTitle=false&size=27763&status=done&style=none&taskId=uefca18db-874a-4259-93f6-f92524470ca&title=&width=613.6)
<a name="R3tcZ"></a>
### 6.1.2、挂载数据卷
```bash
# 启动一个挂载新卷的nginx容器
docker run -dit --name nginx -v new-volume:/mnt nginx

# 查看容器的详细信息 grep -a 这里显示具体前后行数
 docker inspect nginx|grep Mounts -a5
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659717244214-a238ed65-e339-4dcf-b2f9-7c279fc404d1.png#clientId=uaa7488e7-d8e1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=91&id=u1b985115&margin=%5Bobject%20Object%5D&name=image.png&originHeight=114&originWidth=1244&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18076&status=done&style=none&taskId=ude25cc1e-82bf-4987-b1b9-54a502a35d3&title=&width=995.2)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659717403784-54cfbe45-727a-436e-8f36-b75c5d850fcc.png#clientId=uaa7488e7-d8e1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=222&id=u7165bd5c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=277&originWidth=1213&originalType=binary&ratio=1&rotation=0&showTitle=false&size=24775&status=done&style=none&taskId=u789b3a90-a04b-43bb-a1e8-afb95d51870&title=&width=970.4)

<a name="GrKar"></a>
### 6.1.3、删除数据卷
 数据卷 是被设计用来持久化数据的，它的生命周期独立于容器，Docker 不会在 容器被删除后自动删除 数据卷 ，并且也不存在垃圾回收这样的机制来处理没有任 何容器引用的 数据卷 。如果需要在删除容器的同时移除数据卷。可以在删除容器 的时候使用 **docker rm -v** 这个命令。  
```bash
docker volume rm new-volume
```
 无主的数据卷可能会占据很多空间，要清理请使用以下命令  
```bash
docker volume prune

```
<a name="LtKlW"></a>
## 6.2、挂载主机目录
<a name="gyICR"></a>
### 6.2.1、挂载主机目录作为数据卷
 也可以使用 -v 标记也可以指定挂载一个本地主机的目录到容器中去。 
```bash
# 在root目录下创建web目录，并创建index.html文件
mkdir /root/web
echo "This is mount root dir" > /root/web/index.html

# 运行挂载主机目录 /root/web/ 到 容器/usr/share/nginx/html
docker run -dit --name nginxweb -p 8088:80 -v /root/web/:/usr/share/nginx/html/ nginx

# curl查看内容
curl localhost:8088
```
 ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659753492757-34294899-4ab0-404e-a9fa-2f6a4f1874ea.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=246&id=u8ec710cb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=307&originWidth=1280&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46431&status=done&style=none&taskId=u77711960-8788-445c-a64b-6d20fc18a50&title=&width=1024)<br />上面的命令加载主机的 **/root/web** 目录到容器的** /usr/share/nginx/html **目录。<br />这个功能在进行测试的时候十分方便，比如 用户可以放置一些程序到本地目录中，来查看容器是否正常工作。本地目录的路径必须是绝对路径，如果目录不存在 Docker 会自动为你创建它。 <br />***注意**：Dockerfile 中**不支持**这种用法，这是因为 Dockerfile 是为了移植和分享用的。然而，不同操作系统的路径格式不一 样，所以目前还不能支持。<br />Docker 挂载数据卷的默认权限是读写，用户也可以通过 :ro 指定为只读。  
```bash
docker run -dit --name nginxweb -p 8088:80 -v /root/web/:/usr/share/nginx/html/:ro nginx
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659754033255-8d0bb9b1-6a47-4012-ae60-015628a68113.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=155&id=ub2bd9161&margin=%5Bobject%20Object%5D&name=image.png&originHeight=194&originWidth=1415&originalType=binary&ratio=1&rotation=0&showTitle=false&size=35577&status=done&style=none&taskId=ue095eded-a836-475f-8954-bf26fce15d1&title=&width=1132)
<a name="L7oIk"></a>
### 6.2.2、挂载主机文件作为数据卷
同样，使用 -v 来进行挂载，从主机挂载单个文件到容器
```bash
# 创建演示文件
echo "This is mount single file" > /root/index.html

# 创建挂载单个主机文件的容器
docker run -dit --name nginxweb -p 8088:80 -v /root/index.html:/usr/share/nginx/html/index.html nginx

```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659754708280-c91f1dfe-e897-4111-98c3-50d5eee00355.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=185&id=u1d383f3b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=231&originWidth=1352&originalType=binary&ratio=1&rotation=0&showTitle=false&size=30169&status=done&style=none&taskId=ue313b27c-5f16-4c77-b8a1-79590d92450&title=&width=1081.6)
<a name="VtSBT"></a>
## 6.3、容器间共享卷
在这个案例中，将使用三个nginx容器进行演示，分别为 nginxweb1、nginxweb2、nginxweb3
```bash

# 启动nginxweb1 创建共享卷
docker run -dit --name nginxweb1 -p 8081:80 -v /usr/share/nginx/html nginx
# 启动nginxweb2、nginxweb3 并指定共享卷为 nginxweb1
docker run -dit --name nginxweb2 --volumes-from nginxweb1 -p 8082:80 nginx
docker run -dit --name nginxweb3 --volumes-from nginxweb1 -p 8083:80 nginx
# curl测试
curl localhost:8081
curl localhost:8082
curl localhost:8083
# 进入nginxweb1 进行修改index.html文件，并测试
docker exec -it nginxweb1 bash
容器内操作
echo "This is nginxweb1 website" > /usr/share/nginx/html/index.html
# 退出容器测试 exit
curl localhost:8081
curl localhost:8082
curl localhost:8083
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659757054533-7455415b-f365-4874-9732-ddeb933d7f9b.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=505&id=ucefd9263&margin=%5Bobject%20Object%5D&name=image.png&originHeight=631&originWidth=1129&originalType=binary&ratio=1&rotation=0&showTitle=false&size=80232&status=done&style=none&taskId=ud2126bba-241e-4a38-9531-b6b608ef110&title=&width=903.2)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659757078122-00dab523-0f30-4414-8ca7-2f1aeeba018c.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=230&id=u97fba3a0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=288&originWidth=987&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32504&status=done&style=none&taskId=u231d6c9b-9f28-497d-9ebd-bf7036925fc&title=&width=789.6)
<a name="JNUgO"></a>
# 7、网络管理
<a name="TJLCq"></a>
## 7.1、映射网络
容器中可以运行一些网络应用，要让外部也可以访问这些应用，可以通过 -P 或 -p 参数来指定端口映射。<br />当使用 -P 标记时，Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口。 <br />使用 docker ps 可以看到，本地主机的 49153 被映射到了容器的 80 端口。此时访问本机的 49153 端口即可访问容器 内 web 应用提供的界面。  
```bash

# 指定映射
docker run -dit --name nginxweb1 -p 8081:80 nginx

# 随机映射
docker run -dit --name nginxweb4 -P nginx

# 查看所有容器
docker ps -a
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659757950948-30df3fcf-e15f-49c3-a209-b68a67b6dc92.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=546&id=u069573c9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=682&originWidth=1550&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102923&status=done&style=none&taskId=ua21ffcef-519d-47d4-8efa-04e6f135b1f&title=&width=1240)
<a name="yzFzg"></a>
## 7.2、使用主机网络
可以使用 --network=host 参数来直接使用宿主机网络
```bash
docker run -dit --network=host --name nginx-host nginx
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659758003644-cbf61970-4aa6-4ca8-907e-5106bb33f1cc.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=545&id=u053136a1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=681&originWidth=1462&originalType=binary&ratio=1&rotation=0&showTitle=false&size=98231&status=done&style=none&taskId=u90d680b3-97e4-4a15-a4b6-adc82024191&title=&width=1169.6)
<a name="ECbh0"></a>
## 7.3、容器互联
<a name="W032Q"></a>
### 7.3.1、新建网络
 -d 参数指定 Docker 网络类型，有 bridge overlay 。其中 overlay 网络 类型用于 Swarm mode，在本小节中你可以忽略它。  
```bash
docker network create -d bridge new-net
```
<a name="qzw09"></a>
### 7.3.2、容器互联
```bash
docker run -dit --name box1 --network new-net busybox
docker run -dit --name box2 --network new-net busybox
```
<a name="yfNZ1"></a>
### 7.3.3、ping测试
```bash
# 进入box1容器
docker exec -it box1 sh

# ping测试
ping box2
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659761438344-c50837c0-baf8-463b-8abd-53ed931927e7.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=294&id=ubbf72f26&margin=%5Bobject%20Object%5D&name=image.png&originHeight=368&originWidth=1689&originalType=binary&ratio=1&rotation=0&showTitle=false&size=65322&status=done&style=none&taskId=u74614c23-2493-411e-87ce-726a91b9e34&title=&width=1351.2)
<a name="ICxgM"></a>
## 7.4、自定义docker0网络
<a name="gAGRq"></a>
### 7.4.1、移除原有网络
<a name="j9XHn"></a>
#### 7.4.1.1、安装btctl命令
```bash
yum install -y bridge-utils
```
<a name="gBzIx"></a>
#### 7.4.1.2、查询网桥信息
```bash
brctl  show
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659762023826-98544de6-568b-4e09-956d-03c2f5e9d48d.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=175&id=ube51530a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=219&originWidth=779&originalType=binary&ratio=1&rotation=0&showTitle=false&size=22987&status=done&style=none&taskId=u5269b4d2-2916-4846-ae6b-48826e23f85&title=&width=623.2)
<a name="vu327"></a>
#### 7.4.1.3、关闭docker服务
```bash
systemctl stop docker
```
<a name="zSeUH"></a>
#### 7.4.1.4、停止docker0网桥
```bash
ip link set dev docker0 down
```
<a name="DAALj"></a>
#### 7.4.1.5、删除docker0网桥
```bash
brctl delbr docker0
```
<a name="WV2Dq"></a>
#### 7.4.1.6、查询所有网桥信息
```bash
brctl show
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659762074029-a4c3cfcd-34fa-4f03-bf4f-24fab07017f1.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=138&id=u89b442c4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=172&originWidth=774&originalType=binary&ratio=1&rotation=0&showTitle=false&size=12239&status=done&style=none&taskId=u1719ff94-6584-4d4a-b424-38706fc8eab&title=&width=619.2)
<a name="zxhkr"></a>
### 7.4.2、自定义新网络
<a name="dlRNG"></a>
#### 7.4.2.1、创建新网桥bridge0
```bash
brctl addbr bridge0
```
<a name="nBMLW"></a>
#### 7.4.2.2、查询创建的bridge0
```bash
brctl show
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659762111508-4d0d4ef9-9ebf-45dd-81b3-8bdb1c04c9c4.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=123&id=u2833aadc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=154&originWidth=723&originalType=binary&ratio=1&rotation=0&showTitle=false&size=16976&status=done&style=none&taskId=u30b97521-7a9d-41b9-abea-94699e5af18&title=&width=578.4)
<a name="OYUVZ"></a>
#### 7.4.2.3、设置新网桥的网络段地址
```bash
ip addr add 192.168.0.1/24 dev bridge0
```
<a name="tp3ji"></a>
#### 7.4.2.4、启动bridge0网桥
```bash
ip link set dev bridge0 up
```
<a name="GHEJQ"></a>
#### 7.4.2.5、查询bridge0网桥信息
```bash
ifconfig bridge0
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659762165196-e45dde2b-4e0b-47e4-9b68-9d73f2394c62.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=307&id=u6be17c9e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=384&originWidth=810&originalType=binary&ratio=1&rotation=0&showTitle=false&size=54361&status=done&style=none&taskId=u335c8683-223d-4417-b8e8-acb17a3fefc&title=&width=648)
<a name="QNY5l"></a>
#### 7.4.2.6、添加新网桥到配置文件
```bash
vi /etc/sysconfig/docker
# 添加 -b=bridge0 到 OPTIONS 中
OPTIONS='-b=bridge0'

```
<a name="BAKJP"></a>
#### 7.4.2.7、加载配置文件，重启docker服务
```bash
systemctl daemon-reload
systemctl restart docker
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659762269420-02a3dd09-44fb-459e-a7f9-8fbcdceec321.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=329&id=ud4383cba&margin=%5Bobject%20Object%5D&name=image.png&originHeight=411&originWidth=751&originalType=binary&ratio=1&rotation=0&showTitle=false&size=55729&status=done&style=none&taskId=u4492c82a-6adf-4447-9e12-45af9a0c231&title=&width=600.8)


<a name="aOVZC"></a>
### 7.4.3、使用新网络部署应用
<a name="NV6du"></a>
#### 7.4.3.1、创建一个nginx容器
```bash
docker run -dit --name nginx-net nginx
```
<a name="K2rLc"></a>
#### 7.4.3.2、查看容器的状态
```bash
docker ps -a
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659762409925-20bd985e-be97-4717-ae22-594b0cc34d7f.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=222&id=u5c839099&margin=%5Bobject%20Object%5D&name=image.png&originHeight=278&originWidth=1689&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58991&status=done&style=none&taskId=u8aaf1349-c5aa-430d-87fa-fafa54cecdc&title=&width=1351.2)
<a name="Ml4oQ"></a>
#### 7.4.3.3、查看容器的bridge
```bash
docker inspect -f {{.NetworkSettings.Networks.bridge}} nginx-net
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659762371582-e371ef41-8e5f-4c49-99bb-15374acc1136.png#clientId=u45dad7f1-3b57-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=109&id=u975dc73d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=136&originWidth=1720&originalType=binary&ratio=1&rotation=0&showTitle=false&size=26592&status=done&style=none&taskId=u3d3a1a51-fb25-4e36-88d1-25882c4b372&title=&width=1376)
<a name="Ti9Y8"></a>
# 8、Nginx负载均衡(轮询)
<a name="CxcE9"></a>
## 8.1、创建测试网页
```bash
# 创建web1文件夹 以及页面
mkdir /root/web1
echo "This is website 1 Page 11111111111111111" > /root/web1/index.html

# 创建web2文件夹 以及页面
mkdir /root/web2
echo "This is website 2 Page 22222222222222222" > /root/web2/index.html
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659770617871-bd3391bc-3c0a-44ee-95d3-2147bbc3ea52.png#clientId=u7a5576a2-b3cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=258&id=uf6709375&margin=%5Bobject%20Object%5D&name=image.png&originHeight=322&originWidth=693&originalType=binary&ratio=1&rotation=0&showTitle=false&size=47047&status=done&style=none&taskId=u9f2d6add-f985-4476-92fb-8c1260c4f4e&title=&width=554.4)
<a name="v7Rbq"></a>
## 8.2、创建测试容器 nginx1 nginx2
```bash
# 创建nginx1容器挂载 web1页面
docker run -dit --name nginx1 -v /root/web1/index.html:/usr/share/nginx/html/index.html -p 8091:80 nginx
# 创建nginx2容器挂载 web2页面
docker run -dit --name nginx2 -v /root/web2/index.html:/usr/share/nginx/html/index.html -p 8092:80 nginx
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659770677929-88cd3c80-d8f4-4f94-9d46-26cfc89261ab.png#clientId=u7a5576a2-b3cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=245&id=ue6013c6d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=306&originWidth=1398&originalType=binary&ratio=1&rotation=0&showTitle=false&size=59041&status=done&style=none&taskId=u323145a4-c033-4330-9b59-6544f7a7910&title=&width=1118.4)
<a name="x7XVK"></a>
## 8.3、创建nginx.conf配置文件
:::info
配置文件中的 172.31.36.113 为宿主机的内网IP地址，请按实际情况修改
:::
```bash
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;




events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;


    include /etc/nginx/conf.d/*.conf;
# 定义Tomcat服务的负载均衡
upstream tomcat_alb {

    server 172.31.36.113:8091;

    server 172.31.36.113:8092;

}
server {
    listen       80;
    server_name  172.31.36.113;#宿主机的内网IP

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;
# 这个是调用Tomcat服务的负载均衡
    location / {
        proxy_pass http://tomcat_alb;
    }
}
}

```

<a name="h4Vpi"></a>
## 8.4、创建nginx负载均衡容器
```bash
# -v 标记挂载本地的 /root/nginx.conf 文件
docker run -dit --name nginx-alb -v /root/nginx.conf:/etc/nginx/nginx.conf -p 80:80 nginx

```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659770797203-ce04dc59-c54e-40a4-9304-fa0aa737b76c.png#clientId=u7a5576a2-b3cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=135&id=udead61c2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=169&originWidth=1552&originalType=binary&ratio=1&rotation=0&showTitle=false&size=39421&status=done&style=none&taskId=u77295aef-03d2-4f10-83f1-64ca8ba6e78&title=&width=1241.6)

<a name="z2cgn"></a>
## 8.5、负载测试
```bash
# 循环测试
for i in `seq 1 6`;do curl 172.31.36.113;done
```
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2207808/1659770832552-e88b6b51-6bd0-4cef-92c5-27b07ec03791.png#clientId=u7a5576a2-b3cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=159&id=u636dce1f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=199&originWidth=803&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18743&status=done&style=none&taskId=u9dce26b9-1bb8-481e-be55-e236850f2e7&title=&width=642.4)







<a name="odWS8"></a>
##