> ## Content Index
> Fetch the complete content index at: https://www.richarvin.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Docker学习笔记（基础篇）二
- URL: https://www.richarvin.com/docker-xue-xi-bi-ji-ji-chu-pian-er/
- Published: 2024-03-10T04:00:14.000Z
- Updated: 2024-05-22T02:53:38.000Z
- Author: Richarvin
- Tags: 编程技术

## 一、Docker 镜像的使用

---

镜像是docker容器运行的基础，如果没有对应的镜像，则无法创建容器实例运行。

### 查找本地镜像：

使用 **docker images** 来列出本地主机上的镜像：

![](https://picture.richarvin.com/202403/xnip2024-03-10_09-31-55.webp)

- REPOSITORY:  
指的是镜像的仓库名称，通常由组织或个人创建并维护。例如hello-world镜像的仓库名称为hello-world。仓库名称可以包含多个部分，由/分隔。例如jc21/nginx-proxy-manager也是一个有效的仓库名称。
- TAG:  
指的是镜像的标签，用于标识镜像的特定版本或变体。例如hello-world:latest 镜像表示最新版本的hello-world镜像。你也可以为同一个基础镜像指定发布多个版本的标签。
- IMAGE ID:  
指的是镜像的唯一标识符，是一个由12个字符组成的字符串。可以使用IMAGE ID来检索或删除镜像。
- CREATED:  
指的是镜像的创建时间，以UTC时间格式表示。
- SIZE:  
指的是镜像的大小，以字节为单位。

注意：如果你看见一个镜像没有名称（REPOSITORY为none）并且TAG也是none的时候，这个镜像就是“虚悬镜像”，虚悬镜像主要是在构建或删除镜像失败时产生的，平时最好定期删除那些虚悬镜像，否则后续会引起一定的故障。

### 删除虚悬镜像

```bash
docker image rm $(docker images -f dangling=true -q)
```

### 查找docker hub官网上的镜像

使用 “**docker search 镜像名称”**

![](https://picture.richarvin.com/202403/xnip2024-03-10_11-25-41.webp)

- NAME: 镜像仓库源的名称；
- DESCRIPTION: 镜像的描述；
- OFFICIAL: 是否 docker 官方发布；
- STARS: 类似 Github 里面的 star，表示点赞、喜欢的意思；
- AUTOMATED: 自动构建；

### 获取一个新的镜像(带具体版本)

使用 **"docker pull 镜像名称:版本号"**  来拉取指定镜像版本，并查看当前机器上已有的所有镜像文件信息：

![](https://picture.richarvin.com/202403/xnip2024-03-10_09-48-51.webp)

### 运行一个指定的镜像，但无交互

```bash
docker run -d ubuntu:20.04
```

### 运行一个指定的镜像并有交互行为

```bash
docker run -d -it ubuntu:20.04 /bin/bash
```

参数说明：  
\-d: 指的是以守护进程模式运行容器并在后台运行。  
\-it: 指的是为容器分配一个伪输入终端。允许用户在容器内输入命令。  
/bin/bash：在此示例中，将在容器内运行 bash shell。

以下是命令的执行过程:

> 1.Docker 首先会检查本地是否存在 ubuntu:20.04 镜像。  
> 2.如果镜像不存在，Docker 会从 Docker Hub 下载镜像。  
> 3.Docker 会创建一个新的容器，并使用 ubuntu:20.04 镜像作为基础镜像。  
> 4.Docker 会在容器内启动 bash shell。  
> 5.用户可以输入命令并在容器内执行操作。

然后使用 **"docker ps"查看当前已经运行的容器。**

### 镜像创建

当你为一些基础镜像添加了额外的新功能后，可以使用 "docker commit -m="has update" -a="myname" 容器ID myname/ubuntu:v1.0"制作一个新的镜像。

参数说明：

- commit：制作一个新的镜像；
- \-m: 为新镜像添加注释，内容为“has update”，比方说可以说明该镜像添加了什么功能；
- \-a: 镜像作者；
- 容器ID：通过docker ps查询获取；
- myname/ubuntu:v1.0: 镜像作者/新镜像名称:自定义镜像版本号；

![](https://picture.richarvin.com/202403/xnip2024-03-10_10-34-51.webp)

## 二、容器操作

---

### 启动一个容器

使用 **"**docker run -d --name 自定义容器名称 镜像名称:版本号"

![](https://picture.richarvin.com/202403/xnip2024-03-10_11-03-46.webp)

基于指定镜像分别启动两个自定义名称的容器

![](https://picture.richarvin.com/202403/xnip2024-03-10_11-06-20.webp)

同一镜像不同容器、容器ID也不相同

### 进入容器

```bash
docker exec -it 容器ID /bin/bash
```

### 数据持久化共享同步

```bash
#将宿主机的目录或文件绑定到容器内的指定目录，实现宿主机和容器之间的数据同步。
docker run -v /宿主机绝对路径目录:/容器内目录 -d 镜像名

#容器内的文件变动后，会实时同步到宿主机的目录中，反之亦然。如果容器意外停止或者宕机后，宿主机中的文件做了改动后，容器修复再次上线后，宿主机内的变更会同步到容器中；在分布式集群中，例如在三主三从架构中，如果一台宿主机发生故障，依赖于配置的高可用性解决方案，系统可以自动将流量转移到健康的节点上。在宿主机恢复并重新上线后，新启动的实例会作为集群的一部分，自动开始从其它存活的节点同步数据，直到完全恢复到最新状态。
```

### 停止容器运行

```bash
docker stop 容器ID
```

### 重启容器运行

```bash
docker restart 容器 ID
```

### 容器查看

```bash
#输出一个JSON对象，显示容器的ID、镜像、创建时间、运行状态、网络配置、端口映射、环境变量、卷信息等
docker inspect 容器ID

```

### 容器日志查看

```bash
docker logs 容器ID
```

### 查看容器中正在运行的进程信息

```bash
#显示该容器中正在运行进程的ID、用户、CPU 使用率、内存使用率、进程的命令行
docker top 容器ID

#注意：容器运行时不一定有/bin/bash终端来交互执行top命令，而且容器还不一定有top命令，可以使用docker top来实现查看container中正在运行的进程。
```

### 容器的导入导出

Docker容器的导入和导出主要涉及两对命令：docker export与docker import，以及docker save与docker load。这两对命令在使用场景和目的上有所不同。

### *1、docker export和docker import*

**`docker export`**：此命令用于将运行中的容器的文件系统导出为一个tar包。这个命令不会包括容器的元数据（如环境变量、默认命令等），只包括文件系统:

```bash
sudo docker export <容器ID或名称> -o <导出文件名>.tar

```

例如导出名为`my_container`的容器：

```bash
sudo docker export my_container -o my_container.tar

```

**`docker import`**：此命令用于从一个tar包创建一个Docker镜像。可以通过修改tar包中的内容来更改镜像的文件系统。导入的镜像不包含任何历史或层次信息:

```bash
cat <导出文件名>.tar | sudo docker import - <新镜像名>:<标签>

```

或者直接使用文件路径：

```bash
sudo docker import <导出文件名>.tar <新镜像名>:<标签>

```

比如从`my_container.tar`导入镜像，并命名为`new_image:latest`：

```bash
sudo docker import my_container.tar new_image:latest

```

### *2、docker save和docker load*

`**docker save**`：此命令用于将一个或多个镜像保存到一个tar包中。与`docker export`不同，`docker save`包含了镜像的元数据和所有层次信息：

```bash
sudo docker save -o <保存文件名>.tar <镜像名>:<标签>

```

比如保存ubuntu:20.04镜像：

```bash
sudo docker save -o ubuntu_20.04.tar ubuntu:20.04

```

**`docker load`**：此命令用于从一个tar包中加载一个镜像，包括镜像的元数据和所有层次信息:

```bash
sudo docker load -i <保存文件名>.tar

```

比如加载ubuntu\_20.04.tar包中的镜像：

```bash
sudo docker load -i ubuntu_20.04.tar

```

![](https://picture.richarvin.com/202403/xnip2024-03-10_11-54-38.webp)

### 强制删除容器(一次一个)

```bash
docker rm -f 容器ID
```

### 强制删除容器(一次多个)

```bash
#强制删除指定的容器，即使容器正在运行，也会将其删除
docker rm -f 容器ID 容器ID 容器ID

#强制删除所有容器，包括正在运行和已停止的容器
docker rm -f $(docker ps -a -q)

#注意区别：两种删除方式，前者更具可控性，而后者更具破坏性。
```

### 删除所有已经处于停止运行的容器

```bash
docker container prune
```

## 三、Docker网络

---

在我们安装完Docker后，它会自动创建三个网络。你可以使用以下 docker network ls命令列出这些网络：

- bridge：所有未指定网络的容器都会连接到这个网络。在这种模式下，容器可以通过内部IP地址相互通信，但需要端口映射才能从外部访问容器。
- host：容器共享宿主机的网络命名空间，不进行网络隔离。这意味着容器直接使用宿主机的IP和端口。
- none：容器将不会被分配网络接口，实际上是网络隔离的。

```bash
#运行nginx容器时指定bridge网络
docker run --network=bridge -d nginx

#运行nginx容器时指定host网络
docker run --network=host -d nginx

#运行nginx容器时禁用网络
docker run --network=none -d nginx

```

> 在Docker的bridge网络中，默认的IP地址分配是动态的，并非是持久的。一旦某台机器宕机或者意外挂起，重启后不会再是原先的IP地址，除非你绑定（但实际生成环境中并不建议绑定IP这样的操作）。一是维护成本大，二是一旦IP地址变动后，原先的服务将变得不可用。这个时候往往可以通过自己创建一个网络，虽然默认驱动也是bridge，但是自己创建的网络本身就维护好了主机名和ip的对应关系（ip和域名都能访问），那么后续服务就可以通过域名去访问，避免了因为ip变更而出现的困扰。

### 自定义网络

```bash
docker network creat 自定义网络名称
```

### 将容器添加到自定义网络中

```bash
#以容器nginx为例，在启动时运行如下命令
docker run --name my_nginx --network my_custom_network -d nginx

#参数说明
#--name my_nginx：my_nginx是你给容器指定的别名，用于Docker内部的引用，可以帮助你轻松地识别、管理和引用不同的容器；
#my_custom_network：前面自定义网络的名称；
#末尾的nginx：你从docker hub下载的基础镜像，或者是你自己自定义的镜像模版
```

### host网络

当使用host网络模式时，容器的网络隔离特性将会失去，而是会直接使用宿主机的网络：包括IP地址和端口号。由于容器使用的是宿主机的网络，所以容器内应用绑定的端口直接映射到宿主机上。如果容器尝试绑定一个已经被宿主机上其他应用或其他容器使用的端口，那么它就会无法启动。所以你需要检查容器使用的端口在宿主机上是否被占用。更重要的是，在该模式下恶意容器可能更容易访问宿主机网络上的服务和数据。