Docker 容器化技术核心知识笔记
配套视频链接:40分钟的Docker实战攻略,一期视频精通Docker_哔哩哔哩_bilibili
0. Docker 常用命令一览表
1. 容器生命周期管理 (Container Lifecycle)
这是最基础的操作,决定了容器的生与死。
| 命令 | 常用参数 | 说明 | 来源/备注 |
|---|---|---|---|
docker run |
-d (后台), -p (端口), -v (卷), --name (命名), --restart always, -e (环境变量) |
核心命令:创建并启动容器 | |
docker start |
- | 启动一个或多个已被停止的容器 | |
docker stop |
- | 优雅停止容器(发送 SIGTERM 信号) | |
docker restart |
- | 重启容器 | |
docker kill |
- | 强制停止容器(发送 SIGKILL 信号) | 紧急情况下使用 |
docker rm |
-f (强制), -v (同时删除挂载卷) |
删除容器 | |
docker create |
- | 创建容器但不启动 | |
docker pause/unpause |
- | 暂停/恢复容器内所有进程 | 较少用,用于冻结状态 |
2. 容器运维与调试 (Operations & Debugging)
当容器"跑不起来"或者"表现奇怪"时,这些是你的救命稻草。
| 命令 | 常用参数 | 说明 | 来源/备注 |
|---|---|---|---|
docker ps |
-a (所有), -q (只显示ID), --format |
查看容器列表 | |
docker logs |
-f (实时跟踪), --tail N (查看末尾N行) |
查看容器标准输出日志 | |
docker exec |
-it (交互式终端), -u (指定用户) |
进入运行中的容器执行命令 | |
docker inspect |
- | 查看容器/镜像的元数据 (IP、路径等) | |
docker stats |
--no-stream |
实时查看容器资源占用 (CPU/内存) | |
docker top |
- | 查看容器内运行的进程信息 | 类似 Linux top |
docker cp |
- | 在宿主机和容器之间复制文件 | docker cp src dest |
docker diff |
- | 查看容器文件系统的变更 | 检查文件是否被篡改 |
3. 镜像管理 (Image Management)
构建、分发和清理镜像。
| 命令 | 常用参数 | 说明 | 来源/备注 |
|---|---|---|---|
docker images |
-a, -q |
列出本地镜像 | |
docker pull |
--platform (指定架构) |
从仓库拉取镜像 | |
docker build |
-t (标签), -f (指定Dockerfile路径), --no-cache |
根据 Dockerfile 构建镜像 | |
docker rmi |
-f (强制删除) |
删除本地镜像 | |
docker tag |
- | 给镜像打标签 (常用于推送前) | |
docker push |
- | 推送镜像到远程仓库 | |
docker history |
- | 查看镜像的构建历史 (层) | 分析镜像体积过大原因 |
docker save |
-o (输出文件) |
将镜像保存为 tar 归档文件 | 离线迁移用 |
docker load |
-i (输入文件) |
从 tar 归档文件加载镜像 | 离线迁移用 |
docker search |
--filter=stars=N | 在 Docker Hub 搜索镜像 |
4. 网络与存储 (Network & Volume)
处理容器间的通信和数据持久化。
| 命令 | 常用参数 | 说明 | 来源/备注 |
|---|---|---|---|
docker network ls |
- | 列出所有网络 | |
docker network create |
--driver bridge/overlay |
创建自定义网络 | |
docker network connect |
- | 将容器连接到某个网络 | |
docker network inspect |
- | 查看网络详情 (含子网IP信息) | 排查网络不通问题 |
docker volume ls |
- | 列出所有数据卷 | |
docker volume create |
- | 创建数据卷 | |
docker volume inspect |
- | 查看卷详情 (找宿主机真实路径) | |
docker volume prune |
-a |
慎用:删除未使用的卷 |
5. 系统维护 (System Maintenance)
保持 Docker 环境的整洁和健康。
| 命令 | 常用参数 | 说明 | 来源/备注 |
|---|---|---|---|
docker system prune |
-a (含未使用镜像), --volumes |
一键清理:停止的容器、悬空镜像、网络 | |
docker info |
- | 显示 Docker 系统信息 (内核、插件等) | |
docker version |
- | 显示版本信息 | |
docker login/logout |
- | 登录/登出 镜像仓库 |
6. Docker Compose (多容器编排)
现在官方推荐使用 docker compose (v2) 而不是 docker-compose (v1)。
| 命令 | 常用参数 | 说明 | 来源/备注 |
|---|---|---|---|
docker compose up |
-d (后台), --build (重构) |
启动所有服务 | |
docker compose down |
-v (同时删卷) |
停止并移除容器、网络 | |
docker compose ps |
- | 查看当前编排的服务状态 | |
docker compose logs |
-f |
查看编排服务的日志 |
1. 容器化技术概述
1.1 什么是 Docker
Docker 是一种成熟高效的软件部署技术,利用容器化技术为应用程序封装独立的运行环境。
- 核心思想:Build, Ship, and Run Any App, Anywhere(一次构建,到处运行)。
- 本质 :Docker 容器本质上是宿主机上的一个特殊的进程,通过命名空间(Namespaces)和控制组(Cgroups)实现隔离和资源限制。
1.2 容器 vs 虚拟机 (VM)
核心区别:
- Docker (容器):共享宿主机的操作系统内核,属于进程级隔离。启动快(毫秒级),占用资源少。
- 虚拟机 (VM):通过 Hypervisor 模拟完整的硬件环境,每个 VM 都有独立的操作系统内核。启动慢,资源占用重。
| 特性 | Docker 容器 | 虚拟机 (Virtual Machine) |
|---|---|---|
| 架构 | 共享宿主机 OS 内核,轻量级 | 包含完整的 Guest OS,重量级 |
| 隔离性 | 进程级隔离 | 硬件/系统级隔离 |
| 启动速度 | 秒级/毫秒级 | 分钟级 |
| 磁盘占用 | MB 级别 | GB 级别 |
容器架构
硬件 Infrastructure
宿主操作系统 Host OS
Docker Engine
Container A
Container B
Libs/App A
Libs/App B
虚拟机架构
硬件 Infrastructure
宿主操作系统 Host OS
Hypervisor
客户机 OS
客户机 OS
Libs/Bins
App A
Libs/Bins
App B
2. Docker 基础
2.1 架构模式 (Client-Server)
Docker 采用标准的 C/S 架构:
- Client (客户端) : 用户使用的命令行工具 (
dockerCLI),负责发送指令。 - Host (宿主机/服务端) : 运行
dockerd守护进程,负责处理指令、管理容器生命周期。 - Registry (仓库): 存储镜像的地方。
2.2 核心组件 (三大支柱)
- 镜像 (Image) :
- 定义: 只读的模板,类似于代码中的"类" (Class) 或软件安装包。
- 特性: 分层存储,复用性强。
- 容器 (Container) :
- 定义: 镜像运行时的实例,类似于"对象" (Object)。
- 特性: 可读写,包含应用运行所需的一切。
- 仓库 (Registry) :
- 定义: 集中存放镜像的场所。
- 示例: Docker Hub (官方)、阿里云镜像仓库、Harbor (私有)。
2.3 基本工作流程
镜像仓库 Docker Daemon 用户 (CLI) 镜像仓库 Docker Daemon 用户 (CLI) docker pull nginx 请求下载 nginx 镜像 返回镜像数据 下载完成 docker run -d nginx 基于镜像创建容器进程 返回 Container ID
3. Docker 安装与配置
Docker安装官方文档: Ubuntu | Docker Docs
docker仅兼容部分操作系统版本的安装,以ubuntu为例,仅支持以下版本的docker适配
- Ubuntu Questing 25.10
- Ubuntu Plucky 25.04
- Ubuntu Noble 24.04 (LTS)
- Ubuntu Jammy 22.04 (LTS)
3.1 Linux Docker安装步骤
-
首先清理环境上残留的docker
shellfor pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done -
更新最新的安装包
shellsudo apt-get update -
安装Docker官方GPG key
shellsudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc -
添加docker官方仓库
shellecho \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update -
下载最新版本docker
shellsudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -
查看Docker服务是否启动
shellsudo systemctl status docker # 查看docker状态 sudo systemctl start docker # 手动启动Docker -
配置docker的镜像站
shellvim /etc/docker/daemon.json # 编辑docker镜像站配置文件,添加以下内容json{ "registry-mirrors":[ "https://docker.m.daocloud.io", "https://docker.1panel.live", "https://hub.rat.dev" ] } -
重启docker服务应用镜像站
shellsudo service docker restart -
运行Docker测试
shellsudo docker run hello-worlddocker会首先查找本地镜像仓库是否存在hello-world镜像,当不存在会去远端拉取最新的hello-world并运行,当输出
Hello from Docker!就表示Docker可以正常使用了。
3.2 windows安装Docker
-
打开windows功能,勾选这两个选项
-
重启电脑
-
打开windows的cmd控制台,安装
wslshellwsl --update --web-download -
安装
docker desktop下载地址:Docker: Accelerated Container Application Development
下载完后双击exe文件默认安装在C盘,也可以使用目录安装到指定文件夹
shellstart /w "" "Docker Desktop Install.exe" install --installation-dir={指定windows目录} -
windows系统配置镜像站
打开Docker Desktop->settings->Docker Engine,把镜像站配置信息粘贴进去。
这样我们就可以在windows上拉取docker镜像了
3.Docker官方镜像站
下载官方镜像网址:https://hub.docker.com/
3.3 验证安装
bash
docker --version # 查看版本
docker run hello-world # 运行测试镜像
4. Docker 镜像管理
Docker 镜像(Image)是容器的只读模板,包含了应用程序运行所需的所有依赖(代码、运行时、库、环境变量和配置文件)。镜像是容器生命周期的基石,理解镜像管理是掌握 Docker 的第一步。
4.1 镜像结构与命名规范
一个完整的 Docker 镜像名称由四个部分组成,遵循以下格式:
[Registry/注册表地址]/[Namespace/命名空间]/[Repository/镜像名]:[Tag/版本标签]
| 组成部分 | 说明 | 默认值 | 示例 |
|---|---|---|---|
| Registry | 存放镜像的仓库地址 | docker.io (Docker Hub) |
docker.io 或 registry.cn-hangzhou.aliyuncs.com |
| Namespace | 用户或组织的命名空间 | library (官方镜像) |
library (官方 nginx) 或 mysql (mysql 官方) |
| Repository | 镜像的具体名称 | 无 (必填) | nginx, redis, my-app |
| Tag | 镜像的版本标签 | latest |
1.23, alpine, v1.0 |
示例解析:
-
官方镜像简写:
- 命令:
docker pull nginx - 完整解析:
docker pull docker.io/library/nginx:latest - 说明:省略了默认注册表、默认命名空间和默认标签。
- 命令:
-
第三方私有镜像:
- 命令:
docker pull docker.n8n.io/n8nio/n8n:0.12.1 - 解析:
- Registry:
docker.n8n.io - Namespace:
n8nio - Repository:
n8n - Tag:
0.12.1
- Registry:
- 命令:
4.2 获取与查看镜像
1. 拉取镜像 (docker pull)
从远程仓库下载镜像到本地。
-
基础用法:
bashdocker pull nginx:1.23 -
指定架构拉取 (
--platform) :默认情况下 Docker 会自动拉取匹配当前主机架构的镜像。在跨平台开发(如在 Apple Silicon M1/M2 上开发 x86 应用)时,需显式指定架构。
bash# 拉取 Linux AMD64 架构的 Nginx 镜像 docker pull --platform=linux/amd64 nginx:alpine
2. 查看本地镜像 (docker images)
列出本地主机上已下载的镜像。
-
基础查看:
bashdocker images -
查看所有镜像 (
-a) :显示所有镜像,包括中间层镜像(Intermediate Layers)。
bashdocker images -a -
按条件筛选 (
--filter) :常用于查找悬空镜像 (Dangling Images,即 Repository 和 Tag 均为
<none>的镜像,通常是构建过程中的残留或旧版本覆盖产生)。bashdocker images --filter "dangling=true" -
自定义输出格式 (
--format) :仅显示需要的字段,方便脚本处理。
bashdocker images --format "{{.Repository}}:{{.Tag}} {{.Size}}"
4.3 镜像操作:标记与构建
1. 镜像打标签 (docker tag)
docker tag 本质上是给同一个镜像 ID 创建一个别名(引用),不占用额外的磁盘空间。
-
场景一:版本管理
bash# 将 ID 为 a1b2c3d4 的镜像标记为 myapp:v1.0 docker tag a1b2c3d4 myapp:v1.0 -
场景二:推送前准备
要将镜像推送到远程仓库,必须将镜像标记为
仓库地址/用户名/镜像名:标签的格式。bash# 为本地镜像添加符合 Docker Hub 规范的标签 docker tag myapp:v1.0 xuanchen46789/myapp:v1.0
2. 构建镜像 (docker build)
基于 Dockerfile 构建自定义镜像。
-
命令格式:
bashdocker build -t <镜像名>:<标签> <上下文路径> -
示例:
bash# 在当前目录(.)寻找 Dockerfile 构建镜像,并命名为 my-python-app:v1 docker build -t my-python-app:v1 .--no-cache:构建时不使用缓存,强制重新执行每一层指令(用于解决依赖更新未生效的问题)。
3. 推送镜像 (docker push)
将本地镜像上传至远程仓库。
-
步骤:
- 登录:
docker login - 打标签:
docker tag ... - 推送:
bashdocker push xuanchen46789/myapp:v1.0 - 登录:
4.4 清理与删除 (docker rmi)
管理本地磁盘空间,移除不再使用的镜像。
-
删除指定镜像 :
可以通过镜像 ID 或 镜像名称:标签 进行删除。
bashdocker rmi nginx:latest # 或者使用短 ID docker rmi 605c77 -
强制删除 (
-f) :如果镜像正在被某个停止的容器引用,默认无法删除。使用
-f强制移除。bashdocker rmi -f nginx:latest -
批量清理悬空镜像 :
结合 shell 命令批量删除所有无用的悬空镜像。
bashdocker rmi $(docker images -q --filter "dangling=true")
4.5 进阶:镜像的导入导出 (离线环境)
在没有外网的服务器环境(如内网部署),无法使用 docker pull,此时需要使用导入导出命令。
1. 导出镜像 (docker save)
将本地的一个或多个镜像打包成 tar 归档文件。
-
命令:
bash# 将 nginx:alpine 镜像保存为 nginx-alpine.tar 文件 docker save -o nginx-alpine.tar nginx:alpine
2. 导入镜像 (docker load)
从 tar 归档文件中加载镜像到本地 Docker 环境。
-
命令:
bash# 从 tar 包加载镜像 docker load -i nginx-alpine.tar
4.6 镜像元数据查看 (docker inspect)
查看镜像的详细配置信息,如 CMD 命令、环境变量、暴露端口、架构等。
-
命令:
bashdocker inspect nginx:latest -
实战用途 :
当不知道某个镜像默认启动命令是什么,或者不知道它默认的数据卷挂载路径时,通过
inspect查看Config和Mounts字段。
5. Docker 容器管理
5.1 启动容器 (docker run)
docker run 是 Docker 中最基础也是最重要的命令。
运行机制:当你执行这个命令时,Docker 会首先在本地寻找同名的镜像。如果本地没有找到,它会自动去远程仓库(Registry)拉取最新的镜像,然后启动容器。
关键参数详解:
-d:后台分离模式 (Detached Mode)
-
作用:让容器在后台运行,而不是直接占用控制台窗口。
-
原理 :使用
-d的本质是将容器进程交给 Docker 守护进程(dockerd)托管,使其作为子进程在后台运行。这符合操作系统对守护进程(Daemon)的管理规范。 -
反馈:执行后会打印出完整的容器 ID。
-
示例:
bashdocker run -d nginx
-p:端口映射 (Port Mapping)
-
背景:Docker 容器运行在独立的虚拟网络环境中,默认情况下,外部无法直接访问容器内的服务。
-
作用:建立宿主机端口与容器端口的映射关系。
-
语法 :
-p 宿主机端口:容器端口 -
效果:访问宿主机的 80 端口,流量会被转发到容器内的 80 端口。
-
示例:
bashdocker run -p 80:80 nginx
-v:数据卷挂载 (Volume Mounting)
-
核心目的 :实现数据的持久化。如果不挂载,容器一旦被删除,里面的数据也会随之消失。
-
两种模式对比:
-
绑定挂载 (Bind Mount):
-
描述:直接把宿主机的具体路径映射到容器内。
-
注意:如果宿主机路径为空,容器内对应目录的内容会被覆盖(清空),使用时需谨慎。
-
示例:
bashdocker run -d \ --name volume-demo \ -v /usr/share/nginx/html:/usr/share/nginx/html \ nginx
-
-
命名卷 (Named Volume):
-
描述:由 Docker 管理的存储空间。
-
优势:首次挂载时,会将容器内的原有文件复制到卷中,不会像绑定挂载那样导致文件丢失。适合在多个容器间共享数据。
-
示例:
bashdocker run -d \ --name volume-demo \ -v my-volume:/usr/share/nginx/html \ nginx
-
-
--name:指定容器名称
-
作用:给容器起一个易于记忆的名字,方便后续管理。
-
注意 :如果不指定,Docker 会随机生成一个名字。容器名称和容器 ID 在管理命令(如
docker rm)中是等价的。 -
示例:
bashdocker run -d --name nginx-demo nginx
-e:设置环境变量 (Environment Variables)
-
作用:在不修改镜像的情况下,动态调整应用的配置。
-
场景:
- 动态配置:传入数据库连接地址、日志级别等。
- 安全隔离:避免将密码等敏感信息硬编码在镜像里。
- 跨环境适配:不同环境(开发、测试、生产)使用同一镜像,仅通过环境变量区分配置。
-
示例(启动 MongoDB):
bashdocker run -d --network some-network --name some-mongo \ -p 27017:27017 \ -e MONGO_INITDB_ROOT_USERNAME=mongoadmin \ -e MONGO_INITDB_ROOT_PASSWORD=secret \ mongo
-it:交互式终端
-
作用 :开启一个连接容器内部的通道,允许进入容器执行 Shell 命令。通常与
/bin/bash或/bin/sh配合使用。 -
示例:
bashdocker run -it --rm alpine
--rm:自动清理
- 作用:当容器停止运行时,自动删除该容器。
- 场景 :非常适合用于临时的调试或一次性任务,避免残留大量无用的停止容器。通常与
-it一起使用。
--restart:重启策略
-
作用:定义容器退出后的行为,保证服务的高可用性。
-
选项:
always:无论什么原因停止,总是尝试重启。unless-stopped:除非是人工手动停止的,否则都会尝试重启(例如服务器重启后,容器会自动启动)。
-
示例:
bashdocker run -d --restart always nginx
5.2 常用管理命令
除了启动容器,日常运维中还需要掌握以下命令来管理容器的状态:
- 查看容器 :
docker ps:查看当前正在运行的容器。docker ps -a:查看所有容器(包括已停止的)。
- 进入容器 :
docker exec -it <容器名> /bin/bash:在运行中的容器内开启一个新的终端,是调试问题的神器。
- 查看日志 :
docker logs -f <容器名>:实时跟踪容器的标准输出日志,用于排查启动报错或运行异常。
- 停止与删除 :
docker stop <容器名>:优雅地停止容器。docker rm <容器名>:删除已停止的容器。如果要强制删除正在运行的容器,需添加-f参数。
6. Docker 生命周期
容器的生命周期是指从容器被创建开始,到最终被删除的整个过程。Docker 守护进程(Daemon)负责管理和监控这些状态的变化。理解生命周期对于排查容器故障(如容器无法启动、无法停止)至关重要。
6.1 五大核心状态详解
Docker 容器在运行过程中主要会在以下五种状态之间流转:
-
Created (已创建)
- 描述:容器实例已经由镜像创建,文件系统层(可读写层)已经分配,但容器内的核心进程尚未启动。
- 触发 :通常通过
docker create命令触发。
-
Running (运行中)
- 描述:容器内的 PID 1 进程正在处于活跃状态。这是容器提供服务的正常状态。
- 触发 :通过
docker start或docker run触发。
-
Paused (暂停)
- 描述:容器内的所有进程都被挂起(Frozen)。容器的内存状态被保留,但不再消耗 CPU 资源。这类似于虚拟机的挂起操作。
- 触发 :通过
docker pause触发。
-
Exited (停止/退出)
- 描述:容器内的主要进程已经结束。这可能是任务正常完成(退出码 0),也可能是因为错误崩溃(非 0 退出码),或者是被用户手动停止。此时容器的文件系统依然保留,可以查看到日志。
- 触发 :进程自动结束、
docker stop、docker kill。
-
Dead (死亡)
- 描述:这是一个异常状态。通常表示 Docker 试图删除容器,但由于某些原因(如文件系统忙、资源未释放)导致删除失败。处于 Dead 状态的容器通常无法启动,需要手动强制清理。
- 触发:系统错误或移除操作失败。
6.2 容器状态流转图
下图展示了容器在不同命令作用下的状态变迁逻辑,并补充了 Dead 状态:
docker create
docker start
docker run
docker pause
docker unpause
docker stop / 进程自然结束
docker kill (强制停止)
docker start / docker restart
docker rm (操作失败/系统异常)
系统严重错误
docker rm -f (强制删除)
docker rm
docker rm -f (手动清理)
docker rm
Created
Running
Paused
Exited
Dead
6.3 改变生命周期的命令示例
以下是这些命令在实际操作中的具体用法:
1. 创建与启动 (Create / Start / Run)
-
仅创建容器 (Created) :
如果你想先配置好容器但不立即运行(例如为了后续批量启动),可以使用
create。bash# 从 nginx 镜像创建一个名为 my_web 的容器 docker create --name my_web nginx -
启动已存在的容器 (Running) :
用于启动处于
Created或Exited状态的容器。bashdocker start my_web -
一键创建并运行 (Running) :
这是开发中最常用的命令,通常配合
-d参数让容器在后台运行。bash# 创建并启动一个名为 my_redis 的容器,并在后台运行 docker run -d --name my_redis redis
2. 停止与恢复 (Stop / Restart / Kill)
-
优雅地停止 (Exited) :
给容器内的进程发送信号,让其有时间保存数据。
bashdocker stop my_redis -
强制杀死进程 (Exited) :
如果容器无响应,强制立即停止。
bashdocker kill my_redis -
重启容器 :
常用于配置文件修改后的生效。
bashdocker restart my_redis
3. 暂停与取消暂停 (Paused)
-
挂起容器进程 :
当你需要临时释放 CPU 资源,但不想完全停止容器时使用。
bashdocker pause my_redis -
恢复运行:
bashdocker unpause my_redis
4. 移除容器 (Deleted)
-
删除已停止的容器:
bashdocker rm my_web -
强制删除运行中的容器 :
如果容器正在运行,必须使用
-f(force) 参数。bashdocker rm -f my_redis
命令表格如下:
| 命令 | 作用 | 状态变迁方向 | 说明 |
|---|---|---|---|
docker create |
创建新容器 | None -> Created |
仅加载镜像并配置层,不启动进程。 |
docker start |
启动容器 | Created/Exited -> Running |
启动容器的主进程。 |
docker run |
创建并启动 | None -> Running |
相当于 docker create + docker start 的组合原子操作。 |
docker stop |
优雅停止 | Running -> Exited |
先发送 SIGTERM 信号给容器,等待一段时间(默认10秒)后若未停止则发送 SIGKILL。 |
docker kill |
强制停止 | Running -> Exited |
直接发送 SIGKILL 信号,立即终止进程,可能导致数据丢失。 |
docker restart |
重启容器 | Running -> Running |
先执行 stop,再执行 start。 |
docker pause |
暂停容器 | Running -> Paused |
利用 cgroups 的 freezer 特性挂起进程。 |
docker unpause |
恢复容器 | Paused -> Running |
解除进程挂起状态。 |
docker rm |
删除容器 | Exited/Created -> Deleted |
移除容器的文件层和元数据。只能删除非运行状态的容器(除非加 -f)。 |
7. Docker 网络管理
Docker 网络子系统允许容器之间以及容器与宿主机之间进行通信。Docker 的网络架构是可插拔的,默认提供了多种驱动程序来适应不同的用例。
7.1 核心网络模式详解
通过 docker network ls 可以查看当前 Docker 环境中的网络列表。Docker 默认包含以下三种核心模式:
| 网络模式 | 驱动名称 | 特点与适用场景 |
|---|---|---|
| Bridge (桥接模式) | bridge |
默认模式。容器通过虚拟网桥(docker0)连接,通过 NAT(网络地址转换)访问外部网络。容器间网络隔离,需通过端口映射暴露服务。 |
| Host (主机模式) | host |
无隔离。容器直接共享宿主机的网络栈(IP 和端口)。性能最高,但容易导致端口冲突。 |
| None (无网络模式) | none |
完全隔离。容器没有外部网络接口,仅保留回环接口(lo, 127.0.0.1)。适用于安全性要求极高或不需要网络的离线任务。 |
宿主机
Bridge 模式
Host 模式容器
虚拟网桥 docker0
应用
物理网卡 Eth0
NAT 转换
veth pair
容器1
veth pair
容器2
7.2 常用网络管理命令
| 命令 | 说明 | 示例 |
|---|---|---|
docker network ls |
列出所有网络 | docker network list |
docker network create |
创建自定义网络 | docker network create my-net |
docker network rm |
删除网络 | docker network rm my-net (需确保网络中无运行容器) |
docker network connect |
将容器加入网络 | docker network connect my-net my-container |
docker network disconnect |
将容器移出网络 | docker network disconnect my-net my-container |
docker network inspect |
查看网络详情 | docker network inspect my-net (查看子网段、网关、连接的容器) |
7.3 深入 Bridge 模式 (桥接)
这是 Docker 的默认网络驱动。
1. 默认桥接 vs 自定义桥接
- 默认桥接 (
bridge) :- 容器安装后默认加入此网络。
- 缺点:不支持通过容器名称(Container Name)进行 DNS 解析,容器间通信必须使用 IP 地址(而 IP 可能会变)。
- 自定义桥接 (
User-defined bridge) :- 优点 :支持 自动 DNS 解析 。同一自定义网络下的容器,可以通过容器名称直接互相
ping通或访问,无需关心 IP 变化。
- 优点 :支持 自动 DNS 解析 。同一自定义网络下的容器,可以通过容器名称直接互相
2. 实战:创建自定义子网与 DNS 解析
场景 :创建两个容器 app1 和 app2,让它们通过名字互相访问。
-
创建自定义网络:
bashdocker network create my-network -
启动容器并加入网络:
bash# 启动 app1 docker run -d --name app1 --network my-network nginx # 启动 app2 docker run -d --name app2 --network my-network nginx -
验证通信 :
进入
app1容器,尝试 pingapp2。bashdocker exec -it app1 ping app2结果:可以 ping 通,说明 Docker 内部 DNS 成功将
app2解析为了对应的 IP 地址。
3. 实战案例:MongoDB 与 Mongo Express 互联
这是您笔记中的一个典型微服务连接案例。如果不使用 Docker Compose,我们需要手动配置网络来实现服务发现。
-
创建网络:
bashdocker network create network1 -
启动数据库 (MongoDB) :
注意:这里不需要
-p映射 27017 端口,因为我们希望数据库只在 Docker 网络内部被访问,不对外暴露,增加安全性。bashdocker run -d \ --name my_mongodb \ -e MONGO_INITDB_ROOT_USERNAME=admin \ -e MONGO_INITDB_ROOT_PASSWORD=secret \ --network network1 \ mongo -
启动管理界面 (Mongo Express) :
这里通过环境变量
ME_CONFIG_MONGODB_SERVER指定数据库地址为容器名my_mongodb。bashdocker run -d \ --name mongo-express \ -p 8081:8081 \ -e ME_CONFIG_MONGODB_SERVER=my_mongodb \ -e ME_CONFIG_BASICAUTH_USERNAME="admin" \ -e ME_CONFIG_BASICAUTH_PASSWORD="secret" \ --network network1 \ mongo-express
效果:访问宿主机 http://localhost:8081 即可管理数据库。虽然 DB 端口未对外开放,但 Web UI 容器可以通过 network1 访问到它。
7.4 Host 模式 (主机)
特点:容器直接共享宿主机的网络命名空间。容器不会拥有自己的 IP 地址,而是直接绑定到宿主机的 IP。
-
适用场景:对网络性能要求极高,或者需要处理大量端口范围的场景。
-
命令:
bashdocker run -d --network host --name my-nginx nginx -
验证 :
进入容器查看 IP,会发现它显示的是宿主机的网络配置,而不是 Docker 的虚拟网段。
bashdocker exec -it my-nginx ip addr show
7.5 None 模式 (无网络)
特点:容器只有本地回环地址(127.0.0.1),无法连接互联网。
-
命令:
bashdocker run -d --network none busybox
7.6 网络清理
当不再需要某个自定义网络时,应当删除以释放资源。
-
删除单个网络:
bashdocker network rm my-network注意:删除前必须断开或停止所有连接到该网络的容器。
-
清理所有未使用网络:
bashdocker network prune
8. Docker 数据卷管理
容器的文件系统是临时的,当容器被删除时,容器内的所有数据都会丢失。为了实现数据的持久化保存 以及在宿主机和容器之间共享数据,Docker 提供了数据卷(Volume)机制。
8.1 核心概念
- 数据持久化:将容器内的数据保存在宿主机上,即使容器被删除,数据依然存在。
- 解耦:数据卷独立于容器的生命周期,可以被多个容器同时挂载和共享。
8.2 挂载方式对比
Docker 提供了两种主要的挂载方式,分别适用于不同的场景:
| 特性 | 绑定挂载 (Bind Mount) | 命名卷 (Named Volume) |
|---|---|---|
| 语法 | -v <宿主机绝对路径>:<容器路径> |
-v <卷名>:<容器路径> |
| 存储位置 | 用户指定的宿主机任意路径 | Docker 管理的特定路径 (/var/lib/docker/volumes/) |
| 初始化行为 | 覆盖:宿主机目录内容会覆盖容器目录(若宿主机为空,容器目录也被清空) | 复制:首次挂载时,会将容器内目标目录的原有文件复制到卷中 |
| 移植性 | 差(依赖宿主机特定路径) | 好(仅依赖 Docker 环境) |
| 适用场景 | 开发环境:代码热更新(本地修改代码,容器内即时生效) | 生产环境:数据库存储、日志持久化、多容器数据共享 |
1. 绑定挂载 (Bind Mount) 实战
直接将宿主机的目录映射到容器内。
bash
# 将宿主机当前目录下的 html 文件夹挂载到 Nginx 容器的网页目录
docker run -d -p 80:80 -v /website/html:/usr/share/nginx/html nginx
- 注意 :如果宿主机的
/website/html是空的,启动后容器内的/usr/share/nginx/html也会变成空的(原有的 index.html 被隐藏/覆盖)。
2. 命名卷 (Named Volume) 实战
使用 Docker 管理的卷。
bash
# 将名为 my-nginx-volume 的卷挂载到 Nginx 容器
docker run -d -v my-nginx-volume:/usr/share/nginx/html nginx
- 机制 :如果
my-nginx-volume不存在,Docker 会自动创建。容器启动时,Docker 会把 Nginx 容器内/usr/share/nginx/html下的默认文件自动复制到这个卷中,不会导致数据丢失。
8.3 数据卷管理命令
Docker 提供了 docker volume 子命令来专门管理数据卷。
1. 创建数据卷
bash
docker volume create <卷名>
# 示例
docker volume create nginx_html
2. 查看所有数据卷
bash
docker volume ls
3. 查看数据卷详情
查看卷在宿主机上的真实存储路径(Mountpoint)。
bash
docker volume inspect <卷名>
# 示例
docker volume inspect nginx_html
- 输出示例 :通常位于
/var/lib/docker/volumes/nginx_html/_data。
4. 删除数据卷
bash
docker volume rm <卷名>
# 示例
docker volume rm nginx_html
- 注意 :只能删除未被任何容器使用的卷。如果卷正在被挂载(即使容器已停止),删除会失败,需先删除相关容器。
5. 清理未使用的卷
一键清理所有未被引用的卷,释放磁盘空间。
bash
# 清理所有未被容器引用的卷
docker volume prune
# 清理所有卷(包括未被运行中容器引用的,慎用!)
docker volume prune -a
9. Docker 系统维护
随着 Docker 的长期使用,系统中会积累大量的临时容器、未使用的镜像、废弃的网络和构建缓存,这些资源会占用大量磁盘空间并可能影响性能。掌握系统维护命令对于保持 Docker 环境的健康至关重要。
9.1 查看系统版本与信息
-
查看版本信息 (
docker version)显示 Docker 客户端(Client)和服务器端(Server/Daemon)的版本详细信息,包括 Go 语言版本、Git commit ID、操作系统架构等。用于确认环境一致性。
bashdocker version -
查看系统全局信息 (
docker info)显示 Docker 系统的汇总报告,常用于排查环境问题。包含信息如下:
- 容器统计:总数、运行中、停止、暂停的数量。
- 镜像统计:本地镜像总数。
- 基础设施:存储驱动(Overlay2 等)、内核版本、操作系统类型、CPU 架构、内存总量等。
bashdocker info
9.2 资源监控 (docker stats)
作用 :提供一个实时的流式数据界面,监控所有运行中容器的资源占用情况,功能类似于 Linux 的 top 命令。
-
基础命令:
bashdocker stats -
输出关键指标解析:
- CPU %:CPU 使用率。
- MEM USAGE / LIMIT:当前内存使用量 / 容器内存限制。
- MEM %:内存使用百分比。
- NET I/O:网络输入/输出流量。
- BLOCK I/O:磁盘读写数据量。
9.3 系统大扫除 (docker system prune)
作用 :一键清理 Docker 系统中所有未使用的资源。这是释放磁盘空间最有效的命令,但具有破坏性,需谨慎使用。
1. 安全清理 (日常维护)
默认情况下,docker system prune 仅删除"悬空"和"无用"的临时资源。
bash
docker system prune
清理范围:
- 所有已停止的容器 (Stopped containers)。
- 所有未被任何容器使用的网络 (Unused networks)。
- 所有悬空镜像 (Dangling images,即标签为
<none>的镜像)。 - 构建缓存 (Build cache)。
2. 彻底清理 (深度释放)
如果磁盘空间严重不足,可以添加参数进行深度清理。
bash
docker system prune -a --volumes
新增清理范围:
-a:删除所有未被运行中容器使用的镜像(即使它有正常的标签,只要没在跑,就会被删掉)。--volumes:删除所有未被任何容器使用 的数据卷(警告:这可能导致持久化数据丢失!)。
清理建议:
- 日常维护仅使用
docker system prune。- 仅在确认数据已备份且环境需要重置时,才使用
docker system prune -a --volumes。
10. Dockerfile (构建自定义镜像)
Dockerfile 是一个没有后缀名的文本文件,它包含了一系列指令,用于自动化构建 Docker 镜像。
10.1 核心指令详解
| 指令 | 说明 | 关键细节 |
|---|---|---|
| FROM | 指定基础镜像 | 必须是 Dockerfile 的第一行指令 。例如 FROM python:3.13-slim。 |
| WORKDIR | 设置工作目录 | 相当于 Linux 的 cd。如果目录不存在会自动创建。后续的 RUN, CMD, COPY 等指令都会基于此目录执行。 |
| COPY | 复制文件 | 格式:COPY <本地路径> <镜像路径>。将宿主机当前上下文目录的文件复制到镜像内。 |
| RUN | 构建时执行命令 | 在镜像构建阶段执行(Build time)。常用于安装依赖、创建目录等。可以写多条 RUN 指令。 |
| EXPOSE | 声明端口 | 仅作为文档声明,告知使用者容器打算监听的端口(如 EXPOSE 8000)。注意 :实际端口映射仍需在 docker run 时通过 -p 参数指定。 |
| CMD | 容器启动默认命令 | 容器启动时执行的命令。推荐使用数组格式 ["exe", "param"]。一个 Dockerfile 只能有一个 CMD,如果有多个,只有最后一个生效。 |
| ENTRYPOINT | 容器固定入口 | 设置容器启动时的固定程序。与 CMD 不同,ENTRYPOINT 指定的命令不易被 docker run 后的参数覆盖。 |
10.2 RUN vs CMD vs ENTRYPOINT
这是面试和实战中的高频考点,三者区别如下:
- RUN (构建时)
- 触发时机 :
docker build构建镜像时。 - 作用:安装软件、配置环境。
- 触发时机 :
- CMD (启动默认值)
- 触发时机 :
docker run容器启动时。 - 可覆盖性 :如果在
docker run后面指定了命令,CMD 会被覆盖。- 例 :
CMD ["python", "app.py"]。若运行docker run ... python test.py,则原 CMD 不执行,改执行python test.py。
- 例 :
- 配合 ENTRYPOINT :如果有 ENTRYPOINT,CMD 会变成 ENTRYPOINT 的默认参数。
- 触发时机 :
- ENTRYPOINT (固定入口)
- 触发时机 :
docker run容器启动时。 - 不可覆盖性 :默认不会被
docker run后的命令覆盖(除非使用--entrypoint强制替换)。 - 场景:将容器当作一个可执行程序使用。
- 触发时机 :
组合示例:
dockerfile
ENTRYPOINT ["nginx"] # 固定程序:nginx
CMD ["-g", "daemon off;"] # 默认参数:前台运行
- 如果不传参:执行
nginx -g "daemon off;" - 如果传参(
docker run ... -v):执行nginx -v
10.3 示例 (Python FastAPI 应用)
以下是一个完整的 Dockerfile 编写示例:
dockerfile
# 1. 基础镜像
FROM python:3.13-slim
# 2. 设置工作目录 (后续操作都在 /app 下)
WORKDIR /app
# 3. 复制项目文件 (将当前目录所有文件复制到镜像的 /app)
COPY . .
# 4. 安装依赖 (构建阶段执行)
RUN pip install -r requirements.txt
# 5. 声明端口 (仅做声明)
EXPOSE 8000
# 6. 启动命令 (容器启动时执行)
CMD ["python", "main.py"]
10.4 镜像构建与发布流程
1. 构建镜像 (Build)
使用 docker build 命令将 Dockerfile 打包为镜像。
bash
# 格式:docker build -t <镜像名:标签> <上下文路径>
# 注意:最后的 . 表示当前目录为构建上下文
docker build -t xuanchen46789/docker-test .
注意 :命令最后的
.表示将当前目录作为构建上下文(Context),必须确保该目录下存在 Dockerfile。
2. 镜像打标签 (Tag)
给镜像起别名,通常用于推送到远程仓库前的规范命名。
bash
# 格式:docker tag <源镜像ID/名> <新镜像名:版本>
docker tag a1b2c3d4 xuanchen46789/myapp:v1.0
3. 推送镜像 (Push)
将镜像上传至 Docker Hub 或私有仓库。
bash
# 1. 登录 (首次需要)
docker login
# 2. 推送
docker push xuanchen46789/docker-test
11. Docker Compose 与多容器管理
Docker Compose 是 Docker 官方推出的轻量级容器编排工具。它允许用户通过一个 YAML 文件定义多个关联容器(如 Web 应用 + 数据库),实现"一键启动/停止"整个应用栈。
11.1 核心概念
- 服务 (Services) :应用的一个组成部分(如
web或db),对应一个容器。 - 项目 (Project):由一组关联的应用容器组成的一个完整业务单元,默认以目录名作为项目名。
- 自动化网络 :Compose 会自动为该项目创建一个默认网络,服务之间可以通过服务名(Hostname)直接通信,无需知道具体 IP。
11.2 docker-compose.yml 结构解析
以下是一个典型的 Web + Database 架构配置示例:
yaml
version: '3.8' # Compose 文件版本
services: # 定义服务列表
web: # 服务名称:web
build: . # 从当前目录 (.) 的 Dockerfile 构建镜像
ports:
- "8000:8000" # 端口映射:宿主机:容器
depends_on:
- db # 依赖声明:确保 db 服务先启动
networks:
- my-net # 加入自定义网络
db: # 服务名称:db
image: postgres:13 # 直接使用官方镜像,不需构建
volumes:
- db-data:/var/lib/postgresql/data # 挂载数据卷实现持久化
environment:
- POSTGRES_PASSWORD=secret # 设置环境变量
networks:
- my-net
volumes: # 定义数据卷
db-data: # 自动管理的命名卷
networks: # 定义网络
my-net: # 自定义桥接网络
关键配置说明:
buildvsimage:build用于开发阶段构建本地代码;image用于直接拉取现成镜像。depends_on:控制启动顺序。注意:它只保证启动顺序,不保证被依赖的服务(如数据库)已经完全初始化完毕(Ready)。environment:注入配置信息,避免硬编码敏感数据。
11.3 常用命令
Docker Compose 命令主要用于管理整个服务的生命周期。
| 命令 | 描述 | 关键参数与场景 |
|---|---|---|
docker compose up |
创建并启动服务 | -d: 后台运行 (Detached mode)。 --build: 启动前强制重新构建镜像(当代码更新时使用)。 |
docker compose down |
停止并删除资源 | 默认删除容器和网络。 -v: 同时删除数据卷 (慎用!会导致数据库数据丢失)。 --rmi all: 删除相关镜像。 |
docker compose logs |
查看服务日志 | -f: 实时跟踪日志输出。 docker compose logs -f web: 仅查看 web 服务的日志。 |
docker compose ps |
查看服务状态 | 列出当前项目下所有容器的运行状态。 |
docker compose stop/start |
暂停/恢复服务 | 仅停止/启动容器,不删除容器和网络(不同于 down)。 |
11.4 最佳实践
- 数据持久化 :数据库服务一定要使用
volumes挂载数据卷,否则docker compose down后数据会丢失。 - 环境隔离 :可以通过
-f参数指定不同的配置文件(如docker-compose.dev.ymlvsdocker-compose.prod.yml)来区分开发和生产环境。 - 服务通信 :在代码中连接数据库时,Host 地址直接填服务名(如
db),不要填 IP 地址。
12. Docker 技术原理 (进阶)
Docker 并非像虚拟机那样通过 Hypervisor 虚拟化硬件,而是利用 Linux 内核的特性实现操作系统层面的虚拟化。Docker 容器本质上是宿主机上的一个特殊的进程。
12.1 核心技术架构
Docker 的魔法主要由 Linux 内核的三大基石支撑:Namespaces (隔离)、Cgroups (限制)和 UnionFS(分层)。
1. Namespaces (命名空间) ------ 负责"隔离"
- 作用:为容器提供独立的系统视图。让容器内的进程"以为"自己独占了整个操作系统。
- 原理:Linux 内核通过 Namespaces 将全局系统资源包裹起来,使得处于不同 Namespace 的进程拥有独立的资源视图。
- 常见的 Namespace :
- PID:进程隔离(容器内 PID 为 1 的进程,在宿主机上只是一个普通进程)。
- NET:网络栈隔离(独立的 IP、端口、网卡)。
- MNT:文件挂载点隔离(独立的文件系统)。
- USER:用户和用户组隔离。
- UTS:主机名和域名隔离。
- IPC:进程间通信隔离。
2. Cgroups (Control Groups) ------ 负责"限制"
- 作用:限制容器能使用的资源上限,防止单个容器耗尽宿主机资源(如 CPU、内存、磁盘 I/O)。
- 原理:Cgroups 是 Linux 内核提供的一种机制,可以限制、记录和隔离进程组所使用的物理资源。
- 场景:如果没有 Cgroups,一个死循环的容器可能会占满 100% 的 CPU,导致宿主机和其他容器崩溃。
3. UnionFS (联合文件系统) ------ 负责"分层"
- 作用:支持镜像的分层存储和复用,实现极速的文件操作。
- 原理:UnionFS 允许将多个不同位置的目录(分支)联合挂载到同一个目录下,表现为一个统一的文件系统。
- 写时复制 (CoW - Copy on Write) :
- 镜像层 (Read-Only):底层的镜像层是只读的。
- 容器层 (Read-Write):当容器启动时,Docker 会在镜像层之上挂载一个可写的"容器层"。
- 修改机制 :当你尝试修改一个文件时,Docker 不会直接修改只读层,而是将文件复制到可写层进行修改。这使得镜像可以被多个容器安全共享。
12.2 架构原理图
以下图表展示了容器进程如何依赖 Linux 内核特性实现虚拟化:
Docker 容器
Linux 内核
宿主机硬件
看到的视图被隔离
使用的资源被限制
文件系统被分层
管控
管控
读取/写入
CPU
内存
磁盘
Namespaces
(视图隔离)
Cgroups
(资源限制)
UnionFS
(分层文件系统)
容器进程 (App)
12.3 总结:Docker vs 虚拟机
回顾核心区别,这有助于理解为什么 Docker 启动更快:
| 特性 | Docker 容器 | 虚拟机 (VM) |
|---|---|---|
| 核心原理 | 进程级隔离 (Namespaces + Cgroups) | 硬件级虚拟化 (Hypervisor) |
| 操作系统 | 共享宿主机内核 | 拥有独立的 Guest OS (重) |
| 启动速度 | 毫秒/秒级 | 分钟级 |
| 磁盘占用 | MB 级 (镜像分层复用) | GB 级 (完整 OS) |