Docker 安全实践
本章将介绍 Docker 容器安全的最佳实践,帮助你构建和运行安全的容器化应用。
镜像安全
使用官方镜像
dockerfile
# ✅ 使用官方镜像
FROM node:20-alpine
# ❌ 避免使用来源不明的镜像
FROM random-user/node-custom固定镜像版本
dockerfile
# ✅ 使用具体版本标签
FROM node:20.11.1-alpine3.19
# ⚠️ 避免使用 latest(可能引入未知变更)
FROM node:latest镜像漏洞扫描
bash
# 使用 Docker Scout 扫描
docker scout cves myimage:latest
# 使用 Trivy 扫描
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image myimage:latest最小化镜像
dockerfile
# 使用多阶段构建,最终镜像只包含运行时必需的文件
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o main .
FROM scratch
COPY --from=builder /app/main /main
CMD ["/main"]容器运行安全
使用非 root 用户
dockerfile
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm ci
# 创建并切换到非 root 用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
CMD ["node", "server.js"]只读文件系统
bash
# 以只读模式运行容器
docker run --read-only \
--tmpfs /tmp \
--tmpfs /var/run \
myapp:latest限制容器权限
bash
# 删除所有 Linux capabilities
docker run --cap-drop ALL myapp:latest
# 只添加必要的 capabilities
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp:latest
# 禁止容器获取新权限
docker run --security-opt no-new-privileges myapp:latest资源限制
bash
# 限制内存和 CPU
docker run -m 256m --cpus 0.5 myapp:latest
# 限制进程数
docker run --pids-limit 100 myapp:latest
# 限制重启次数
docker run --restart on-failure:5 myapp:latest网络安全
网络隔离
bash
# 创建隔离网络
docker network create --internal backend-net
# 前端网络(可访问外部)
docker network create frontend-net
# 数据库只在内部网络
docker run -d --name db --network backend-net postgres:16
# 应用连接两个网络
docker run -d --name app --network frontend-net myapp
docker network connect backend-net app限制容器间通信
bash
# 禁用默认 bridge 网络的容器间通信
# 编辑 /etc/docker/daemon.json
{
"icc": false
}敏感信息管理
使用 Docker Secrets(Swarm 模式)
bash
# 创建 secret
echo "my-password" | docker secret create db_password -
# 在服务中使用
docker service create \
--name myapp \
--secret db_password \
myapp:latest环境变量安全
bash
# ❌ 不要在 Dockerfile 中硬编码敏感信息
ENV DB_PASSWORD=secret123
# ✅ 运行时通过环境变量传入
docker run -e DB_PASSWORD=secret123 myapp
# ✅ 使用 .env 文件
docker run --env-file .env myapp
# ✅ 使用 Docker Compose secrets
# docker-compose.yml
services:
app:
image: myapp
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt.dockerignore 排除敏感文件
# .dockerignore
.env
.env.*
*.key
*.pem
secrets/
.gitDockerfile 安全检查清单
| 检查项 | 说明 |
|---|---|
| ✅ 使用官方基础镜像 | 确保镜像来源可信 |
| ✅ 固定版本标签 | 避免意外引入变更 |
| ✅ 使用非 root 用户 | 降低容器逃逸风险 |
| ✅ 多阶段构建 | 减少攻击面 |
| ✅ 不包含敏感信息 | 密码、密钥等不写入镜像 |
| ✅ 最小化安装包 | 只安装必要的依赖 |
| ✅ 使用 COPY 而非 ADD | ADD 有自动解压等隐含行为 |
| ✅ 设置 HEALTHCHECK | 监控容器健康状态 |
Docker Daemon 安全
启用 TLS
bash
# 生成 CA 和证书后配置 daemon.json
{
"tls": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem",
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}日志审计
bash
# 配置日志驱动
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
}
}本章小结
Docker 安全需要从镜像构建、容器运行、网络配置和敏感信息管理等多个层面综合考虑。遵循最小权限原则,定期扫描漏洞,是保障容器安全的关键。
关键要点:
- 使用官方镜像并固定版本
- 容器以非 root 用户运行
- 限制容器权限和资源
- 网络隔离和通信控制
- 敏感信息不写入镜像