解决 Windows 10 启动 Docker 时端口被占用问题


背景

由于 Windows 的 Docker 是依赖 Hyper-V 的,但在启用 Hyper-V 后,会产生各种端口莫名被占用的问题。

例如启动 Docker 时会报错(端口随机在一个小范围内波动的):

Error starting userland proxy: Bind for 0.0.0.0:50022: unexpected error Permission denied.

电脑重启几次之后,以上报错可能会消失,好像一切又恢复正常。

Docker 的服务端口会在 50000 - 50059 中随机分配

分析

表面看上去像是端口 50022 被占用,但是当在 PowerShell 中查看端口占用情况时:

netstat -ano | findstr 50022

发现这个端口并未被某个进程使用。这说明这些端口可能是被系统保留了,比如 Hyper-V。

根据 List of TCP and UDP port numbers 的说明,tcp/udp 端口号被分为 3 段:

端口类型 范围 用途
周知端口 0 - 1023 提供广泛使用的网络服务类型的系统进程使用
注册端口 1024 - 49151 给用户进程或应用程序使用
动态端口 49152 - 65535 用于私有或定制服务、临时目的以及临时端口的自动分配

Service overview and network port requirements for Windows,Windows 将 49152 - 65535 划分为 动态端口

Hyper-V 会将动态端口中的几段范围的端口保留给自己使用,用户的应用程序无法使用这些端口。

可以执行命令 netsh int ipv4 show dynamicport tcp 查看动态端口范围:

再执行命令 netsh int ipv4 show excludedport tcp 查看被系统保留的端口(其中标记 * 的端口被 Administrator 排除):

可以看到,50000 - 50059 等范围端口被系统保留了(即用户不可用),且 Administrator 没有排除任何端口,导致用户启动 Docker 时,当端口落到这些系统保留范围内时,就会因为端口被占用而启动失败。

解决

知道原因后就很容易解决了:只需要用 Administrator 排除 50000 - 50059 范围的端口,使得 Docker 可以使用即可。

具体方法为:

  1. 停止 Docker 进程(最好重启电脑)
  2. 在 powershell 执行以下命令设置排除端口范围:
# 保留 50000 - 50059 这 60 个端口给应用程序使用
netsh int ipv4 add excludedportrange protocol=tcp startport=50000 numberofports=60
  1. 重启电脑,使得排除策略生效
  2. 执行命令 netsh int ipv4 show excludedport tcp 可以看到 50000 - 50059 已被排除(不被系统保留),此时即可成功启动 Docker

参考文档


文章作者: EXP
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 EXP !
 上一篇
AI 全自动考勤原理与实现 AI 全自动考勤原理与实现
相信很多人都有上下班忘记考勤签到的问题,这里结合 Mediapipe 这个号称可以达到亚毫秒级的人脸识别开源工具,可以有效地解决这个问题,同时 ADB 也能适用于大部分的手机的考勤 APP ...
2022-11-20
下一篇 
Docker 设置代理指引(Windows 系统) Docker 设置代理指引(Windows 系统)
背景当我们在国内使用 docker 时,因为 GFW 的原因,有时会非常慢甚至连接不上。 一般 docker 命令会遇到以下两种异常情况: error pulling image configuration: unexpected EOF
2022-11-20
  目录