把容器平台交给多个团队共同使用时,权限管理几乎是最先要面对的问题。Docker 的架构决定了客户端与守护进程之间的信任关系非常强,谁控制了 docker 命令,谁就基本控制了整台宿主机。很多团队在没有做任何隔离的情况下,直接把所有开发者加进 docker 用户组,表面上是提升了效率,实际上是给每个人发了 root 密码。本文从 Docker 的权限模型入手,分析企业场景下的典型风险,并给出一套可落地的权限管理方案。

理解 Docker 的权限模型与风险来源
Docker 采用 C/S 架构,docker 客户端本身只是一个薄薄的壳,真正的操作全部由 dockerd 守护进程完成,而 dockerd 默认以 root 身份运行。这意味着客户端与守护进程之间的通道就是一条特权通道。理解了这一点,就能明白为什么权限管理要围绕两个层面展开:一是谁能够连上这条通道,二是连上之后能执行哪些操作。
第一个层面的风险来自 Unix socket。默认情况下 dockerd 监听 /var/run/docker.sock,只有 root 和 docker 组成员可以读写。网上大量教程会告诉你执行 sudo usermod -aG docker 用户名 来免 sudo 使用 Docker,但在企业环境里这个操作等于直接提权。攻击者只要能访问 docker 组,就可以通过挂载宿主机根目录的方式拿到完整控制权。
# 危险操作演示:docker组成员可以这样做 docker run -v /:/host -it alpine sh # 进入容器后,宿主机文件系统完整暴露在 /host 下 chroot /host # 直接变成宿主机的root
第二个层面的风险来自暴露的 TCP API。为了图方便,有些环境会把 dockerd 配置成监听 2375 端口且不加认证,这等于把 root 权限开放给整个网络,任何能访问该端口的人都可以创建特权容器、挂载任意目录。2375 是无认证端口,2376 才是 TLS 加密端口,这个区别在企业内网也经常被忽视。
常见授权方案对比与选型
针对上述风险,业界的做法大致分为四类,各有适用场景。第一种是保持默认的 socket 授权,即严格管控 docker 组成员。它实现成本最低,适合只有少数运维人员登录宿主机的传统部署模式,缺点是无法做细粒度控制,成员要么全有要么全无。
第二种是 TLS 双向认证。给 dockerd 配置 CA 签发的服务端证书与客户端证书,只有持有合法证书的客户端才能调用 API。这种方案解决了认证问题,适合需要远程管理 Docker 的场景,但仍然做不到授权细分——所有持证客户端权限完全相同,而且证书的签发、轮换、吊销需要配套流程支撑,管理成本不低。
# 以TLS方式启动dockerd dockerd --tlsverify \ --tlscacert=/etc/docker/ca.pem \ --tlscert=/etc/docker/server-cert.pem \ --tlskey=/etc/docker/server-key.pem \ -H=0.0.0.0:2376 # 客户端使用证书访问 docker --tlsverify \ --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \ -H=tcp://docker-host:2376 ps
第三种是在 Docker 前面架设 API 网关,比如开源的 Portus、Harbor 配合 Notary,或者自研的代理层。所有请求先经过网关完成认证与鉴权,再转发给后端 dockerd。这种方式可以实现按用户、按操作的细粒度控制,还能统一记录审计日志,是多团队共享环境的推荐方案。第四种是使用授权插件机制,Docker 原生支持 --authorization-plugin 参数加载第三方插件,在守护进程内部对每个 API 请求做策略判断,适合对性能敏感且希望策略与引擎紧耦合的场景。
| 方案 | 认证能力 | 授权粒度 | 适用场景 |
|---|---|---|---|
| socket + docker组 | 本机用户 | 无 | 单人运维 |
| TLS 双向认证 | 证书 | 无 | 远程管理 |
| API 网关 | 账号体系 | 操作级 | 多团队共享 |
| 授权插件 | 依赖外部 | API级 | 深度定制 |
| rootless 模式 | 本机用户 | 进程级 | 开发环境 |
另外值得一提的是 rootless 模式。较新版本的 Docker 支持让普通用户在自己账户下运行完整的 Docker 环境,守护进程不再需要 root 权限,即使用户拿到完整控制权,影响范围也被限制在其个人账户内。对于开发者本地环境或者 CI 构建节点,rootless 是性价比很高的选择。
基于角色的访问控制设计
在多人共享的平台上,RBAC 是最容易被理解和维护的模型。设计时建议先把角色定义为与职责对齐,而不是与具体命令对齐。典型的角色划分包括:平台管理员,拥有全部权限,负责节点与网络管理;运维人员,可执行容器的创建、启停、日志查看;开发人员,只能查看自己所属项目的容器与日志;审计人员,只读全部资源并访问操作记录。
落地上可以通过自定义 API 网关实现,也可以借助 Harbor 这类企业级仓库的角色体系。Harbor 自带项目管理模型,每个项目下可以设置项目管理员、维护人员、开发者和访客四种角色,并支持对接 LDAP 或 OIDC,直接复用企业已有的账号体系。镜像推送与拉取的权限由项目角色控制,这样就解决了制品分发环节的授权问题。
{
"version": "2",
"policies": [
{
"name": "developer-policy",
"subjects": ["group:developers"],
"actions": ["container-list", "container-logs", "image-pull"],
"resources": ["project:order-service/*"]
},
{
"name": "ops-policy",
"subjects": ["group:ops"],
"actions": ["*"],
"resources": ["*"]
}
]
}
上面的策略文件展示了一个简单的权限模型:开发人员只能对 order-service 项目的资源执行查看类操作,运维则拥有全部权限。策略文件应该纳入版本控制,变更走评审流程,避免权限配置变成一笔糊涂账。同时要建立定期回收机制,人员转岗或离职时及时清理对应权限,这是权限治理中最容易失控的环节。
镜像仓库与运行时的加固清单
权限管理不只是控制谁能执行 docker 命令,镜像供应链同样是重点。企业环境应强制使用私有仓库,禁止直接从公网拉取未审查的镜像。Harbor 可以配置项目级别的镜像签名与漏洞扫描策略,只有通过扫描的镜像才允许部署。配合 Notary 做内容信任后,即使仓库被入侵,攻击者也无法推送未签名的恶意镜像。
运行时层面要注意几个高危配置。首先是特权容器,--privileged 会赋予容器几乎全部的宿主机能力,除非有明确需求否则一律禁止。其次是敏感目录挂载,像 /var/run/docker.sock、/etc、宿主机根目录这类路径的挂载操作应该在平台层拦截。最后是能力裁剪,通过 --cap-drop=ALL 再按需添加最小能力集,配合只读文件系统使用,可以把容器逃逸的攻击面压到最低。
# 最小权限运行示例 docker run -d \ --user=1000:1000 \ --cap-drop=ALL \ --cap-add=NET_BIND_SERVICE \ --security-opt=no-new-privileges \ --read-only \ --tmpfs /tmp \ --pids-limit=100 \ nginx:alpine
最后是审计与监控。无论采用哪种授权方案,都要确保每个 API 调用有迹可循。Docker 本身支持将守护进程日志导出到 syslog 或 json-file 并对接日志平台,网关层的操作记录则应包含操作人、时间、目标资源和结果四个要素。建议配置告警规则,对特权容器创建、危险挂载、异常时间段的批量操作实时告警。权限体系不是一次性建设项目,定期做权限审计和渗透测试,才能真正守住容器平台的安全底线。
Docker权限管理Docker安全 RBAC修改时间:2026-09-13 21:03:09