Docker 基础¶
⚙️ 不用 Docker 会怎样?——Docker 架构原理¶
开发时「在我电脑上跑得好好的」,部署到服务器却各种报错——环境不一致、依赖冲突、配置漂移……Docker 就是为了解决这类问题而生的。它把应用和所有依赖打包成一个标准化的镜像,在任何支持 Docker 的机器上都能以相同方式运行。
Docker 采用 client-server(客户端-服务端)架构,通过 REST API 通信:
graph LR
CLI[docker CLI] -->|REST API| D[Docker Daemon<br>docketd]
Compose["Docker Compose"] -->|REST API| D
D --> C[containerd]
C --> R[runc]
R --> Container[容器进程]
D --> |管理| Images[镜像存储]
D --> |管理| Networks[网络]
D --> |管理| Volumes[卷]
classDef client fill:transparent,stroke:#539bf5,color:#adbac7,stroke-width:2px
classDef engine fill:transparent,stroke:#57ab5a,color:#adbac7,stroke-width:2px
classDef runtime fill:transparent,stroke:#e3b341,color:#adbac7,stroke-width:1px
classDef process fill:transparent,stroke:#e5534b,color:#adbac7,stroke-width:2px
classDef resource fill:transparent,stroke:#768390,color:#adbac7,stroke-width:1px
class CLI,Compose client
class D engine
class C,R runtime
class Container process
class Images,Networks,Volumes resource
| 组件 | 说明 |
|---|---|
Docker Client(docker CLI) |
用户与 Docker 交互的入口,将命令通过 REST API 发送给 Daemon |
Docker Daemon(dockerd) |
后台服务进程,负责构建、运行、管理容器和镜像 |
containerd |
容器运行时管理器,负责镜像拉取、容器生命周期管理 |
runc |
OCI 标准的底层运行时,实际创建和运行容器进程 |
理解调用链的价值
排错时,这个调用链能帮你快速定位问题层级:
- docker run 报错 → 检查 Client 与 Daemon 的通信(权限、TCP/Socket)
- 容器启动失败 → 检查 containerd 日志(journalctl -u containerd)
- 运行时崩溃 → 检查 runc 和内核(cgroup/namespace 限制)
Docker 与虚拟机的区别¶
| 对比维度 | Docker 容器 | 虚拟机(VM) |
|---|---|---|
| 隔离级别 | 进程级(共享宿主内核) | 硬件级(独立内核) |
| 启动速度 | 秒级 | 分钟级 |
| 镜像大小 | MB 级(分层共享) | GB 级(完整 OS) |
| 资源开销 | 接近原生性能 | 有虚拟化损耗(5-10%) |
| 安全隔离 | 较弱(共享内核,需注意逃逸风险) | 较强(硬件级隔离) |
| 适用场景 | 微服务、CI/CD、快速伸缩 | 强隔离需求、异构 OS |
graph TB
subgraph 容器方案
H1[Host OS 内核] --> D1[Docker Engine]
D1 --> C1[App A + 依赖]
D1 --> C2[App B + 依赖]
D1 --> C3[App C + 依赖]
end
subgraph 虚拟机方案
H2[Host OS] --> VMM[Hypervisor]
VMM --> G1[Guest OS + App A]
VMM --> G2[Guest OS + App B]
VMM --> G3[Guest OS + App C]
end
classDef engine fill:transparent,stroke:#539bf5,color:#adbac7,stroke-width:2px
classDef hypervisor fill:transparent,stroke:#e5534b,color:#adbac7,stroke-width:2px
classDef app fill:transparent,stroke:#768390,color:#adbac7,stroke-width:1px
class D1 engine
class VMM hypervisor
class C1,C2,C3,G1,G2,G3 app
镜像分层原理¶
Docker 镜像由多个只读层叠加而成,每层只记录与上一层的差异。容器运行时,在镜像顶部添加一个可写层(Container Layer):
分层存储使得多个镜像可以共享相同的底层,节省磁盘空间构建缓存利用分层机制——未变化的层直接复用,加速后续构建联合文件系统(Union File System,如 OverlayFS)将所有层合并为统一视图
🧱 核心概念¶
Docker 的核心概念围绕三个对象展开:镜像(Image)、容器(Container)、仓库(Registry)。
graph LR
A[Dockerfile] -->|docker build| B[镜像 Image]
B -->|docker push| C[仓库 Registry]
C -->|docker pull| B
B -->|docker run| D[容器 Container]
D -->|docker commit| B
classDef source fill:transparent,stroke:#768390,color:#adbac7,stroke-width:1px
classDef image fill:transparent,stroke:#539bf5,color:#adbac7,stroke-width:2px
classDef registry fill:transparent,stroke:#57ab5a,color:#adbac7,stroke-width:1px
classDef container fill:transparent,stroke:#e3b341,color:#adbac7,stroke-width:1px
class A source
class B image
class C registry
class D container
镜像(Image)¶
镜像是一个只读的模板,包含运行应用所需的代码、运行时、库、环境变量和配置文件。镜像采用分层存储结构,每一层只记录相对于上一层的差异,多个镜像可共享相同的底层。
容器(Container)¶
容器是镜像的运行实例。可以把镜像看作类,容器看作对象。容器在镜像的只读层之上增加一个可写层,容器内的所有写操作都发生在这一层。容器停止后,写层的数据会保留;容器删除后,写层数据随之消失(除非使用 Volume)。
仓库(Registry)¶
仓库用于存储和分发镜像。官方公共仓库为 Docker Hub,企业可自建私有仓库(如 Harbor)。
📦 安装与配置¶
- 下载并安装 Docker Desktop for Windows
- 确保已开启 WSL 2 或 Hyper-V
- 安装完成后在终端验证:
配置镜像加速¶
在 Docker Desktop(Windows/Mac)的 Settings → Docker Engine 中,或在 Linux 的 /etc/docker/daemon.json 中添加:
| /etc/docker/daemon.json | |
|---|---|
修改后重启 Docker 服务:
🖼️ 镜像操作¶
搜索与拉取¶
查看与删除¶
导入与导出¶
🚀 容器操作¶
运行容器¶
docker run 是最核心的命令,常用参数如下:
| 参数 | 说明 | 示例 |
|---|---|---|
-d |
后台运行(detached 模式) | docker run -d nginx |
-p 宿主:容器 |
端口映射 | -p 8080:80 |
-v 宿主:容器 |
挂载目录/卷 | -v /data:/app/data |
--name |
指定容器名称 | --name myapp |
-e KEY=VAL |
设置环境变量 | -e SPRING_PROFILES_ACTIVE=prod |
--rm |
容器退出后自动删除 | docker run --rm alpine echo hi |
-it |
交互式终端 | docker run -it ubuntu bash |
--network |
指定网络 | --network mynet |
--restart |
重启策略 | --restart=always |
生命周期管理¶
进入与调试¶
💾 数据持久化¶
容器内的文件在容器删除后会丢失,Docker 提供两种持久化机制:
Volume(推荐 ⭐)¶
Volume 由 Docker 管理,默认存储在 /var/lib/docker/volumes/ 下。
Bind Mount(绑定挂载)¶
将宿主机的指定目录挂载到容器中,适合开发时热更新。
bind mount 注意事项
- 宿主机路径必须使用
绝对路径 - 挂载后容器内该路径的原有文件会被宿主机内容
覆盖 - 生产环境推荐使用 Volume,开发环境可使用 bind mount
tmpfs 挂载(临时文件系统)¶
tmpfs 将数据存储在宿主机内存中,容器停止后数据自动消失。适用于存储临时敏感数据(如会话缓存、加密密钥),避免写入磁盘。
| 参数 | 说明 |
|---|---|
size |
tmpfs 最大容量(如 100m、1g) |
mode |
文件权限模式(如 1777 表示所有用户可读写) |
rw / ro |
读写 / 只读 |
tmpfs 限制
- 仅在 Linux 上可用
- 数据存储在内存中,容器停止即丢失——不能替代持久化存储
- 大量写入可能影响宿主机可用内存
🌐 网络¶
网络模式¶
| 模式 | 说明 |
|---|---|
bridge(默认) |
每个容器分配独立 IP,通过虚拟网桥通信 |
host |
容器直接使用宿主机网络,无端口隔离 |
none |
禁用网络 |
| 自定义 bridge | 同网络内容器可通过容器名互访(推荐) |
📝 Dockerfile¶
Dockerfile 是构建镜像的脚本文件,每条指令创建一个镜像层。
常用指令¶
| 指令 | 说明 |
|---|---|
FROM |
指定基础镜像(必须是第一条指令) |
LABEL |
为镜像添加元数据 |
RUN |
在构建时执行命令,结果提交为新层 |
COPY |
从构建上下文复制文件/目录到镜像 |
ADD |
类似 COPY,额外支持 URL 和解压 tar |
WORKDIR |
设置工作目录(后续指令的相对路径基准) |
ENV |
设置环境变量 |
ARG |
定义构建参数(仅构建时可见) |
EXPOSE |
声明容器监听的端口(仅文档作用) |
VOLUME |
声明匿名卷挂载点 |
USER |
切换运行用户 |
ENTRYPOINT |
设置容器启动时执行的命令(不易被覆盖) |
CMD |
容器默认执行命令(可被 docker run 覆盖) |
HEALTHCHECK |
定义容器健康检查 |
Spring Boot 应用示例¶
构建与推送¶
.dockerignore¶
类似 .gitignore,排除构建上下文中不需要的文件,减少构建时的传输量:
| .dockerignore | |
|---|---|