2. Docker 基础回顾:镜像与容器概念、Dockerfile 基础、常用命令

在深入多租户隔离之前,必须牢固掌握 Docker 最核心的两个抽象:镜像(Image)与容器(Container)。本章将快速梳理这两个概念的本质、Dockerfile 的编写规范以及日常高频命令,为后续构建隔离镜像和运行安全容器打下基础。

2.1 镜像与容器的核心关系

镜像是一个只读的、分层构建的模板,包含运行应用所需的代码、运行时、库、环境变量和配置文件。容器则是镜像的运行实例,在镜像层之上添加一个可写层,并拥有独立的进程、网络和文件系统命名空间。

关键理解:镜像 = 类(Class),容器 = 对象(Instance)。一个镜像可以启动多个容器,每个容器之间默认隔离。
多租户视角:在多租户场景中,每个租户通常使用独立的镜像(或镜像标签),并通过容器实现资源与权限的硬隔离。
镜像与容器分层结构 容器可写层(Writable Layer) 镜像层 3:应用代码与配置 镜像层 2:依赖库与运行时 镜像层 1:基础操作系统层 容器实例特征 • 独立的进程命名空间(PID) • 独立的网络栈(IP/端口) • 独立的文件系统挂载 • 独立的用户与权限(UID) • 资源限制(CPU/内存/磁盘)

2.2 Dockerfile 基础

Dockerfile 是一个文本文件,包含一系列指令,用于自动化构建镜像。每条指令都会在镜像中创建一个新的只读层。掌握以下核心指令即可应对绝大多数多租户镜像构建场景。

指令 作用 多租户注意事项
FROM 指定基础镜像 尽量使用官方精简镜像(如 alpine),减少攻击面
RUN 执行命令并创建新层 合并多个 RUN 指令以减少镜像层数
COPY / ADD 将文件从构建上下文复制到镜像 避免复制敏感文件(如 .env、密钥)
WORKDIR 设置工作目录 使用非 root 用户目录,增强安全性
USER 指定运行用户 必须切换到非 root 用户,防止容器逃逸
EXPOSE 声明容器监听端口 仅暴露必要端口,减少网络暴露面
ENV 设置环境变量 避免硬编码租户敏感信息
CMD / ENTRYPOINT 定义容器启动命令 推荐使用 exec 格式,确保信号正确传递
安全红线:在多租户环境中,Dockerfile 中禁止使用 --privileged 或挂载宿主机敏感目录(如 /var/run/docker.sock),否则租户容器可能突破隔离边界。

2.2.1 多租户安全 Dockerfile 示例

# 使用精简基础镜像
FROM alpine:3.19

# 安装必要工具,合并 RUN 减少层数
RUN apk add --no-cache curl ca-certificates \
    && addgroup -S appgroup \
    && adduser -S appuser -G appgroup

# 设置工作目录
WORKDIR /app

# 复制应用文件(注意权限)
COPY --chown=appuser:appgroup ./app /app

# 切换到非 root 用户
USER appuser

# 声明端口
EXPOSE 8080

# 启动命令(exec 格式)
CMD ["/app/start.sh"]

2.3 常用命令速查

以下命令覆盖了镜像与容器的全生命周期管理,是多租户运维的必备技能。

2.3.1 镜像管理命令

命令 说明 多租户场景示例
docker build -t <tag> . 构建镜像 docker build -t registry.tenant-a.com/app:v1 .
docker images 列出本地镜像 配合 --filter 按仓库筛选租户镜像
docker rmi <image> 删除镜像 清理不再使用的租户镜像,释放磁盘
docker tag <src> <target> 标记镜像 为租户镜像打上版本标签
docker push <image> 推送镜像到仓库 推送到租户隔离的私有仓库

2.3.2 容器生命周期命令

命令 说明 多租户场景示例
docker run -d --name <name> <image> 启动容器 docker run -d --cpus=1 --memory=512m --name tenant-a app:v1
docker ps 列出运行中的容器 使用 --filter name=tenant-* 查看特定租户
docker stop <container> 停止容器 优雅停止租户容器,发送 SIGTERM
docker rm <container> 删除容器 回收租户资源前先 stop 再 rm
docker logs <container> 查看日志 排查租户应用问题
docker exec -it <container> sh 进入容器 调试租户容器内部环境

2.3.3 资源限制与隔离命令

# 限制 CPU 和内存
docker run -d --cpus=1.5 --memory=256m --memory-swap=512m nginx

# 限制磁盘 I/O
docker run -d --device-read-bps /dev/sda:1mb --device-write-bps /dev/sda:1mb nginx

# 使用只读根文件系统(增强安全)
docker run -d --read-only --tmpfs /tmp nginx

# 指定用户运行(禁止 root)
docker run -d --user 1000:1000 nginx
最佳实践:在多租户环境中,始终使用 --cpus、--memory、--read-only 和 --user 参数启动容器,确保每个租户的资源边界和安全边界清晰。
Docker 命令工作流:从构建到运行 Dockerfile docker build 镜像仓库 docker run 运行容器 多租户关键命令组合 docker build -t registry.tenant-a.com/app:v1 . docker run -d --cpus=1 --memory=256m --read-only --user 1000:1000 registry.tenant-a.com/app:v1

2.4 本章小结

  • 镜像是只读模板,容器是运行实例,两者通过分层文件系统关联。
  • Dockerfile 中的 USER、WORKDIR、COPY --chown 指令对多租户安全至关重要。
  • 常用命令覆盖构建、推送、运行、限制和调试,每个命令在多租户场景下都有特定的安全参数。
  • 资源限制参数(--cpus、--memory、--read-only)是租户隔离的第一道防线。