3. Docker 基础回顾:Dockerfile、镜像分层、容器生命周期、网络模式与数据卷

在深入可观测性租户隔离之前,必须夯实 Docker 核心基础。本章从 Dockerfile 构建、镜像分层机制、容器生命周期、网络模式 与 数据卷 五个维度展开,为后续的隔离策略与安全评估提供底层知识支撑。

3.1 Dockerfile 与镜像分层

Dockerfile 是定义镜像构建过程的声明式脚本,每一行指令对应一个只读层(Layer)。分层机制是镜像复用与缓存加速的核心。

3.1.1 典型 Dockerfile 结构

# 基础镜像层
FROM alpine:3.18

# 元数据层
LABEL maintainer="sre-team@example.com" \
      version="1.0.0"

# 环境变量层
ENV APP_HOME=/opt/app \
    LOG_LEVEL=info

# 工作目录层
WORKDIR $APP_HOME

# 依赖安装层
RUN apk add --no-cache python3 py3-pip

# 代码复制层
COPY ./app ./app
COPY ./requirements.txt .

# 依赖安装层(利用缓存)
RUN pip install --no-cache-dir -r requirements.txt

# 端口暴露层
EXPOSE 8080

# 启动命令层
CMD ["python3", "./app/main.py"]

3.1.2 镜像分层原理

层类型 特性 缓存条件
基础层(FROM) 只读,从 Registry 拉取 镜像摘要不变即命中
指令层(RUN/COPY/ADD) 只读,每层生成一个中间镜像 指令字符串与上下文未变
可写层(容器层) 容器运行时创建,销毁即丢失 不参与缓存
关键认知: 镜像层是只读的,容器启动时在顶部叠加一个可写层。所有写操作(日志、临时文件)都发生在可写层,这也是容器重启后数据丢失的根本原因。
Docker 镜像分层结构 容器可写层(临时) Layer 5: CMD ["python3", "./app/main.py"] Layer 4: EXPOSE 8080 Layer 3: RUN pip install -r requirements.txt Layer 2: COPY ./app ./app Layer 1: FROM alpine:3.18(基础层) 分层特性 • 只读层共享 • 层叠缓存加速 • 层 ID 由内容哈希决定 • 修改上层不影响下层 • 推送/拉取按层增量 • 容器层不持久化 • 层数建议 ≤ 30

3.2 容器生命周期

容器从创建到销毁经历明确的状态转换。理解生命周期是排查故障、设计健康检查与优雅关闭的基础。

3.2.1 状态转换图

状态 说明 常见触发命令
created 镜像已加载,文件系统就绪,未启动进程 docker create
running 主进程正在执行,可接受网络请求 docker start / docker run
paused 进程被 SIGSTOP 挂起,CPU 不分配 docker pause
exited 主进程终止(正常退出或崩溃) docker stop / 进程退出
dead 容器已停止且资源未完全清理 docker kill 强制终止
可观测性实践: 在容器退出前,通过 STOPSIGNAL 和 HEALTHCHECK 指令配合生命周期钩子,可以优雅地采集退出前的日志与指标,避免数据丢失。
容器生命周期状态机 created running paused exited dead start pause unpause stop / exit kill rm -f 注:exited 状态可通过 docker start 重新进入 running,dead 状态不可恢复

3.3 网络模式

Docker 网络模式决定了容器间通信、端口映射与隔离边界。在租户隔离场景中,网络模式的选择直接影响安全域划分。

模式 隔离级别 IP 分配 适用场景
bridge(默认) 容器间隔离,通过 docker0 桥接 172.17.0.0/16 子网 单机多容器通信
host 无隔离,共享宿主机网络栈 宿主机 IP 高性能网络、监控 Agent
none 完全隔离,无网络接口 无 离线计算、安全沙箱
overlay 跨主机容器通信,VXLAN 封装 自定义子网 Swarm/K8s 集群
macvlan 容器拥有独立 MAC 地址 物理网络子网 遗留应用、网络策略绑定
安全评估要点: 在租户隔离架构中,禁止使用 --network=host 模式,因为它会绕过 iptables 规则与网络命名空间隔离。推荐使用自定义 bridge 网络 + 子网划分实现租户级网络隔离。

3.4 数据卷(Volume)

数据卷是 Docker 持久化数据的标准机制,独立于容器生命周期。在可观测性场景中,日志、指标与 Trace 数据的持久化依赖 Volume 的正确配置。

3.4.1 三种挂载方式对比

类型 管理方式 性能 隔离性 推荐场景
Volume Docker 管理(/var/lib/docker/volumes/) 高 好 数据库、日志持久化
Bind Mount 用户指定宿主机路径 高 差(依赖宿主机路径) 开发调试、配置文件注入
tmpfs 内存中,不写入磁盘 极高 好 敏感数据、临时缓存

3.4.2 可观测性数据卷实践

# 创建专用卷用于日志采集
docker volume create --name observability-logs \
  --label tenant=team-a \
  --label environment=production

# 挂载到容器
docker run -d \
  --name app-service \
  --mount source=observability-logs,target=/var/log/app \
  --mount type=tmpfs,target=/tmp/cache,tmpfs-size=100m \
  my-app:1.0.0

# 查看卷元数据(用于审计)
docker volume inspect observability-logs --format '{{.Labels}}'
租户隔离建议: 为每个租户创建独立的 Volume,并附加 tenant 与 environment 标签。在可观测性管道中,通过 Volume 标签路由日志与指标到对应的租户存储桶,实现数据面隔离。

3.5 本章小结

  • Dockerfile 的每一行指令生成一个只读层,合理排序可最大化缓存命中率。
  • 镜像分层 是镜像复用与增量推送的基础,容器可写层不持久化。
  • 容器生命周期 包含 created → running → paused → exited → dead 五个状态,健康检查应覆盖 running 与 paused 状态。
  • 网络模式 中自定义 bridge 与 overlay 是租户隔离的首选,host 模式禁止用于多租户环境。
  • 数据卷 通过 Volume 标签实现租户级数据隔离,tmpfs 适用于临时敏感数据。