Docker
Docker 解决“在我机器上能跑”:打包应用 + 环境成标准镜像。面试主线:镜像分层、容器隔离原理、Dockerfile 优化。
镜像与分层
镜像分层: 只读层共享, 容器加可写层
- 镜像 = 分层只读文件系统(UnionFS),层可复用(同基础镜像只存一份)
- 容器 = 镜像 + 可写层(运行时的修改写这里,删除容器即丢弃)
- 层是缓存单位:构建时层没变就用缓存(Dockerfile 顺序影响构建速度)
容器原理
容器 = Namespace(隔离)+ Cgroups(限制)+ 镜像(文件系统):
| 机制 | 作用 |
|---|---|
| Namespace | 隔离视图:PID/网络/文件系统/用户(进程以为独占) |
| Cgroups | 限制资源:CPU/内存/IO 配额 |
| 联合文件系统 | 分层镜像 + 可写层 |
对比虚拟机:容器共享宿主机内核(无独立内核),隔离是“视图级”,所以轻但隔离弱。
Dockerfile 优化
FROM python:3.12-slim # 1. 小基础镜像
WORKDIR /app
COPY requirements.txt . # 2. 先复制依赖文件(层缓存)
RUN pip install -r requirements.txt # 3. 依赖层(代码变了这层不重建)
COPY . . # 4. 复制代码(放依赖后)
CMD ["uvicorn", "main:app"] # 5. 启动命令| 优化 | 效果 |
|---|---|
| 小基础镜像(slim/alpine) | 镜像小、攻击面小 |
| 依赖先于代码复制 | 命中层缓存,构建快 |
| 多阶段构建 | 构建产物瘦身(编译 → 运行分离) |
| 非 root 运行 | 安全 |
| .dockerignore | 别把 .git/node_modules 打进去 |
网络模式
| 模式 | 行为 |
|---|---|
| bridge(默认) | 容器间内网互通,端口映射暴露 |
| host | 共享宿主机网络(快,端口冲突) |
| none | 无网络(安全隔离) |
| 自定义 bridge | 容器间域名互访(docker compose 默认) |
面试追问
- 镜像分层好处? 层复用(同基础镜像只存一份)+ 构建缓存 + 传输增量
- 容器隔离原理? Namespace(视图隔离)+ Cgroups(资源限制)+ 分层文件系统
- 容器和虚拟机? 容器共享内核进程级隔离(轻),虚拟机独立内核(重但隔离强)
- Dockerfile 怎么优化? 依赖先复制(缓存命中)、小基础镜像、多阶段构建、非 root
- 容器为什么比虚拟机启动快? 不用启动 OS,直接起进程(共享内核)