Docker设置普通用户运行容器无权限报错反而挂起的原因
问题根因
这个现象和Docker安全配置、Linux特权端口限制没有关系,核心是busybox:1.29内置的nc命令参数逻辑和常规发行版的nc不一致,它从始至终都没有尝试绑定80端口,自然不会触发权限拒绝报错。
具体逻辑拆解:
- BusyBox 1.29 内置的轻量nc工具,在监听模式(加
-l参数)下不支持-p参数指定监听端口,监听端口需要直接作为位置参数传入,正确监听80端口的写法是nc -l 80 0.0.0.0。-p参数在BusyBox nc里仅用于客户端连接模式,指定发起连接时使用的源端口。 - 按照你Dockerfile里的配置,容器最终执行的命令是
nc -l -p 80 0.0.0.0。nc解析参数时,会把-p 80识别为客户端模式的源端口配置,这个配置在监听模式下会被直接忽略;同时-p参数会把后面的80当成自己的参数值消耗掉,不会把80识别为要监听的端口。 - 解析完所有选项后,nc拿到的位置参数只剩
0.0.0.0,无法转换成合法的数字端口,此时nc会默认绑定0端口——0端口不属于1-1023的特权端口范围,普通用户有权限绑定,作用是向内核申请分配一个随机的空闲高端口(通常在32768-60999区间)。监听地址没有额外指定的话,nc默认就会绑定0.0.0.0。 - 整个绑定过程操作的是普通用户有权限的高端口,不会触发权限校验失败,nc启动后会一直前台驻留等待连接,所以容器表现为无输出挂起状态,和你预期的权限报错不符。
你可以启动容器后执行docker exec <容器ID> netstat -tulpn验证,会看到nc实际监听的是一个随机分配的高端口,根本没有占用80端口。
内容的提问来源于stack exchange,提问作者qqqqqqq
相关产品推荐
相关产品推荐

