Docker FAQ
内容:基础概念、镜像、容器、网络、存储、Compose、Registry、优化、安全、生产运维实践。
Docker 是一个基于 容器技术 的应用打包、分发、部署平台,解决了:
- 应用环境一致性问题
- 打包与迁移困难
- 部署流程复杂
核心优势:构建一次,到处运行。
镜像是 只读模板,类似:
- 一个文件系统快照
- 包含程序和运行环境
镜像可分为:
- 基础镜像(如 ubuntu、python)
- 应用镜像(基于基础镜像构建)
容器是镜像的运行实例,包含:
- 进程
- 文件系统写层
- 网络隔离
- cgroups 资源限制
容器是轻量级“进程级虚拟化”。
| 对比项 | Docker | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源开销 | 低 | 高 |
| 隔离方式 | 进程级(namespace + cgroups) | 完整操作系统 |
| 镜像体积 | 小 | 大 |
| 部署方式 | 快速便携 | 笨重 |
Dockerfile 是用于 构建镜像的脚本文件,包含:
FROM
RUN
COPY
CMD
EXPOSE
ENTRYPOINT
OCI = Open Container Initiative
规范包括:
- 镜像规范(Image Spec)
- 运行时规范(Runtime Spec,如 runc)
Docker 已遵从 OCI。
镜像是由多层文件系统组成,每条指令(RUN/COPY)会生成一层。
好处:
- 层可复用(提高构建速度)
- 节省空间
- 构建时可以利用缓存
COPY – 复制文件(推荐)
ADD – 附加功能:
- 自动解压 tar
- 支持 URL 下载
最佳实践:永远优先使用 COPY。
| 指令 | 作用 |
|---|---|
| CMD | 默认命令,可被覆盖 |
| ENTRYPOINT | 主命令,不会被覆盖 |
最佳实践:
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]
- WORKDIR:设置工作目录
- ENV:设置环境变量
- EXPOSE:声明镜像监听的端口(仅文档意义)
- 使用 slim/alpine/distroless
- 多阶段构建(multi-stage)
- 合并 RUN
- 清理缓存(apt clean / npm cache clean)
- 使用 .dockerignore
- 合理使用缓存
- 优先 COPY package.json / go.mod
- 多阶段构建
- 使用 BuildKit
- -d 后台运行
- -p 端口映射
- -v 数据卷挂载
- –name 容器名
- –network 指定网络
- –restart=always 自动拉起
- -e 环境变量
- 内核
- 网络(通过 namespace 隔离)
- 文件系统挂载点(mount)
- CPU/内存限制(cgroups)
docker exec -it <container> /bin/bash
docker logs -f
- no
- always
- unless-stopped
- on-failure
| 模式 | 说明 | | bridge | 默认模式,私网 | | host | 使用宿主机网络 | | none | 无网络 | | container | 共用另一个容器的网络 |
docker run -p 8080:80 nginx
- 左:宿主机
- 右:容器
在 Swarm 或 Kubernetes 中跨主机通信的网络。
容器与宿主机共享的持久数据目录。
好处:
- 多容器共享数据
- 容器销毁后数据保留
- 性能优于 bind mount
| 对比项 | Volume | Bind mount |
|---|---|---|
| 性能 | 高 | 中等 |
| 灵活性 | 中 | 高 |
| 隔离 | 高 | 低(直接访问宿主机目录) |
| Portability | 好 | 差 |
docker system prune -a
docker volume prune
- Docker Hub:公开仓库(SaaS)
- Registry:企业私有仓库
docker run -d -p 5000:5000 registry:2
docker tag myapp registry:5000/myapp
docker push registry:5000/myapp
Compose 是一个 多容器编排工具,用于定义和运行多容器应用。
services:
app:
image: xxx
build: .
ports:
- "8080:80"
volumes:
- ./data:/data
docker compose up -d # 启动
docker compose down # 删除容器、网络
- 使用更小基础镜像
- 精简镜像层
- 避免在容器入口执行复杂脚本
- 使用 alpine/slim
- 多阶段构建
- dockerignore
- 清理缓存
- 避免频繁写入容器文件系统
- 使用 volume
- 避免 journal/log 在容器中堆积
- 镜像不要使用 latest
- 不要在容器内运行 root
- 使用 seccomp、AppArmor
- 关闭不必要的 capability
- 不要把 secrets 写入镜像
不同容器的进程互不可见。
- namespace(pid/net/ipc/uts/mount)
- cgroups(CPU/内存限制)
- 联合文件系统(AUFS/overlayfs)
docker stats
docker top <container>
进入容器后:
top
ps aux
- docker system df
- 容器写入大量日志
- volume 写入过多数据
- overlay2 文件膨胀
- 检查 Dockerfile 指令顺序
- 使用 –progress=plain –no-cache 观察详细日志
- 检查 dockerignore
方案:
- 运行多个版本的容器
- 通过 Nginx/LB 配置权重
- Kubernetes Deployment(滚动升级)
| 对比项 | Swarm | Kubernetes |
|---|---|---|
| 功能丰富 | ❌ | ✅ |
| 社区支持 | 弱 | 强 |
| 学习成本 | 低 | 高 |
| 企业使用量 | 低 | 极高 |
如今企业基本都运行 Kubernetes。