2026-02-22

Docker 容器隔离与运行时边界整理

回顾了一次多服务部署中的容器隔离实践,重点包括网络暴露面、卷挂载、最小权限与镜像构建边界。

DockerInfraOps

Docker 容器隔离与运行时边界整理

做小型部署时,很多人会把所有服务直接放进同一个 compose 编排里,然后默认认为“容器化了就安全”。实际情况通常没有这么乐观。容器只是隔离起点,不是隔离结论。

1. 先列出每个服务真正需要暴露什么

外网只应该暴露反向代理层,数据库、缓存、内部任务服务默认都不需要直接对宿主机开放端口。

只要端口暴露多了,后面的安全面和排查复杂度都会一起增加。

2. 卷挂载范围要尽可能小

挂载目录时我现在尽量避免把整个项目目录直接塞进容器。尤其是 Nginx、任务调度和第三方工具容器,更适合只挂最少的配置或数据路径。

这样做至少能减少三类问题:

  • 容器误改宿主文件
  • 权限边界变得模糊
  • 日志和缓存混进仓库目录

3. 镜像构建时不要带无关依赖

运行时镜像里残留太多构建工具、包管理缓存和调试二进制,既增加镜像大小,也增加攻击面。多阶段构建虽然不复杂,但收益很稳定。

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
CMD ["node", "server.js"]

4. 容器用户不要默认 root

这个原则听起来很基础,但在很多内部项目里仍然经常被忽略。只要不是必须,运行时服务应该切到非 root 用户。

5. 内部服务之间也要考虑边界

容器之间默认互通时,很容易把“内部可信”当成理所当然。实际上,只要一个服务被利用,整组内部网络就可能变成横向移动入口。

在能力允许的情况下,我会更偏向:

  • 明确区分公网入口和内部服务
  • 限制宿主挂载路径
  • 让敏感服务不暴露宿主端口

6. 日志和临时文件不要无限增长

Compose 默认日志策略如果不收紧,磁盘很容易被慢慢吃满。这个问题不是马上爆发,但一旦撞上,排查很浪费时间。

7. 最后再谈“安全加固”

真正有效的安全往往不是后期临时加几条规则,而是从镜像、用户、端口和卷挂载开始就尽量收窄边界。

总结

容器化最怕“形式上有隔离,实际上边界很宽”。把暴露面、卷挂载和运行用户这些基础问题先处理好,后面的维护成本会低很多。