📘 第28课:安全加固
生产部署
🔒 容器安全加固
默认Docker配置并不足够安全。生产环境需要额外加固,减少攻击面,限制容器权限。
📐 安全层级模型
容器安全四层防御:
┌─────────────────────────────────┐
│ 第4层:运行时安全 │ ← 监控异常行为
├─────────────────────────────────┤
│ 第3层:编排安全 │ ← RBAC、网络策略
├─────────────────────────────────┤
│ 第2层:容器配置安全 │ ← 最小权限、只读文件系统
├─────────────────────────────────┤
│ 第1层:镜像安全 │ ← 最小镜像、漏洞扫描
└─────────────────────────────────┘
🛡️ 镜像安全
# 1. 使用最小基础镜像 ✅
FROM scratch # 静态编译的Go/Rust应用
FROM distroless # 无shell的精简镜像
FROM alpine # 有shell但极小
# 2. 固定镜像版本 ✅
FROM node:20.11.0-alpine3.19 # 精确版本+digest
# 3. 扫描漏洞 ✅
trivy image --severity HIGH,CRITICAL my-app:latest
# 4. 使用多阶段构建 ✅
# 去除构建工具和源码
🔐 容器配置安全
# 1. 非root用户运行 ✅
RUN adduser -D appuser
USER appuser
# 2. 只读文件系统 ✅
docker run --read-only --tmpfs /tmp --tmpfs /run my-app
# 3. 禁用特权模式 ✅
# ❌ docker run --privileged
# ✅ 按需添加能力
docker run --cap-add=NET_BIND_SERVICE my-app
# 4. 丢弃所有能力,按需添加 ✅
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE my-app
# 5. 安全选项 ✅
docker run --security-opt=no-new-privileges my-app
# 6. 资源限制 ✅
docker run -m 512m --cpus=1 my-app
📋 Compose安全配置
# 生产级安全配置 ✅
services:
app:
read_only: true
tmpfs:
- /tmp
- /run
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
🔧 宿主机安全
# 1. 保持Docker更新 ✅
apt-get update && apt-get install docker-ce
# 2. 限制docker组权限
# 只给需要的人
# 3. 启用用户命名空间重映射 ✅
# /etc/docker/daemon.json
{
"userns-remap": "default"
}
# 4. 配置Seccomp默认配置文件
docker run --security-opt seccomp=default.json my-app
# 5. 使用AppArmor配置文件
docker run --security-opt apparmor=docker-default my-app
📊 安全审计
# Docker Bench for Security ✅
docker run --rm --net host --pid host \
--userns host --cap-add 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 /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
docker/docker-bench-security
❓ 常见问题
🏆 本课成就
- 理解容器安全四层防御模型
- 掌握镜像安全最佳实践 ✅
- 学会容器配置安全加固 ✅
- 掌握Compose安全配置 ✅
- 学会Docker Bench安全审计 ✅
📚 深度补充:安全加固进阶要点
【运维与部署阶段】生产环境注意事项
| 要点 | 说明 | 最佳实践 |
| 资源规划 | 根据业务负载合理分配CPU/内存 | 先压测再上线,设置requests和limits |
| 监控告警 | 设置关键指标阈值和告警规则 | Prometheus + AlertManager,5分钟P99延迟告警 |
| 备份策略 | 定期备份关键数据和配置 | 自动化备份脚本 + 异地存储 + 定期恢复演练 |
| 灰度发布 | 新版本逐步放量降低风险 | 金丝雀发布5%→20%→50%→100% |
| 回滚预案 | 部署前确认回滚方案和步骤 | 保留前一版本镜像,数据库迁移向前兼容 |
| 文档更新 | 配置变更必须同步更新文档 | GitOps管理配置,变更即文档 |
| 安全基线 | 遵循CIS Docker Benchmark | 非root运行、只读FS、最小能力 |
| 日志规范 | 结构化日志,统一格式 | JSON格式日志,包含traceId |
常见误区与避坑指南
- 过度配置:不是所有服务都需要高可用,根据实际需求选择架构复杂度,避免过度工程
- 忽略日志:日志是排障的关键,确保日志格式统一、级别合理、采集完整
- 资源超卖:容器资源限制不是摆设,超卖会导致性能下降甚至OOM Kill
- 安全忽视:默认配置不等于安全配置,生产环境必须加固(非root、只读FS、最小能力)
- 监控缺失:没有监控等于盲飞,至少要有基础的健康检查和资源监控
- 手动运维:能自动化的绝不手动,手动操作容易出错且不可追溯
- 忽略网络策略:默认所有容器互通不安全,应按最小权限原则配置网络
进阶阅读与参考
Docker命令速查卡
# 容器生命周期
docker create/start/stop/restart/rm/pause/unpause
docker logs/top/stats/inspect/exec diff
# 镜像构建
docker build/pull/push/tag/rmi/images/history
docker save/load/import/manifest
# 网络与存储
docker network create/ls/inspect/connect/disconnect/rm/prune
docker volume create/ls/inspect/rm/prune
# Docker Compose
docker compose up/down/ps/logs/build/exec
docker compose config/stop/start/scale/top/cp
# 系统维护
docker system df/prune/info
docker builder prune
docker container/prune/image prune
# K8s常用命令
kubectl get/describe/logs/exec/apply/delete
kubectl rollout status/undo/history
kubectl scale/autoscale/set
本阶段知识脉络
运维与部署阶段知识体系:
核心概念 → 实操演练 → 最佳实践 → 故障排查
每一课都遵循:概念讲解 → 命令实操 → 代码示例 → 常见问题 → 练习巩固
确保学完即能上手,理论实践并重。
生产环境检查清单
| 类别 | 检查项 | 命令/方法 |
| 安全性 | 容器非root运行 | docker exec <c> whoami |
| 只读文件系统 | docker run --read-only |
| 最小能力集 | docker inspect --format '{{.HostConfig.CapAdd}}' |
| 可靠性 | 健康检查配置 | docker inspect --format '{{.State.Health}}' |
| 重启策略 | docker inspect --format '{{.HostConfig.RestartPolicy}}' |
| 资源限制 | docker stats --no-stream |
| 可观测性 | 日志收集 | 日志驱动+集中式平台 |
| 指标监控 | Prometheus+cAdvisor |
| 链路追踪 | Jaeger/Zipkin |
| 备份 | 数据卷备份 | 定期tar备份到远程存储 |
| 配置版本化 | GitOps管理所有配置 |
SRE关键指标(SLI/SLO)
| 指标 | 定义 | 典型SLO |
| 可用性 | 成功请求/总请求 | 99.9% |
| 延迟 | 请求处理时间P99 | <200ms |
| 错误率 | 5xx响应比例 | <0.1% |
| 吞吐量 | QPS/TPS | 根据业务设定 |
| MTTR | 平均恢复时间 | <15分钟 |
| MTBF | 平均故障间隔 | 根据业务设定 |
实战案例:故障排查流程
# Step 1: 检查容器状态
docker ps -a # 查看所有容器
docker inspect <container> # 查看详细配置
# Step 2: 查看日志
docker logs --tail 100 <container> # 最近100行日志
docker logs --since 1h <container> # 最近1小时
# Step 3: 进入容器排查
docker exec -it <container> sh # 进入容器shell
# Step 4: 检查资源
docker stats --no-stream # 资源使用概览
docker system df # 磁盘使用
# Step 5: 网络排查
docker network ls # 网络列表
docker exec <c> ping <target> # 网络连通性
docker exec <c> nslookup <svc> # DNS解析
# Step 6: 检查健康状态
docker inspect --format '{{.State.Health}}' <c>
docker inspect --format '{{.State.ExitCode}}' <c>
docker inspect --format '{{.State.OOMKilled}}' <c>
Dockerfile模板:多语言通用
# 通用最佳实践模板
FROM alpine:3.19 AS builder
# ... 构建步骤 ...
FROM alpine:3.19
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/output .
USER appuser
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1
EXPOSE 8080
CMD ["./app"]
Docker Compose健康检查模板
services:
app:
build: .
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 512M