Docker镜像基本概念与构建指南
一、Docker镜像基本概念
Docker镜像是容器运行的基础,包含应用程序及其运行所需的文件系统、依赖库、环境变量和配置。其核心特性包括:
- 只读性:镜像本身不可修改,容器运行时在镜像层之上创建可写层。
- 分层存储:由多个只读层(Layer)叠加组成,每层对应Dockerfile中的一个指令。
- 可移植性:镜像通过注册中心(如Docker Hub)实现跨环境部署。
二、镜像的分层结构
1. 分层机制原理
- 联合文件系统(UnionFS):将多个目录(层)挂载到同一虚拟目录,上层文件覆盖下层同名文件。
- 层复用性:相同层的镜像可共享存储,减少磁盘占用。例如,基于ubuntu:22.04的多个镜像共享基础层。
- 写时复制(Copy-on-Write):容器修改文件时,仅复制目标层到可写层,不影响原始镜像。
2. 典型分层示例
FROM ubuntu:22.04 # 基础镜像层(Layer 1)
RUN apt-get update # 软件源更新层(Layer 2)
COPY app /opt/app # 文件复制层(Layer 3)
CMD ["/opt/app/start.sh"] # 启动命令层(Layer 4)
每层生成唯一哈希值,修改任意指令会重建后续所有层。
三、构建镜像的详细步骤
1. 编写Dockerfile
# 指定基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 安装依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 8000
# 启动命令
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]
2. 构建镜像
# -t指定镜像标签,.表示构建上下文路径
docker build -t myapp:v1 .
# 查看构建过程日志(显示分层详情)
docker build --progress=plain -t myapp:v1 .
3. 验证与优化
- 检查分层结构:
history myapp:v1
- 多阶段构建(减少镜像体积):
构建阶段
FROM golang:1.20 AS builder
WORKDIR /src
COPY . .
RUN go build -o /app
运行阶段
FROM alpine:3.18
COPY --from=builder /app /app
CMD ["/app"]
四、最佳实践
- 精简基础镜像:优先选择Alpine、Distroless等轻量镜像。
- 合并指令:减少层数,例如将多个RUN合并:
apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*
- 使用.dockerignore:排除无关文件(如node_modules、.git)。
- 定期清理:删除无用镜像和中间层:
system prune -a
五、常见问题
缓存失效:Dockerfile中指令顺序变化会导致后续层缓存失效。
层大小控制:COPY/ADD指令会生成新层,大文件建议通过卷(Volume)挂载。
安全扫描:使用docker scan检测镜像漏洞。