创建安全 Docker 容器需从用户身份、Linux 能力、资源、网络和命名空间五方面做减法:用非 root 用户(USER 或 --user)、--cap-drop=ALL 加白名单能力、启用用户命名空间映射、限制资源与网络、禁用 --privileged 等危险选项。

创建带有安全限制的 Docker 容器,核心是避免默认的高权限运行模式,从用户身份、Linux 能力、资源、网络和命名空间五个维度主动收紧权限。不是加功能,而是做减法——只保留应用真正需要的部分。
用非 root 用户运行容器
镜像默认常以 root 启动,一旦被攻破就可能影响宿主机。推荐显式指定普通用户 ID:
- 构建镜像时在 Dockerfile 中添加 USER 1001:1001(避免使用 0)
- 运行时强制覆盖:用 --user 1001:1001 参数,即使镜像没设 USER 也生效
- 注意:若需绑定 80/443 等特权端口,可在启动时加 --cap-add=NET_BIND_SERVICE,而非用 root
丢弃默认能力,按需授权
Docker 默认赋予容器部分 Linux capabilities(如 CAP_SYS_ADMIN),极易被滥用于逃逸。应彻底清空再加白名单:
- 启动命令中加上 --cap-drop=ALL 移除全部能力
- 仅追加必需项,例如:--cap-add=NET_BIND_SERVICE(绑定低端口)、--cap-add=CHOWN(改文件属主)
- 禁用新特权:--security-opt no-new-privileges,防止进程后续提权
启用用户命名空间映射(UserNS)
这是根治“容器 root = 宿主机 root”风险的关键机制。它让容器内 UID 1000 映射为宿主机上一个无权限的普通 UID:
- 宿主机需开启内核支持:sysctl -w user.max_user_namespaces=15000
- 启动容器时加 --userns=host(若 daemon 已配置 default-userns-mode=host)
- 更彻底的做法是直接运行 rootless Docker(普通用户启动 dockerd-rootless.sh),天然隔离
限制资源与网络暴露
资源不限制会导致 DoS 攻击;网络不收敛则扩大攻击面:
- CPU 和内存硬限制:--cpus="1.0" --memory="512m" --memory-swap="512m"
- 禁止访问敏感设备:--device-read-bps /dev/sda:1mb --read-only(挂载为只读)
- 网络最小化:--network=none(完全断网),或 --network=bridge + -p 8080:80 显式暴露端口,禁用 -P 自动映射
禁用危险选项,加固运行时
有些参数看似方便,实则大幅削弱隔离性,应明确禁用:
- 绝对不用 --privileged —— 它等同于给容器开了 root 闸门
- 避免 --pid=host、--ipc=host、--uts=host,防止命名空间共享导致信息泄露或干扰
- 敏感路径不挂载:不映射 /proc、/sys、/dev、/var/run/docker.sock 到容器内
不复杂但容易忽略:安全不是靠单个开关,而是组合策略。比如只改 USER 不丢 cap,或只限内存却开 privileged,都形同虚设。关键是在启动命令里把这几类参数一起写全,一次成型。


















