目录
- [1 Docker简介](#1 Docker简介)
- [2 容器和虚拟机的区别](#2 容器和虚拟机的区别)
- [3 Docker官方架构](#3 Docker官方架构)
- [4 Docker核心组件](#4 Docker核心组件)
-
- [4.1 Docker Registry(镜像仓库)](#4.1 Docker Registry(镜像仓库))
-
- [4.1.1 什么是 Docker Registry](#4.1.1 什么是 Docker Registry)
- [4.1.2 镜像仓库分类及工作机制](#4.1.2 镜像仓库分类及工作机制)
- [4.1.3 镜像仓库命令](#4.1.3 镜像仓库命令)
- [4.2 Docker Image(镜像)](#4.2 Docker Image(镜像))
-
- [4.2.1 什么是 Docker Image](#4.2.1 什么是 Docker Image)
- [4.2.2 为什么需要镜像](#4.2.2 为什么需要镜像)
- [4.2.3 镜像常用命令](#4.2.3 镜像常用命令)
- [4.3 Docker Container(容器)](#4.3 Docker Container(容器))
-
- [4.3.1 什么是容器](#4.3.1 什么是容器)
- [4.3.2 容器的生命周期](#4.3.2 容器的生命周期)
- [4.3.3 容器OOM](#4.3.3 容器OOM)
- [4.3.4 容器异常退出](#4.3.4 容器异常退出)
- [4.3.5 容器暂停状态和停止状态的区别](#4.3.5 容器暂停状态和停止状态的区别)
- [4.3.6 容器常用命令](#4.3.6 容器常用命令)
- [4.4 Docker Volume(存储卷)](#4.4 Docker Volume(存储卷))
-
- [4.4.1 什么是存储卷](#4.4.1 什么是存储卷)
- [4.4.2 存储卷的作用](#4.4.2 存储卷的作用)
- [4.4.3 存储卷的分类及常用命令](#4.4.3 存储卷的分类及常用命令)
-
- [4.4.3.1 命名卷(Named Volume)](#4.4.3.1 命名卷(Named Volume))
- [4.4.3.2 匿名卷(Anonymous Volume)](#4.4.3.2 匿名卷(Anonymous Volume))
- [4.4.3.3 绑定挂载(Bind Mount)](#4.4.3.3 绑定挂载(Bind Mount))
- [4.5 Docker Network(网络)](#4.5 Docker Network(网络))
-
- [4.5.1 Docker 网络架构简介](#4.5.1 Docker 网络架构简介)
-
- [4.5.1.1 CNM](#4.5.1.1 CNM)
- [4.5.1.2 Libnetwork](#4.5.1.2 Libnetwork)
- [4.5.1.3 驱动](#4.5.1.3 驱动)
- [4.5.2 常见的网络类型](#4.5.2 常见的网络类型)
- [4.5.3 Docker网络管理常用命令](#4.5.3 Docker网络管理常用命令)
- 写在最后
1 Docker简介
Docker是一款基于操作系统层级虚拟化技术的开源平台即服务产品,用于开发、交付和运行应用程序。其核心是将软件及其依赖项打包为轻量级的容器,这些容器由Docker引擎托管。
容器技术使开发者能够在Windows、macOS和Linux系统上,将应用程序及其依赖项打包至一个独立的运行环境中。这些容器彼此隔离,但可通过特定通道通信,且能在任何支持Docker的环境中一致地运行。由于所有容器共享主机操作系统内核,避免了启动与维护完整虚拟机的开销,因此相比于传统虚拟机,Docker容器更加轻便、快速且易于部署。

为什么需要 Docker?
| 传统方式(不推荐) | Docker 方案 |
|---|---|
| 用 VirtualBox 创建虚拟机 → 安装 OS → 配置环境 → 启动应用 | 直接运行一个"轻量级沙盒"(500MB 内存 vs 虚拟机 2GB+) |
| 每次部署要重复配置环境(如 Python 3.9、MySQL) | 一次打包,到处运行(CentOS 10 服务器、Windows、Mac 都能用) |
| 项目依赖冲突(如 Python 3.9 和 Python 3.10 混用) | 隔离环境(应用只用自己需要的依赖) |
一句话总结:
Docker 是让应用"轻量级打包+运行"的工具,本质是 "容器技术",帮你把应用(代码+依赖)打包成可移植的"沙盒"。
2 容器和虚拟机的区别
容器是轻量级的操作系统级虚拟化技术,共享宿主机内核,启动快、资源占用低;虚拟机是系统级虚拟化技术,运行完整独立操作系统,隔离性强但资源消耗大。
| 对比维度 | 虚拟机 | 容器 |
|---|---|---|
| 隔离性与安全性 | 系统级隔离(Hypervisor),独立内核 / OS,强安全边界 | 进程级隔离(Namespace+Cgroup),共享宿主机内核,安全性较弱 |
| 资源占用 | 完整操作系统,GB 级存储,CPU / 内存开销大 | 仅含应用依赖,MB 级存储,资源开销极小 |
| 封装程度 | 打包整个操作系统 | 打包项目代码和依赖信息 |
| 启动速度 | 分钟级(需加载完整 OS) | 秒级(直接调用宿主机进程) |
| 性能损耗 | 虚拟化层额外消耗约 5% 性能 | 接近原生性能 |
| 操作系统兼容性 | 支持任意 OS,可 Windows/Linux 混合部署 | 需与宿主机 OS 版本兼容,依赖同内核 |
3 Docker官方架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。 Docker 容器通过 Docker 镜像来创建。

Docker架构主要由以下几个核心组件构成:
- Docker 客户端 (Docker Client)
○ 用户与Docker交互的主要接口。用户通过命令行界面或Docker API与Docker守护进程(daemon)通信。 - Docker 守护进程 (Docker Daemon)
○ 运行在主机上的后台服务,负责构建、运行、分发Docker容器。守护进程监听Docker API的请求并管理Docker对象如镜像(images)、容器(containers)、网络(networks)和卷(volumes)。 - Docker 镜像 (Docker Images)
○ Docker镜像是一个轻量级、可执行的独立软件包,它包括运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。镜像被用来创建Docker容器。 - Docker 容器 (Docker Containers)
○ 容器是镜像的运行实例。它可以被启动、停止、删除。每个容器都是相互隔离的,并且可以认为是轻量级的虚拟机。 - Docker 仓库 (Docker Registries)
○ Docker仓库用于存储Docker镜像,可以是公开的也可以是私有的。最著名的公共仓库是Docker Hub,它托管了大量的官方和用户创建的镜像。 - Docker 网络 (Docker Networks)
○ Docker网络允许容器之间以及容器与外部世界之间的通信。它提供了多种网络模式,如桥接网络、主机网络、覆盖网络等。 - Docker 卷 (Docker Volumes)
○ 卷是用于持久化数据、共享数据或将数据从容器持久化到宿主机上的机制。卷可以用于数据库存储和其他需要持久化数据的场景。
4 Docker核心组件
4.1 Docker Registry(镜像仓库)
4.1.1 什么是 Docker Registry
镜像仓库 (Docker Registry) 负责存储、管理和分发镜像,并且提供了登录认证能力, 建立了仓库的索引。 镜像仓库管理多个 Repository, Repository 通过命名来区分。每个 Repository 包含一个或多个镜像,镜像通过镜像名称和标签 (Tag)来区分。

一个容器镜像包含了两个部分,一个是元数据,其实就是由 dockerfile 构建出来的描述文件,这个描述文件会说这个容器镜像有多少层,每一层里面有什么内容,它的 checksum 这些信息都会记录下来,还有最终的可执行文件在哪就是在存储数据里面, 就是在一个一个的 blob 里面,真正占有空间的就是这些 blob。
怎么理解呢?
超市货架用来存放和展示商品,顾客可以从中选择购买。我们可以将 Docker 仓库类比为超市货架:
- 货架(仓库):存放商品的区域。在 Docker 世界里,仓库就是存放 Docker 镜像的地方。
- 商品(镜像):超市中的商品对应于 Docker 中的镜像,是预先打包好的软件应用。
- 分类与标签:超市中的商品会按类别(如食品、日用品)和品牌(如可口可乐、百事可乐)分类。在 Docker 中,镜像可以有不同的标签(tag),用于区分不同的版本或配置。
- 上架与下架:超市上架新商品,下架旧商品。在 Docker 中,开发者会推送新的镜像版本到仓库,旧的版本可以被标记为过时或删除。
4.1.2 镜像仓库分类及工作机制
按是否对外开放划分
- 公有仓库:像阿里云、dockerhub 等放到公有网络上,不用登录就可以下载镜像, 供大家访问使用
- 私有仓库:不对外开放,往往位于私有网络,只有公司内部人员可以使用。
按供应商和面向群体划分
- sponsor(赞助)registry:第三方的 registry,供客户和 docker 社区版使用
- mirror(镜像)registry:第三方的 registry,只让客户使用,例如阿里云必须注册才能使用
- vendor(供应商)registry:由发布 docker 镜像的供应商提供的 registry,例如像 Google 和 Redhat 提供了镜像仓库服务
- private registry:通过没有防火墙和额外的安全层的私有实体提供的 registry,仅供内部使用
启动容器时,docker daemon 会试图从本地获取相关的镜像;本地镜像不存在时,其将 从 Registry 中下载该镜像并保存到本地。
4.1.3 镜像仓库命令
| 命令 | 功能 | 语法 | 样例 |
|---|---|---|---|
| docker login | 登录镜像仓库(Docker Hub / 私有仓库) | docker login [OPTIONS] [SERVER] | 1. 登录 Docker Hub:docker login 2. 登录私有仓库:docker login registry.example.com:5000 3. 免交互登录:docker login -u username -p password registry.example.com:5000 |
| docker logout | 退出已登录的镜像仓库 | docker logout [SERVER] | 1. 退出 Docker Hub:docker logout 2. 退出私有仓库:docker logout registry.example.com:5000 |
| docker pull | 从镜像仓库拉取镜像到本地 | docker pull [OPTIONS] NAME[:TAG@DIGEST] | 1. 拉取最新版:docker pull nginx:latest 2. 拉取指定版本:docker pull nginx:1.25 3. 拉取私有仓库镜像:docker pull registry.example.com:5000/my-app:v1.0 |
| docker push | 将本地镜像推送到镜像仓库 | docker push [OPTIONS] NAME[:TAG] | 1. 推送 Docker Hub:docker tag my-app:v1.0 username/my-app:v1.0 docker push username/my-app:v1.0 2. 推送私有仓库:docker tag my-app:v1.0 registry.example.com:5000/my-app:v1.0 docker push registry.example.com:5000/my-app:v1.0 |
| docker search | 搜索 Docker Hub 中的镜像 | docker search [OPTIONS] TERM | 1. 基础搜索:docker search nginx 2. 过滤官方镜像:docker search --filter "is-official=true" nginx 3. 过滤星级≥10 的镜像:docker search --filter "stars=10" nginx |
4.2 Docker Image(镜像)
4.2.1 什么是 Docker Image
Docker image 本质上是一个 read-only 只读文件, 这个文件包含了文件系统、 源码、库文件、依赖、工具等一些运行 application 所必须的文件。
我们可以把 Docker image 理解成一个模板, 可以通过这个模板实例化出来很多容器。
image 里面是一层层文件系统 Union FS。联合文件系统,可以将几层目录挂载到一起,形成一个虚拟文件系统。
每一层文件系统我们叫做一层 layer,联合文件系统可以对每一层文件系统设置三 种权限,只读(readonly)、读写(readwrite)和写出(whiteout-able),但是 docker 镜像中每一层文件系统都是只读的。
构建镜像的时候,从一个最基本的操作系统开始,每个构建的操作都相当于做一层的修改,增加了一层文件系统。一层层往上叠加,上层的修改会覆盖底层该位置的可见性,这也很容易理解,就像上层把底层遮住了一样。当你使用的时候,你只会看到一个完全的整体,你不知道里面有几层,也不清楚每一层所做的修改是什么。
怎么理解呢?
在理解Docker镜像(Image)的概念时,我们可以将其类比于面向对象编程中的"类"概念, 可以很方便的构建出来不同的对象。

4.2.2 为什么需要镜像
在传统部署方式里,我们要么手动部署,要么自己写脚本部署。这种方式最大的问题就是:本地环境、测试环境、云端环境等很难保持完全一致。 而且,每个应用都要自己打包、配置、反复修改,流程非常繁琐、容易出错。
Docker 镜像就是为了解决这些问题才火起来的。可以把它简单理解成一个 "超级压缩包",但它不只是压缩文件 ------它把应用 + 依赖 + 配置 + 完整操作系统文件和目录结构全部打包在一起。这样一来,不管是在你本地、测试环境,还是上云部署,环境都是一模一样的 ,从根本上解决了 PaaS 时代 "本地能跑、线上不行" 的一致性问题。
Docker 最核心的贡献,是定义了一套标准化的容器镜像分层存储格式 。它的底层依赖 UnionFS(联合文件系统) ,让镜像可以一层一层叠加:
- 相同的层可以共享复用
- 不用重复存储
- 既节省空间,又提升构建和传输效率
简单说,Docker 镜像提供了一种极其便捷的方式:把应用和运行环境一次性打包好,既能自己用,也能轻松分享给别人,真正实现 "一次打包,到处运行"。
4.2.3 镜像常用命令
| 命令 | 功能 | 语法 | 样例 |
|---|---|---|---|
| docker images | 列出本地已有的镜像 | docker images [OPTIONS] [REPOSITORY[:TAG]] | 1. 列出所有镜像:docker images 2. 列出指定仓库镜像:docker images nginx 3. 只显示镜像 ID:docker images -q |
| docker tag | 为本地镜像打标签(重命名 / 指定仓库) | docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] | 1. 基础打标:docker tag nginx:latest my-nginx:v1.0 2. 为推送仓库打标:docker tag nginx:latest registry.example.com:5000/nginx:v1.0 |
| docker pull | 从镜像仓库拉取镜像到本地 docker pull [OPTIONS] NAME[:TAG | @DIGEST] | 1. 拉取最新版:docker pull nginx:latest 2. 拉取指定版本:docker pull nginx:1.25 3. 拉取私有仓库镜像:docker pull registry.example.com:5000/my-app:v1.0 |
| docker push | 将本地镜像推送到镜像仓库 | docker push [OPTIONS] NAME[:TAG] | 1. 推送 Docker Hub:docker push username/my-app:v1.0 2. 推送私有仓库:docker push registry.example.com:5000/my-app:v1.0 |
| docker rmi | 删除本地指定的镜像 | docker rmi [OPTIONS] IMAGE [IMAGE...] | 1. 删除指定镜像:docker rmi nginx:v1.0 2. 强制删除(镜像被容器使用时):docker rmi -f nginx:v1.0 3. 删除多个镜像:docker rmi nginx:v1.0 mysql:8.0 |
| docker save | 将镜像保存为 tar 文件(离线导出) | docker save [OPTIONS] IMAGE [IMAGE...] | 1. 保存单个镜像:docker save -o nginx-v1.0.tar nginx:v1.0 2. 保存多个镜像:docker save -o app-images.tar nginx:v1.0 mysql:8.0 |
| docker load | 从 tar 文件导入镜像到本地 | docker load [OPTIONS] | 1. 从文件导入:docker load -i nginx-v1.0.tar 2. 从管道导入:``cat /tmp/nginx-v1.0.tar |
| docker inspect | 查看镜像(或容器)的详细元数据 | docker inspect [OPTIONS] NAME/ID [NAME/ID...] | 1. 查看镜像详情:docker inspect nginx:latest 2. 只查看镜像 ID:docker inspect -f '{{.Id}}' nginx:latest |
| docker history | 查看镜像的分层构建历史 | docker history [OPTIONS] IMAGE | 1. 查看镜像历史:docker history nginx:latest 2. 显示完整命令(不截断):docker history --no-trunc nginx:latest |
| docker import | 从本地 tar 文件 / URL 导入镜像(与 load 不同) | docker import [OPTIONS] file/URL/- [REPOSITORY[:TAG]] | 1. 从 tar 文件导入:docker import nginx.tar my-nginx:v1.0 2. 从 URL 导入:docker import https://example.com/nginx.tar my-nginx:v1.0 |
| docker image prune | 清理本地未使用的镜像(悬空 / 无标签镜像) | docker image prune [OPTIONS] | 1. 清理悬空镜像:docker image prune 2. 清理所有未使用镜像(含未运行容器的镜像):docker image prune -a 3. 免交互清理:docker image prune -a -f |
| docker build | 从 Dockerfile 构建镜像 | docker build [OPTIONS] PATH/URL/- | 1. 基础构建:docker build -t my-app:v1.0 ./ 2. 指定 Dockerfile:docker build -t my-app:v1.0 -f ./Dockerfile.prod ./ 3. 无缓存构建:docker build --no-cache -t my-app:v1.0 ./ |
4.3 Docker Container(容器)
4.3.1 什么是容器
通俗地讲,容器是镜像的运行实体。镜像是静态的只读文件,而容器带有运行时需要的可写文件层,并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容 器有初建、运行、停止、暂停和删除五种状态 。
虽然容器的本质是主机上运行的一个进程,但是容器有自己独立的命名空间隔离和资源限制。也就是说,在容器内部,无法看到主机上的进程、环境变量、网络等信息, 这是容器与直接运行在主机上进程的本质区别 。
容器是基于镜像创建的可运行实例,并且单独存在,一个镜像可以创建出多个容器。 运行容器化环境时,实际上是在容器内部创建该文件系统的读写副本。 这将添加一个容器层,该层允许修改镜像的整个副本。
怎么理解呢?
容器(Container)则可以视为基于"类"创建出的"对象"。容器是动态的,你可以在容器中启动、停止、修改或删除应用,而这一切都不会影响底层的镜像。容器可以被创建、启动、停止、删除等操作。
4.3.2 容器的生命周期
容器的生命周期是容器可能处于的状态。
- created:初建状态
- running:运行状态
- stopped:停止状态
- paused: 暂停状态
- deleted:删除状态
各生命周期之间的转换关系如图所示:

4.3.3 容器OOM
Docker 在处理 OOM 事件时分为三种情况
(1)如果容器中的应用耗尽了主机系统分配给容器的内存限额,就会触发 OOM 事件。 例如,在容器当中,部署了一个 web 服务。假设主机分配给此容器的内存上限为 1G, 当脚本申请的内存大于 1G 时,此容器就会触发 OOM 事件。而在这种情况下,此容器将会被强制关闭。 但需要注意的是,此时关闭容器的并非是 Docker Daemon,而是宿主机操作系统。因为一个容器其实就是一组运行在宿主机操作系统当中的进程,宿主机操作系统通过 cgroups 对这组进程设定资源上限,当这些进程申请的资源到达上限时,触发的是宿主机操作系统的内核 OOM 事件,因此最终是由宿主机内核来关闭这些进程。
(2) 如果用户不想关闭这个容器,那么可以选择--oom-kill-disable 来禁用 OOM-Killer。 使用此参数时,仍需要注意,如果使用-m 设置了此容器内存上限,那么当容器到达内存资源上限时,主机不会关闭容器,但也不会继续向此容器继续分配资源,此时容器将处于 hung 状态。只需要将最坏的情况封闭在一定范围之内,而不至于蔓延出去。
(3)如果用户使用了--oom-kill-disable,但也没有使用-m 来设定上限,因而此时此容器将会尽可能多地使用主机内存资源。换言之,主机内存有多大,它就将用多大。
4.3.4 容器异常退出
每个容器内部都存在一个 Init 进程,容器中其他所有进程都是此进程的子进程。运行的容器是因为 Init 进程在运行,如果一个子进程因为某种原因造成了退出,那么其父进程也会同步退出,直至 Init 进程也退出。当 Init 进程退出时,也就代表着此容器被关闭。docker 目前没有办法知道此时的进程退出属于正常退出还是异常退出。当出现容器关闭情况时,Docker Daemon 会尝试再次重新将此容器由 Stopped 状态转为 Running 状态。只有设置了--restart 参数的容器,Docker Daemon 才会去尝试启动,否则容器会保持停止状态。
4.3.5 容器暂停状态和停止状态的区别
| 对比项 | 暂停状态(Pause) | 停止状态(Stop) |
|---|---|---|
| 本质操作 | 仅冻结进程,不终止 | 终止容器进程 |
| 容器进程是否存在 | 存在,只是被挂起 | 不存在,已退出 |
| 内存 / 运行时状态 | 保留内存、连接、上下文 | 释放内存,断开连接,清空运行状态 |
| 恢复启动速度 | 极快(直接解冻) | 较慢(需重新初始化、启动进程) |
| 容器是否仍在宿主机列表 | 是(docker ps -a 可见) | 是(docker ps -a 可见) |
| 对应 Docker 命令 | docker pause / unpause | docker stop / start |
| 典型用途 | 临时冻结、调试、资源临时避让 | 正常停机、重启、更新配置 |
| 对依赖服务影响 | 连接会超时但不断开 | 连接会断开 |
| 数据 / 日志 | 保留在内存中 | 写入磁盘,进程退出 |
4.3.6 容器常用命令
| 命令 | 功能 | 基本语法 | 实用样例 |
|---|---|---|---|
| docker create | 创建容器(仅创建,不启动) | docker create [OPTIONS] IMAGE [COMMAND] [ARG...] | docker create --name my-nginx nginx:alpine |
| docker run | 创建并启动容器(最常用) | docker run [OPTIONS] IMAGE [COMMAND] [ARG...] | docker run -d -p 8080:80 --name my-nginx nginx:alpine |
| docker ps | 查看容器列表 | docker ps [OPTIONS] | docker ps(查看运行中)docker ps -a(查看所有) |
| docker logs | 查看容器日志 | docker logs [OPTIONS] CONTAINER | docker logs -f my-nginx(实时跟踪日志) |
| docker attach | 附着到运行中的容器(共享终端) | docker attach [OPTIONS] CONTAINER | docker attach my-nginx |
| docker exec | 在运行中的容器执行命令(推荐) | docker exec [OPTIONS] CONTAINER COMMAND [ARG...] | docker exec -it my-nginx /bin/bash(进入容器终端) |
| docker start | 启动已停止的容器 | docker start [OPTIONS] CONTAINER [CONTAINER...] | docker start my-nginx |
| docker stop | 优雅停止容器(发送 SIGTERM 信号) | docker stop [OPTIONS] CONTAINER [CONTAINER...] | docker stop my-nginx |
| docker restart | 重启容器 | docker restart [OPTIONS] CONTAINER [CONTAINER...] | docker restart my-nginx |
| docker kill | 强制终止容器(发送 SIGKILL 信号) | docker kill [OPTIONS] CONTAINER [CONTAINER...] | docker kill my-nginx |
| docker top | 查看容器内运行的进程 | docker top CONTAINER [ps OPTIONS] | docker top my-nginx |
| docker stats | 实时查看容器资源占用(CPU / 内存等) | docker stats [OPTIONS] [CONTAINER...] | docker stats my-nginx(单容器)docker stats(所有容器) |
| docker container inspect | 查看容器详细元数据(JSON 格式) | docker container inspect [OPTIONS] CONTAINER [CONTAINER...] | docker container inspect my-nginx |
| docker port | 查看容器端口映射关系 | docker port CONTAINER [PRIVATE_PORT[/PROTO]] | docker port my-nginx |
| docker cp | 在主机和容器间复制文件 / 目录 | docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH | docker cp my-nginx:/etc/nginx/nginx.conf ./(容器→主机)docker cp ./test.txt my-nginx:/tmp/(主机→容器) |
| docker diff | 查看容器文件系统的修改(增 / 删 / 改) | docker diff CONTAINER | docker diff my-nginx |
| docker commit | 将容器修改提交为新镜像 | docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] | docker commit my-nginx my-nginx:v2 |
| docker pause | 暂停容器(冻结进程) | docker pause CONTAINER [CONTAINER...] | docker pause my-nginx |
| docker unpause | 恢复暂停的容器 | docker unpause CONTAINER [CONTAINER...] | docker unpause my-nginx |
| docker rm | 删除容器 | docker rm [OPTIONS] CONTAINER [CONTAINER...] | docker rm my-nginx(删除停止的)docker rm -f my-nginx(强制删除运行中的) |
| docker export | 将容器文件系统导出为 tar 包 | docker export [OPTIONS] CONTAINER | docker export my-nginx > nginx.tar |
| docker wait | 阻塞直到容器停止,返回退出码 | docker wait CONTAINER [CONTAINER...] | docker wait my-nginx |
| docker rename | 重命名容器 | docker rename CONTAINER NEW_NAME | docker rename my-nginx nginx-prod |
| docker container prune | 清理所有停止的容器(释放空间) | docker container prune [OPTIONS] | docker container prune -f(无需确认直接清理) |
| docker update | 更新容器运行时配置(资源限制等) | docker update [OPTIONS] CONTAINER [CONTAINER...] | docker update --memory 512m --cpus 0.5 my-nginx |
4.4 Docker Volume(存储卷)
4.4.1 什么是存储卷
存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。当我们在容器中的这个目录下写入数据时, 容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。
在宿主机上的这个与容器形成绑定关系的目录被称作存储卷。卷的本质是文件或者目 录,它可以绕过默认的联合文件系统,直接以文件或目录的形式存在于宿主机上。 宿主机的/data/web 目录与容器中的/container/data/web 目录绑定关系,然后容器中的进程向这个目录中写数据时,是直接写在宿主机的目录上的,绕过容器文件系统与宿主机的文件系统建立关联关系,使得可以在宿主机和容器内共享数据库内容,让容器直接访问宿主机中的内容,也可以宿主机向容器写入内容,容器和宿主机的数据读写是同步的。

4.4.2 存储卷的作用
- 数据丢失问题
容器按照业务类型,总体可以分为两类:
• 无状态的(数据不需要被持久化)
• 有状态的(数据需要被持久化)
显然,容器更擅长无状态应用。因为未持久化数据的容器根目录的生命周期与容器的
生命周期一样,容器文件系统的本质是在镜像层上面创建的读写层,运行中的容器对
任何文件的修改都存在于该读写层,当容器被删除时,容器中的读写层也会随之消失。
虽然容器希望所有的业务都尽量保持无状态,这样容器就可以开箱即用,并且可以任
意调度,但实际业务总是有各种需要数据持久化的场景,比如 MySQL、Kafka 等有状
态的业务。因此为了解决有状态业务的需求,Docker 提出了卷(Volume)的概念。 - 性能问题
UnionFS 对于修改删除等,一般效率非常低,如果对一于 I/O 要求比较高的应用,如
redis 在实现持化存储时,是在底层存储时的性能要求比较高。 - 宿主机和容器互访不方便
宿主机访问容器,或者容器访问要通过 docker cp 来完成,应用很难操作 - 容器和容器共享不方便
4.4.3 存储卷的分类及常用命令
Docker 的存储卷主要分为 3 大类,核心区别在于"谁来管理""数据存在哪"及"适用场景"。
| 分类 | 管理主体 | 数据存储路径 | 核心特点 | 适用场景 |
|---|---|---|---|---|
| 命名卷(Named Volume) | Docker 引擎 | /var/lib/docker/volumes/卷名/_data | Docker 统一管理,安全、易备份、跨容器共享 | 生产环境、持久化存储(如数据库数据) |
| 匿名卷(Anonymous Volume) | Docker 引擎 | /var/lib/docker/volumes/随机ID/_data | 无自定义名称,随容器创建 / 销毁(默认不删) | 临时存储、不想手动命名的场景 |
| 绑定挂载(Bind Mount) | 宿主机用户 | 宿主机任意路径(如/opt/mysql) | 直接映射宿主机目录,灵活但依赖宿主机路径 | 开发调试、宿主机文件共享 |
4.4.3.1 命名卷(Named Volume)
命名卷是由用户自定义名称、Docker 引擎统一管理的存储卷,数据默认存储在宿主机的/var/lib/docker/volumes/[卷名]/_data目录下。它完全与宿主机路径解耦,Docker 自动处理权限和生命周期,是生产环境中最常用的持久化方式,适合存储数据库、配置文件等需要长期保留的数据。
| 命令 | 功能 | 基本语法 | 实用样例 |
|---|---|---|---|
| docker volume create | 创建命名卷 | docker volume create [卷名] | docker volume create mysql-data(创建名为 mysql-data 的命名卷) |
| docker volume ls | 列出所有卷(含命名 / 匿名) | docker volume ls [可选参数] | docker volume ls(列出所有卷)docker volume ls -q(只显示卷名) |
| docker volume inspect | 查看卷的详细信息 | docker volume inspect [卷名] | docker volume inspect mysql-data(查看 mysql-data 的存储路径、驱动等) |
| docker run -v | 启动容器并挂载命名卷 | docker run -d -v [卷名]:[容器内路径] [镜像] | docker run -d --name mysql -v mysql-data:/var/lib/mysql mysql:5.7(挂载命名卷到 mysql 数据目录) |
| docker volume prune | 清理未被使用的卷(含命名 / 匿名) | docker volume prune [-f] | docker volume prune -f(强制清理所有未挂载的卷,避免数据残留) |
| docker volume rm | 删除指定命名卷 | docker volume rm [卷名] | docker volume rm mysql-data(删除 mysql-data 卷,需先停止使用该卷的容器) |
4.4.3.2 匿名卷(Anonymous Volume)
匿名卷是创建时不指定卷名、由 Docker 自动生成随机字符串作为标识的存储卷,数据同样存储在/var/lib/docker/volumes/[随机ID]/_data目录下。它随容器创建自动生成,容器删除时默认不会被清理(需手动 prune),适合临时存储、测试环境,或不想手动命名的场景(比如临时挂载容器日志目录)。
| 命令 | 功能 | 基本语法 | 实用样例 |
|---|---|---|---|
| docker run -v | 启动容器并创建匿名卷 | docker run -d -v [容器内路径] [镜像] | docker run -d --name nginx -v /usr/share/nginx/html nginx(为 nginx 静态目录创建匿名卷) |
| docker volume ls | 列出卷 | docker volume ls | docker volume ls(NAME 列显示随机字符串的即为匿名卷) |
| docker inspect | 查看容器挂载的卷 | docker inspect [容器名/ID] | docker inspect nginx l grep -A10 "Mounts"(查找 nginx 容器绑定的匿名卷 ID) |
| docker volume prune | 清理未使用的卷 | docker volume prune [-f] | docker volume prune -f(清理所有未挂载的卷,释放磁盘空间) |
| docker volume rm | 删除指定卷 | docker volume rm [匿名卷随机ID] | docker volume rm 0e9f8e7d6b5c4a3b2a1d0f9e8d7c6b5a(删除指定 ID 的匿名卷) |
4.4.3.3 绑定挂载(Bind Mount)
绑定挂载是将宿主机的任意目录 / 文件直接映射到容器内指定路径的方式,由用户手动管理宿主机路径,数据存储在用户指定的宿主机路径(如/opt/mysql)。它完全依赖宿主机目录结构,灵活性极高,但迁移容器时需同步迁移宿主机路径,适合开发调试(如实时同步本地代码到容器)、宿主机文件共享等场景。
| 命令 | 功能 | 基本语法 | 实用样例 |
|---|---|---|---|
| docker run -v | 启动容器并绑定挂载 | docker run -d -v [宿主机路径]:[容器内路径] [镜像] | docker run -d --name app -v /opt/code:/app myapp:1.0(将本地代码目录挂载到容器 /app) |
| docker run --mount (进阶) | 绑定挂载(更清晰) | docker run -d --mount type=bind,source=[宿主机路径],target=[容器内路径] [镜像] | docker run -d --name mysql --mount type=bind,source=/opt/mysql-data,target=/var/lib/mysql mysql:5.7 |
| chmod/chown | 修复绑定挂载权限问题 | chmod [权限] [宿主机路径] chown [用户] [宿主机路径] | chmod 777 /opt/mysql-data(解决 mysql 容器无权限写入宿主机目录)chown 999:999 /opt/mysql-data(匹配 mysql 容器内用户 ID) |
| docker inspect | 查看绑定挂载信息 | docker inspect [容器名/ID] | docker inspect app l grep -A10 "Mounts"(查看 app 容器的绑定挂载路径) |
4.5 Docker Network(网络)
4.5.1 Docker 网络架构简介
Docker 容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作 系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等等与网络相关的模块。 Docker 为实现容器网络,主要采用的架构由三部分组成:CNM、Libnetwork 和驱动。
4.5.1.1 CNM
Docker 网络架构采用的设计规范是 CNM(Container Network Model)。CNM 中规定 了 Docker 网络的基础组成要素:Sandbox、Endpoint、Network。
• Sandbox:提供了容器的虚拟网络栈,也即端口、套接字、IP 路由表、防火墙、 DNS 配置等内容。主要用于隔离容器网络与宿主机网络,形成了完全独立的容器网络 环境。
• Network:Docker 内部的虚拟子网,使得网络内的参与者能够进行通讯。
• Endpoint:就是虚拟网络的接口,就像普通网络接口一样,Endpoint 的主要职责 是负责创建连接。Endpoint 类似于常见的网络适配器,那也就意味着一个 Endpoint 只 能接入某一个网络, 当容器需要接入到多个网络,就需要多个 Endpoint。

如上图所示,容器 B 有两个 Endpoint 并且分别接入 Networkd A 和 Network B。那么 容器 A 和容器 B 之间是可以实现通信的,因为都接入了 NetworkA。但是容器 A 和容 器 C 不可以通过容器 B 的两个 Endpoint 通信。
4.5.1.2 Libnetwork
Libnetwork 是 CNM 的一个标准实现。Libnetwork 是开源库,采用 Go 语言编写(跨 平台的),也是 Docker 所使用的库,Docker 网络架构的核心代码都在这个库中。 Libnetwork 实现了 CNM 中定义的全部三个组件,此外它还实现了本地服务发现、基 于 Ingress 的容器负载均衡,以及网络控制层和管理层等功能。
4.5.1.3 驱动
驱动主要负责实现数据层相关内容,例如网络的连通性和隔离性是由驱动来处理的。 驱动通过实现特定网络类型的方式扩展了 Docker 网络栈,例如桥接网络和覆盖网络。 Docker 内置了若干驱动,通常被称作原生驱动或者本地驱动。例如 Bridge Driver、 Host Driver、Overlay Driver、MacVLan Driver、IPVLan Driver、None Driver 等 等。每个驱动负责创建其上所有网络资源的创建和管理。
4.5.2 常见的网络类型
- bridge 网络
bridge 驱动会在 Docker 管理的主机上创建一个 Linux 网桥。默认情况下,网桥上的容器可以相互通信。也可以通过 bridge 驱动程序配置,实现对外部容器的访问。Docker 容器的默认网络驱动。当我们需要多个容器在同一个 Docker 主机上通信时,桥接网络是最佳选择。 - host 网络
对于独立容器,移除容器和 Docker 主机之间的网络隔离,并直接使用主机的网络。当网络堆栈不应该与 Docker 主机隔离,但是希望容器的其他资源被隔离时,主机网络是最佳选择。 - container 网络
这个模式指定新创建的容器和引进存在的一个容器共享一个网络 ,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 ip,而是和一个指定的容器共享 ip,端口等,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信 - none 网络
Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。容器完全网络隔离。 - overlay 网络
借助 Docker 集群模块 Docker Swarm 搭建的跨 Docker Daemon 网络。将多个Docker 守护进程连接在一起,使集群服务能够相互通信。当我们需要运行在不同Docker主机上的容器进行通信时,或者当多个应用程序使用集群服务协同工作时,覆盖网络是最佳选择。
在 Docker 安装时,会自动安装一块 Docker 网卡称为 docker0,它是一个网 桥设备,主要用于 Docker 各容器及宿主机的网络通信。
4.5.3 Docker网络管理常用命令
| 命令 | 功能 | 基本语法 | 实用样例 |
|---|---|---|---|
| docker network create | 创建自定义网络 | docker network create [可选参数] [网络名] | 1. 创建默认桥接网络:docker network create my-net 2. 创建指定驱动 + 子网的网络:docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 my-custom-net |
| docker network connect | 将容器连接到指定网络 | docker network connect [网络名] [容器名/容器ID] | 1. 将运行中的 mysql 容器连入 my-net 网络:docker network connect my-net mysql 2. 连接时指定容器 IP:docker network connect --ip 172.20.0.10 my-custom-net nginx |
| docker network disconnect | 将容器从指定网络断开 | docker network disconnect [网络名] [容器名/容器ID] | 1. 将 nginx 容器从 my-net 网络断开:docker network disconnect my-net nginx |
| docker network ls | 列出所有 Docker 网络 | docker network ls [可选参数] | 1. 列出所有网络:docker network ls 2. 只显示网络 ID:docker network ls -q 3. 过滤指定驱动的网络:docker network ls --filter driver=bridge |
| docker network prune | 清理未被使用的 Docker 网络 | docker network prune [可选参数] | 1. 交互式清理(需确认):docker network prune 2. 强制清理(无确认):docker network prune -f |
| docker network inspect | 查看网络的详细配置信息 | docker network inspect [网络名/网络ID] | 1. 查看 my-net 网络详情(含子网、连接的容器):docker network inspect my-net 2. 格式化输出关键信息:docker network inspect --format '{{.IPAM.Config}}' my-custom-net |
| docker network rm | 删除指定 Docker 网络 | docker network rm [网络名/网络ID] | 1. 删除单个网络:docker network rm my-net 2. 批量删除多个网络:docker network rm net1 net2 net3 |
写在最后
以上便是本文的全部内容啦!创作不易,如果你有任何问题,欢迎私信,感谢您的支持!
