使用注意事项
11.1 安全注意事项
不要用 root 运行容器
# 危险:容器内 root 可以逃逸到宿主机
docker run -it --user root ubuntu bash
# 正确:使用非 root 用户
docker run -it --user 1000:1000 ubuntu bash
# Dockerfile 中设置
RUN useradd -m appuser
USER appuser
不要挂载 Docker Socket
# 极度危险:容器获得 Docker 完整控制权
docker run -v /var/run/docker.sock:/var/run/docker.sock docker
# 这等于给容器 root 权限,可以:
# - 创建特权容器
# - 访问宿主机文件系统
# - 完全控制 Docker daemon
不要使用 —privileged
# 危险:容器获得宿主机所有 capabilities
docker run --privileged ubuntu bash
# --privileged 会:
# - 禁用所有安全机制
# - 可以访问宿主机设备
# - 可以加载内核模块
# 替代方案:只添加必要的 capabilities
docker run --cap-add=NET_BIND_SERVICE nginx
镜像来源审查
# 只从官方或可信来源拉取镜像
docker pull nginx:alpine # 官方镜像
docker pull myregistry/myapp:v1 # 检查来源
# 扫描镜像漏洞
docker scout cves nginx:alpine
trivy image nginx:alpine
敏感数据处理
# 不要在 Dockerfile 中硬编码密钥
ENV MYSQL_PASSWORD=secret123
# 使用环境变量或 secrets
docker run -e MYSQL_PASSWORD= $ecret docker run --secret db_pass
# 不要在镜像中存储私钥
COPY id_rsa /root/.ssh/
# 使用 BuildKit secret mount
RUN --mount=type=secret,id=ssh_key \
cat /run/secrets/ssh_key
11.2 资源限制
内存限制
# 限制容器内存
docker run --memory=512m --name web nginx
# 超过 512MB 会被 OOM Kill
# 内存 + swap 限制
docker run --memory=512m --memory-swap=1g nginx
# swap 可以用 512MB
# 禁用 swap
docker run --memory=512m --memory-swap=512m nginx
CPU 限制
# 限制 CPU 核心数
docker run --cpus=1.5 nginx
# 最多使用 1.5 个核心
# CPU 份额(相对权重)
docker run --cpu-shares=512 nginx # 默认 1024
docker run --cpu-shares=2048 nginx # 2 倍权重
# 绑定 CPU 核心
docker run --cpuset-cpus= "0,1" nginx # 只用核心 0 和 1
PID 限制
# 防止 fork bomb
docker run --pids-limit=100 nginx
# 最多 100 个进程
磁盘限制
# 限制容器可写层大小
docker run --storage-opt size=1G nginx
资源限制检查
# 查看容器资源使用
docker stats web
11.3 日志管理
日志驱动
// daemon.json
{
"log-driver" : "json-file" ,
"log-opts" : {
"max-size" : "10m" ,
"max-file" : "3"
}
}
查看日志
# 容器日志
docker logs web
docker logs -f web # 跟踪
docker logs --tail 100 web # 最后 100 行
docker logs --since 1h web # 最近 1 小时
# 清理日志
docker truncate -s 0 $( docker inspect --format= '{{.LogPath}}' web )
避免日志撑爆磁盘
# 定期清理
docker system prune -f
# 或配置日志轮转(见上文 daemon.json)
11.4 清理策略
# 查看 Docker 磁盘使用
docker system df
docker system df -v
# 清理已停止容器
docker container prune
# 清理悬空镜像
docker image prune
# 清理所有未使用资源
docker system prune -a
docker system prune -a --volumes # 深度清理
# 定期执行(建议 cron)
docker system prune -af --volumes
11.5 权限问题
容器内文件权限
# 宿主机 UID 1000 = 容器内 UID 1000
# 如果容器内以 root 运行,创建的文件在宿主机也是 root
# 解决:统一 UID/GID
docker run --user $( id -u ) : $( id -g ) -v $( pwd ) :/app alpine
# 或在 Dockerfile 中
RUN groupadd -g 1000 appgroup && useradd -u 1000 -g appgroup appuser
USER appuser
Docker Socket 权限
# Docker 组的用户可以免 sudo 使用 docker
sudo usermod -aG docker $USER
# 需要重新登录
# 检查权限
ls -la /var/run/docker.sock
# srw-rw---- 1 root docker
11.6 内核兼容性
cgroups v1 vs v2
# 查看 cgroups 版本
stat -fc %T /sys/fs/cgroup/
# cgroup2fs = v2
# tmpfs = v1
# Docker 20.10+ 支持 cgroups v2
# 某些旧版功能可能不兼容
旧内核限制
# 内核 3.10 不支持某些功能:
# - overlay2 存储驱动(需要 4.0+)
# - 某些 seccomp 功能
# - 部分网络功能
# 检查内核版本
uname -r
Docker 版本兼容性
# 检查 Docker 版本
docker version
# 建议使用 Docker 20.10+ 或更新版本
# 老版本可能缺少重要安全修复
存储驱动兼容性
# 查看当前存储驱动
docker info | grep "Storage Driver"
# 常见存储驱动及内核要求:
# overlay2 -> 内核 4.0+
# devicemapper -> 内核 3.10+
# btrfs -> 内核 3.9+
# zfs -> 内核 2.6.37+
11.7 生产环境最佳实践
镜像管理
# 使用具体版本标签,避免 latest
docker pull nginx:1.25.3-alpine
# 使用多阶段构建减小镜像体积
docker build --target=builder -t myapp:builder .
docker build -t myapp:latest .
容器重启策略
# 容器退出后自动重启
docker run --restart=always nginx
# 只在非正常退出时重启
docker run --restart=unless-stopped nginx
数据持久化
# 使用命名卷而非绑定挂载
docker volume create mydata
docker run -v mydata:/data nginx
# 备份卷数据
docker run --rm -v mydata:/data -v /backup:/backup alpine \
tar czf /backup/mydata.tar.gz -C /data .
# 恢复卷数据
docker run --rm -v mydata:/data -v /backup:/backup alpine \
tar xzf /backup/mydata.tar.gz -C /data
11.8 常见问题排查
容器无法启动
# 查看容器日志
docker logs web
# 常见退出码:
# 0 -> 正常退出
# 1 -> 应用错误
# 137 -> OOM Kill
# 139 -> 段错误
网络不通
# 检查容器网络配置
docker inspect web | grep IPAddress
# 进入容器测试网络
docker exec -it web ping google.com
磁盘空间不足
# 查看磁盘使用
docker system df
# 清理未使用资源
docker system prune -a --volumes
容器内时间不对
# 查看容器时间
docker exec web date
# 同步宿主机时区
docker run -v /etc/localtime:/etc/localtime:ro nginx