Docker: 容器安全最佳实践

最后更新:2026-08-26

容器安全不是可选项——从镜像到运行时,每一层都需要加固。

1. 你将学到


2. 一个安全审计的故事

(1) 痛点:安全审计 28 项告警

Charlie 的团队收到安全审计报告:28 个告警项包括"容器以 root 运行"(高危)、"镜像有 15 个高危 CVE"(高危)、"Secret 写在环境变量里"(中危)。审计评分只有 45 分,必须修复到 80 分以上才能通过合规。

(2) 系统化安全加固的解法

Charlie 带团队一条条修复:非 root 用户、Trivy 扫描修复 CVE、Secret 改用 Docker Secret、seccomp 限制系统调用。

BASH
# Security hardening: non-root + minimal capabilities
docker run -d \
  --user 1000:1000 \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --security-opt no-new-privileges \
  --read-only \
  myapp:1.0

(3) 收益:审计评分 45→92

系统化加固后审计评分从 45 提升到 92,所有高危项修复。


3. 容器安全层次模型

(1) 安全分层

100%
graph TB
    L6["6. Secret 管理<br/>Docker Secret / Vault"] --> L5["5. 网络安全<br/>Network isolation / TLS"]
    L5 --> L4["4. 运行时安全<br/>seccomp / AppArmor / capabilities"]
    L4 --> L3["3. 镜像安全<br/>扫描 / 签名 / 最小化"]
    L3 --> L2["2. Docker 守护进程安全<br/>TLS / 用户权限"]
    L2 --> L1["1. 主机安全<br/>OS 加固 / 内核更新"]

(1) 安全等级对照

等级 加固措施 效果
0 默认配置 ❌ 大量告警
1 非 root + latest tag ⚠️ 基础安全
2 + 镜像扫描 + 固定版本 ✅ 中等安全
3 + 最小能力 + seccomp ✅ 良好安全
4 + DCT + Secret 管理 ✅ 高安全
5 + 网络隔离 + 审计日志 ✅ 最高安全

4. 镜像漏洞扫描

▶ 示例:Trivy 扫描镜像(难度⭐⭐)

BASH
# Install Trivy (Linux)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh

# Scan an image for vulnerabilities
trivy image nginx:1.25-alpine

# Scan with severity filter
trivy image --severity HIGH,CRITICAL nginx:1.25-alpine

# Scan and output JSON
trivy image --format json --output report.json myapp:1.0
💻 输出(节选):

TEXT 📖 仅展示
nginx:1.25-alpine (alpine 3.19.0)
=========================
Total: 5 (HIGH: 2, CRITICAL: 0)

┌──────────┬────────────┬──────────┬──────────┬─────────────────┐
│ Library  │ Vulnerability│ Severity │ Version  │ Fixed Version   │
├──────────┼────────────┼──────────┼──────────┼─────────────────┤
│ libcurl  │ CVE-2023-xxxx│ HIGH     │ 8.4.0    │ 8.5.0           │
│ openssl  │ CVE-2023-yyyy│ HIGH     │ 3.1.3    │ 3.1.4           │
└──────────┴────────────┴──────────┴──────────┴─────────────────┘

▶ 示例:docker scout 扫描(难度⭐⭐)

BASH
# Docker Scout (Docker Desktop built-in)
docker scout quickview nginx:latest

# Detailed CVE report
docker scout cves nginx:latest

# Compare two images
docker scout compare --from nginx:1.24 --to nginx:1.25

5. 最小权限原则

(1) Linux Capabilities

能力 作用 常见需求
NET_BIND_SERVICE 绑定 <1024 端口 Web 服务(80/443)
NET_RAW 原始网络包 ping / 网络调试
CHOWN 修改文件所有者 文件管理
SETUID / SETGID 切换用户 某些系统工具
ALL 所有能力 ❌ 不要使用

▶ 示例:--cap-drop 最小权限(难度⭐⭐⭐)

BASH
# Drop ALL capabilities, add only what's needed
docker run -d \
  --name secure-app \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --security-opt no-new-privileges \
  -p 80:8080 \
  myapp:1.0
参数 作用
--cap-drop ALL 移除所有 Linux 能力
--cap-add NET_BIND_SERVICE 只添加绑定低端口的能力
--security-opt no-new-privileges 禁止提权(setuid/setgid)
--read-only 文件系统只读(需 tmpfs 辅助)
🔒 安全: --privileged 给容器几乎所有主机权限——永远不要在生产环境使用。用 --cap-drop ALL + 按需 --cap-add 是最小权限原则的体现。**


6. 运行时安全

▶ 示例:seccomp 限制系统调用(难度⭐⭐⭐)

BASH
# Run with a custom seccomp profile
docker run -d \
  --security-opt seccomp=chrome.json \
  --name browser \
  chromium:latest

(1) Docker 默认 seccomp

Docker 自带默认 seccomp 配置文件,已禁用约 44 个危险系统调用(如 mountkeyctladd_key)。大多数应用在默认配置下可正常运行。

▶ 示例:Docker Content Trust 签名(难度⭐⭐)

BASH
# Enable DCT for the current session
export DOCKER_CONTENT_TRUST=1

# Push a signed image
docker push myorg/myapp:v1.0

# Pull: DCT verifies the signature
docker pull myorg/myapp:v1.0

# Pull unsigned image: DENIED (with DCT enabled)
docker pull myorg/myapp:unsigned
# Error: No trust data for unsigned

7. Secret 安全管理

(1) 三种 Secret 管理方式对比

方式 安全级别 可见性 适用场景
环境变量 (-e) ❌ 低 docker inspect 可见 开发环境
Volume 文件 (-v) ⚠️ 中 主机文件可见 过渡方案
Docker Secret ✅ 高 加密存储,运行时挂载 Swarm 生产环境
外部 Vault ✅ 最高 集中管理 + 审计 企业级

8. CIS Docker Benchmark

▶ 示例:docker bench security 基线检查(难度⭐⭐)

BASH
# Run CIS Docker Benchmark check
docker run --rm --net host --pid host \
  --userns host --cap-drop audit_control \
  -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
  -v /etc:/etc:ro \
  -v /lib/systemd/system:/lib/systemd/system:ro \
  -v /usr/bin/containerd:/usr/bin/containerd:ro \
  -v /usr/bin/runc:/usr/bin/runc:ro \
  -v /usr/lib/systemd:/usr/lib/systemd:ro \
  -v /var/lib:/var/lib:ro \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  docker/docker-bench-security
💻 输出(节选):

TEXT 📖 仅展示
[INFO] 1 - Host Configuration
[INFO] 1.1  - Ensure Docker is up to date
[PASS] 1.2  - Ensure only trusted users are allowed to control Docker daemon
[WARN] 1.4  - Ensure a separate partition for containers has been created

[INFO] 4 - Container Images
[PASS] 4.1  - Ensure a user for the container has been created
[WARN] 4.7  - Ensure HEALTHCHECK instructions have been added
[WARN] 4.9  - Ensure COPY is used instead of ADD

9. 完整示例:生产容器全栈加固

BASH
# ============================================
# Complete walkthrough: Production container hardening
# From audit score 45 → 92
# ============================================

# Step 1: Scan for vulnerabilities
trivy image --severity HIGH,CRITICAL myapp:1.0
# Fix: update base image, pin versions

# Step 2: Run with maximum security constraints
docker run -d \
  --name hardened-app \
  --user 1000:1000 \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --security-opt no-new-privileges \
  --security-opt seccomp=default.json \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid \
  --tmpfs /run:rw,noexec,nosuid \
  -v app-logs:/app/logs \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  --health-cmd="curl -f http://localhost:8080/health || exit 1" \
  --health-interval=30s \
  --health-retries=3 \
  -p 8080:8080 \
  myapp:hardened

# Step 3: Verify security configuration
docker inspect hardened-app --format='
User: {{.Config.User}}
ReadOnly: {{.HostConfig.ReadonlyRootfs}}
Capabilities: {{.HostConfig.CapAdd}}
NoNewPrivileges: {{.HostConfig.SecurityOpt}}
'

# Step 4: Run CIS benchmark
docker run --rm ... docker/docker-bench-security

# Step 5: Re-scan after hardening
trivy image myapp:hardened

❓ 常见问题

Q Docker 容器能完全隔离吗?
A 不能。容器共享主机内核,内核漏洞可能导致容器逃逸。但容器提供了进程级隔离(namespace + cgroup + seccomp + AppArmor),大幅缩小攻击面。关键:不要用 --privileged,不要以 root 运行,及时更新内核。
Q --privileged 有什么风险?
A --privileged 赋予容器几乎所有主机权限:访问所有设备、修改内核参数、加载内核模块、绕过 seccomp/AppArmor。这基本等于在主机上直接运行程序。永远不要在生产环境使用 --privileged。
Q 镜像漏洞扫描用什么工具?
A Trivy(开源,最流行)或 Docker Scout(Docker Desktop 内置)。CI/CD 中集成:构建后自动扫描,发现 CRITICAL 漏洞时阻止部署。建议每天扫描生产镜像,新 CVE 发布后及时重建。
Q Secret 放在环境变量有什么问题?
A 三个风险:① docker inspect 任何人都可见环境变量;② 子进程继承环境变量;③ 日志可能意外打印环境变量。Docker Secret(Swarm)加密存储,运行时挂载为临时文件,更安全。非 Swarm 环境用 HashiCorp Vault。
Q rootless 模式安全吗?
A 非常安全。rootless Docker 以普通用户运行整个 Docker 守护进程,即使 Docker 本身有漏洞,攻击者也只有普通用户权限。但 rootless 模式有一些限制(无 --privileged、网络配置受限)。生产环境推荐 rootless。

📖 小节


📝 作业

  1. 基础题(难度⭐):运行 Docker Bench Security 扫描本机,记录 WARN 级别的告警项。
  2. 进阶题(难度⭐⭐):用 Trivy 扫描一个已有镜像,修复所有 CRITICAL 级别的 CVE。
  3. 挑战题(难度⭐⭐⭐):创建一个带 seccomp 限制的容器,验证限制生效(如禁止 mount 系统调用)。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏