Files
docker_practice/10_ops/security
2026-02-09 11:34:35 -08:00
..
2026-02-09 09:32:05 -08:00
2026-02-09 09:32:05 -08:00
2026-02-09 11:34:35 -08:00
2026-02-09 11:34:35 -08:00
2026-02-09 11:34:35 -08:00
2026-02-09 11:34:35 -08:00
2026-02-09 11:34:35 -08:00

安全

容器安全是生产环境部署的核心考量。本章介绍 Docker 的安全机制和最佳实践。

容器安全的本质

核心问题:容器共享宿主机内核,隔离性弱于虚拟机。如何在便利性和安全性之间取得平衡?

虚拟机安全模型:                容器安全模型:
┌─────────────────┐            ┌─────────────────┐
│   Guest OS      │            │    容器进程      │
├─────────────────┤            │   (共享内核)     │
│   Hypervisor    │◄── 隔离边界└────────┬────────┘
├─────────────────┤                     │
│   Host OS       │            ┌────────┴────────┐
└─────────────────┘            │   Namespace     │◄── 隔离边界
                               │   Cgroups       │
完全隔离(性能损耗)            │   Capabilities  │
                               └─────────────────┘
                               进程隔离(轻量但需加固)

核心安全机制

1. 命名空间Namespace

提供进程、网络、文件系统等资源的隔离:

Namespace 隔离内容 安全作用
PID 进程 容器看不到其他进程
NET 网络 独立网络栈
MNT 文件系统 独立的根目录
USER 用户 容器 root ≠ 宿主机 root
IPC 进程通信 隔离共享内存
UTS 主机名 独立主机名

详见 命名空间 章节。

2. 控制组Cgroups

限制容器的资源使用,防止资源耗尽攻击:

## 限制内存(超出会被 OOM Kill

$ docker run -m 512m myapp

## 限制 CPU

$ docker run --cpus=1.5 myapp

## 限制磁盘 I/O

$ docker run --device-write-bps /dev/sda:10mb myapp

3. 能力机制Capabilities

Linux 将 root 权限拆分为多个细粒度的能力。Docker 默认禁用危险能力:

能力 说明 默认状态
CAP_NET_ADMIN 网络管理 禁用
CAP_SYS_ADMIN 系统管理 禁用
CAP_SYS_PTRACE 进程追踪 禁用
CAP_CHOWN 更改文件所有者 启用
CAP_NET_BIND_SERVICE 绑定低端口 启用
## 删除所有能力,只添加需要的

$ docker run --cap-drop=all --cap-add=NET_BIND_SERVICE myapp

## 查看容器的能力

$ docker exec myapp cat /proc/1/status | grep Cap

镜像安全

使用可信镜像

运行以下命令:

## ✅ 使用官方镜像

$ docker pull nginx

## ✅ 使用经过验证的镜像

$ docker pull bitnami/nginx

## ⚠️ 谨慎使用未知来源镜像

$ docker pull randomuser/suspicious-image

漏洞扫描

扫描镜像中的已知安全漏洞:

## Docker Scout官方工具

$ docker scout cves nginx:latest
$ docker scout recommendations nginx:latest

## Trivy开源工具

$ trivy image nginx:latest

## Snyk商业工具

$ snyk container test nginx:latest

镜像签名验证

使用 Docker Content Trust (DCT) 验证镜像来源:

## 启用镜像签名验证

$ export DOCKER_CONTENT_TRUST=1

## 此后的 pull/push 会验证签名

$ docker pull myregistry/myimage:latest

运行时安全

1. 非 root 用户运行

笔者强调:这是最重要的安全实践之一。

FROM node:22-alpine

## 创建非 root 用户

RUN addgroup -g 1001 appgroup && \
    adduser -u 1001 -G appgroup -D appuser

## 设置工作目录权限

WORKDIR /app
COPY --chown=appuser:appgroup . .

## 切换用户

USER appuser

CMD ["node", "server.js"]

或在运行时指定:

$ docker run -u 1001:1001 myapp

2. 只读文件系统

运行以下命令:

## 根文件系统只读

$ docker run --read-only myapp

## 需要写入的目录使用 tmpfs

$ docker run --read-only --tmpfs /tmp --tmpfs /var/run myapp

3. 禁用特权模式

运行以下命令:

## ❌ 绝对不要在生产环境使用

$ docker run --privileged myapp

## ✅ 只添加必要的能力

$ docker run --cap-add=SYS_TIME myapp

4. 限制资源

运行以下命令:

$ docker run \
    -m 512m \                    # 内存限制
    --cpus=1 \                   # CPU 限制
    --pids-limit=100 \           # 进程数限制
    --ulimit nofile=1024:1024 \  # 文件描述符限制
    myapp

5. 网络隔离

运行以下命令:

## 禁用网络(适用于不需要网络的任务)

$ docker run --network=none myapp

## 使用自定义网络隔离

$ docker network create --internal isolated_net
$ docker run --network=isolated_net myapp

Dockerfile 安全实践

1. 使用精简基础镜像

Dockerfile 内容如下:

## ✅ 好:使用精简镜像

FROM node:22-alpine        # ~50MB
FROM gcr.io/distroless/nodejs  # ~20MB

## ❌ 差:使用完整镜像

FROM node:22               # ~1GB
FROM ubuntu:24.04          # ~78MB

2. 多阶段构建

Dockerfile 内容如下:

## 构建阶段

FROM node:22 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

## 生产阶段(不包含开发依赖和源码)

FROM node:22-alpine
COPY --from=builder /app/dist /app
USER node
CMD ["node", "/app/server.js"]

3. 不存储敏感信息

Dockerfile 内容如下:

## ❌ 错误:敏感信息写入镜像

ENV DB_PASSWORD=secret123
COPY .env /app/

## ✅ 正确:运行时传入

## docker run -e DB_PASSWORD=xxx 或使用 Docker Secrets

具体内容如下:

4. 固定依赖版本

Dockerfile 内容如下:

## ✅ 固定版本

FROM node:22.12.0-alpine3.21
RUN apk add --no-cache curl=8.5.0-r0

## ❌ 使用 latest

FROM node:latest
RUN apk add curl

安全扫描清单

部署前检查:

检查项 命令/方法
漏洞扫描 docker scout cvestrivy
非 root 运行 检查 Dockerfile 中的 USER
资源限制 检查 -m, --cpus 参数
只读文件系统 检查 --read-only
无特权模式 确认没有 --privileged
最小能力 检查 --cap-drop=all
网络隔离 检查网络配置
敏感信息 确认无硬编码密码

高级安全方案

Seccomp 系统调用过滤

限制容器可以使用的系统调用:

$ docker run --security-opt seccomp=/path/to/profile.json myapp

AppArmor / SELinux

使用强制访问控制:

$ docker run --security-opt apparmor=docker-default myapp

安全容器gVisor / Kata

需要更强隔离时:

## 使用 gVisor 运行时

$ docker run --runtime=runsc myapp

软件供应链安全

随着软件供应链攻击日益频繁,仅保障运行时安全已不足够。

1. SBOM软件物料清单

SBOM 类似于食品的配料表,列出了容器镜像中包含的所有软件包及其版本。

  • 生成 SBOM: 使用 docker buildx build --sbomdocker scout sbom
  • 管理 SBOM: 确保持续监控 SBOM 中的组件是否存在新披露的漏洞。

2. 镜像签名Sigstore / Notary v2

确保镜像在构建后未被篡改,且确实来自可信的发布者。

  • Cosign: Sigstore 项目的一部分,用于签署和验证容器镜像。
## 签署镜像

$ cosign sign --key cosign.key myimage:tag

## 验证镜像

$ cosign verify --key cosign.pub myimage:tag

3. SLSASupply-chain Levels for Software Artifacts

遵循 SLSA 框架,确保构建过程的完整性,例如使用 GitHub Actions 等受控环境进行构建,而非在开发者本地机器上构建发布。


本章小结

安全措施 重要程度 实现方式
非 root 运行 USER 指令
漏洞扫描 docker scout, trivy
资源限制 -m, --cpus
只读文件系统 --read-only
最小能力 --cap-drop=all
镜像签名 Docker Content Trust

延伸阅读