Docker Desktop 报 Wsl/CommandTimedOut、wsl -l -v 卡死、0x80080005 的完整排查与解决

Docker Desktop 启动超时排查:一次 WslService 卡死导致的 WSL CommandTimedOut 故障

最近在 Windows 开发环境中启动 Docker Desktop 时,遇到了一个看起来像是 Docker Desktop 自身不稳定的问题。

Docker Desktop 启动失败,并提示:

复制代码
A timeout occurred while preparing WSL distro for Docker Desktop.
Restart Docker Desktop.

listing WSL distros: running wslexec:
An error occurred while running the command.

DockerDesktop/Wsl/CommandTimedOut:
c:\windows\system32\wsl.exe -l -v --all:
exit status 1

第一反应很容易是:

Docker Desktop 又挂了?

但经过逐层排查后发现,这次故障实际上并不发生在 Docker Engine、containerd,甚至还没有真正进入 Docker Desktop 的 Linux Backend 启动阶段。

真正卡住的是 Windows 侧的 WSL Service(WslService)

最终通过强制结束异常的 wslservice.exe 进程并重新启动 WslService,在不重启 Windows、不重装 Docker Desktop、不重置 WSL 的情况下恢复正常。

本文完整记录这次问题的定位过程。


一、故障现象

Docker Desktop 启动时出现:

复制代码
DockerDesktop/Wsl/CommandTimedOut

其中最关键的信息不是 DockerDesktop,而是下面这条命令:

复制代码
c:\windows\system32\wsl.exe -l -v --all

Docker Desktop 在启动 WSL Backend 之前,需要先查询当前系统中的 WSL Distribution。

正常情况下执行:

复制代码
wsl -l -v --all

应该立即返回类似:

复制代码
  NAME              STATE           VERSION
* Ubuntu            Stopped         2
  docker-desktop    Stopped         2

但是在本次故障中:

复制代码
wsl -l -v --all

直接卡住,没有任何返回。

这实际上是整个排查过程中最重要的一个信息。

因为这意味着:

Docker Desktop 报超时只是表象,真正发生超时的是 Windows 的 wsl.exe


二、第一步:脱离 Docker Desktop 检查 WSL

遇到 Docker Desktop 的 WSL 错误时,不建议第一时间:

复制代码
重装 Docker Desktop
Reset to factory defaults
删除 docker-desktop
重装 WSL

这些操作不仅比较重,而且有可能破坏原有 Docker 环境。

应该首先脱离 Docker Desktop,直接测试 WSL:

复制代码
wsl --status
wsl -l -v --all

结果:

复制代码
wsl -l -v --all

持续卡住。

到这里实际上已经可以初步判断:

复制代码
Docker Desktop
       │
       │ 调用
       ▼
    wsl.exe
       │
       ▼
   WSL 管理层
       │
       X
     卡住

也就是说,此时继续研究 Docker Engine、containerd、Docker 镜像、Docker 网络已经没有意义。

因为 Docker Desktop 甚至还没有走到那个阶段。


三、尝试关闭 WSL,出现 0x80080005

通常 WSL 出现临时异常时,一个非常有效的恢复方法是:

复制代码
wsl --shutdown

它会关闭当前 WSL2 Utility VM。

但本次执行后直接报错:

复制代码
服务器运行失败
错误代码: Wsl/0x80080005

即:

复制代码
Wsl/0x80080005
Server execution failed

这时候问题进一步明确了。

现在已经同时出现:

复制代码
wsl -l -v --all
        ↓
       卡死

wsl --shutdown
        ↓
Wsl/0x80080005

这说明已经不是某个 Linux Distribution 中的应用程序卡住,而是 Windows 侧负责管理 WSL 的组件出现异常。


四、检查 WSL 和 Hyper-V 服务状态

接下来检查 Windows 服务:

复制代码
Get-Service WslService -ErrorAction SilentlyContinue
Get-Service LxssManager -ErrorAction SilentlyContinue
Get-Service vmcompute
Get-Service hns

现场结果:

复制代码
Status   Name          DisplayName
------   ----          -----------
StopP... WslService    WSL Service

Stopped  LxssManager   LxssManager

Running  vmcompute     Hyper-V 主机计算服务

Running  hns           主机网络服务

这里出现了一个非常关键的异常:

复制代码
WslService
StopP...

也就是:

复制代码
STOP_PENDING

与此同时:

复制代码
vmcompute = Running
hns       = Running

说明 Hyper-V Host Compute Service 和 Host Network Service 本身仍然处于运行状态。

继续检查进程:

复制代码
Get-Process wsl,wslservice,vmmem,vmmemWSL -ErrorAction SilentlyContinue

得到:

复制代码
Handles  NPM(K)  PM(K)  WS(K)  CPU(s)   Id     ProcessName
-------  ------  -----  -----  ------   --     -----------
274      16      5332   18472  0.11     22768  wslservice

此时系统中:

复制代码
wslservice.exe   存在
vmmemWSL         不存在

问题开始高度集中到 WslService


五、确认 WslService 卡在 STOP_PENDING

进一步通过 Windows Service Control Manager 查看:

复制代码
sc.exe queryex WslService

结果:

复制代码
SERVICE_NAME: WslService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
        PID                : 22768

这个结果基本坐实了问题。

WslService 已经收到了停止请求,进入:

复制代码
STOP_PENDING

但对应进程:

复制代码
PID = 22768

始终没有退出。

尤其值得注意的是:

复制代码
CHECKPOINT : 0x0
WAIT_HINT  : 0x0

正常 Windows Service 如果停止过程需要较长时间,通常会通过 CheckPoint 和 WaitHint 向 Service Control Manager 汇报停止进度。

而当前服务长时间停留在:

复制代码
STOP_PENDING

且没有进一步进展。

这已经非常符合"服务退出流程卡死"的特征。


六、检查 vmcompute

为了确认是不是底层 Hyper-V Compute Service 同时出现问题,又检查:

复制代码
sc.exe queryex vmcompute

结果:

复制代码
SERVICE_NAME: vmcompute
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 4  RUNNING
        PID                : 26008

也就是说:

复制代码
WslService    STOP_PENDING    ← 异常

vmcompute     RUNNING         ← 正常

hns           RUNNING         ← 正常

因此此时没有必要贸然:

复制代码
重置 Hyper-V
重启 HNS
删除虚拟网络
重新启用 VirtualMachinePlatform

故障范围已经可以进一步缩小到:

WslService 自身,或者 WslService 正在等待的某个 WSL 管理对象。


七、强制结束卡死的 WslService

由于 WslService 已经无法正常停止,最终决定强制结束其进程:

复制代码
taskkill /PID 22768 /F

然后再次检查:

复制代码
sc.exe queryex WslService

状态变为:

复制代码
SERVICE_NAME: WslService
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 1067  (0x42b)
        PID                : 0

这里出现:

复制代码
WIN32_EXIT_CODE : 1067

并不奇怪。

因为我们刚刚通过 taskkill /F 强制结束了服务进程,所以 Service Control Manager 会认为服务进程发生了异常终止。

这并不是新的故障。

关键是:

复制代码
STATE : STOPPED
PID   : 0

说明之前卡死的 wslservice.exe 已经真正退出。


八、重新启动 WslService

接下来:

复制代码
Start-Service WslService

再次查看:

复制代码
sc.exe queryex WslService

得到:

复制代码
SERVICE_NAME: WslService
        STATE              : 4  RUNNING
        WIN32_EXIT_CODE    : 0  (0x0)
        PID                : 29920

注意这里 PID 已经发生变化:

复制代码
原 PID:22768
新 PID:29920

说明 Windows 已经启动了一个新的 wslservice.exe


九、验证 WSL 是否恢复

先不启动 Docker Desktop,直接执行:

复制代码
wsl --status

正常返回:

复制代码
默认分发: Ubuntu
默认版本: 2

然后:

复制代码
wsl -l -v --all

立即返回:

复制代码
  NAME              STATE           VERSION
* Ubuntu            Stopped         2
  docker-desktop    Stopped         2

至此 WSL 管理面完全恢复。

整个过程中:

  • 没有重启 Windows

  • 没有重装 Docker Desktop

  • 没有重装 WSL

  • 没有删除 docker-desktop

  • 没有 Reset Docker Desktop

  • 没有修改 Hyper-V

  • 没有破坏 Docker 数据

只是将卡死的:

复制代码
wslservice.exe

强制结束并重新启动。


十、完整故障链

回过头来看,这次故障链已经非常清晰:

复制代码
Windows
   │
   ▼
WslService
   │
   ├── 正常情况下负责 WSL 管理
   │
   ▼
进入 STOP_PENDING
   │
   │
   └── wslservice.exe 无法完成退出
           │
           ├──────────────┐
           │              │
           ▼              ▼
  wsl -l -v --all    wsl --shutdown
           │              │
           ▼              ▼
         卡死        0x80080005
           │
           │
           ▼
     Docker Desktop
           │
           │ 启动时执行
           ▼
  wsl.exe -l -v --all
           │
           ▼
       一直等待
           │
           ▼
DockerDesktop/Wsl/CommandTimedOut

因此:

复制代码
DockerDesktop/Wsl/CommandTimedOut

故障结果,并不是这次故障的真正根因。


十一、为什么 WslService 会卡死?

这里需要区分两个概念:

1. 已经确认的直接原因

已经可以确定:

WslService 收到了停止请求并进入 STOP_PENDING,但服务进程没有完成退出。

因此所有需要通过 WSL Service 完成的操作都出现异常。

包括:

复制代码
wsl -l -v
wsl --status
wsl --shutdown

以及 Docker Desktop 对:

复制代码
wsl.exe

的调用。

2. 为什么退出流程没有完成?

这一层仅凭当前现场还不能百分之百确定。

WSL2 并不是简单的 Linux 进程,它背后涉及:

复制代码
Windows
   │
   ├── WslService
   │
   ├── Hyper-V Host Compute Service
   │
   ├── HNS
   │
   ├── Utility VM
   │
   ├── VHDX
   │
   ├── Hyper-V Socket / IPC
   │
   └── Linux Kernel

因此 WslService 在启动或关闭 WSL 环境时,需要协调多个对象。

如果某个对象没有按照预期返回,就可能出现类似:

复制代码
WslService
     │
     ▼
等待某个 WSL/VM/IPC/VHDX 对象
     │
     ▼
一直没有完成
     │
     ▼
STOP_PENDING

比较常见的诱因包括:

  • WSL 自身的状态机异常

  • WSL 版本回归或 Bug

  • Docker Desktop 与 WSL 的特定版本组合问题

  • Windows 睡眠/休眠后的虚拟化状态异常

  • Docker Desktop 长时间运行后 WSL 状态异常

  • Windows Update 或 WSL Update 后组件状态不一致

  • WSL Utility VM、VHDX 或 IPC/vSocket 退出过程中异常

  • 内存或 I/O 压力导致 WSL Backend 状态异常

所以不能简单地得出:

Docker Desktop 不稳定。

更准确的描述应该是:

Docker Desktop 的 WSL2 Backend 依赖 Windows WSL 管理栈,因此 WSL 管理服务发生异常时,最终往往会以 Docker Desktop 启动失败的形式表现出来。


十二、以后再遇到,可以快速定位

以后看到:

复制代码
DockerDesktop/Wsl/CommandTimedOut

第一件事不是重装 Docker Desktop。

先执行:

复制代码
wsl -l -v --all

情况一:正常返回

那么继续调查 Docker Desktop 自身:

复制代码
docker-desktop distro
Docker Backend
containerd
Docker Engine
网络
磁盘

情况二:命令本身卡住

问题已经下沉到:

复制代码
Windows / WSL

尝试:

复制代码
wsl --shutdown

如果成功,再重新启动 Docker Desktop。

情况三:出现 0x80080005

例如:

复制代码
服务器运行失败
错误代码: Wsl/0x80080005

马上检查:

复制代码
sc.exe queryex WslService

如果发现:

复制代码
STATE : 3  STOP_PENDING

并且长期不恢复,再获取 PID:

复制代码
PID : XXXXX

强制结束:

复制代码
taskkill /PID XXXXX /F

然后:

复制代码
Start-Service WslService

最后:

复制代码
wsl --status
wsl -l -v --all

如果全部正常,再启动 Docker Desktop。


十三、建议保留的一套快速诊断命令

以后再遇到 Docker Desktop + WSL 异常,可以先执行:

复制代码
wsl --status
wsl -l -v --all

Get-Service WslService -ErrorAction SilentlyContinue
Get-Service LxssManager -ErrorAction SilentlyContinue
Get-Service vmcompute
Get-Service hns

Get-Process wsl,wslservice,vmmem,vmmemWSL -ErrorAction SilentlyContinue

sc.exe queryex WslService
sc.exe queryex vmcompute

这几条命令基本可以快速回答几个问题:

复制代码
是 Docker 的问题?
        │
        ├── 还是 WSL 的问题?
        │
        ├── WslService 是否卡死?
        │
        ├── WSL VM 是否仍存在?
        │
        └── vmcompute 是否正常?

比一上来重装 Docker Desktop 有效得多。


十四、如果问题反复出现,还要继续追根因

本文解决的是:

如何从 Docker Desktop 的 Wsl/CommandTimedOut 定位到 WslService STOP_PENDING,并恢复环境。

但如果同一台机器频繁出现 WslService 卡死,就不能满足于每次:

复制代码
taskkill

而应该进一步检查版本:

复制代码
wsl --version
winver

同时记录 Docker Desktop 版本。

还可以在故障现场检查 Windows Event Log:

复制代码
Get-WinEvent -LogName "Microsoft-Windows-Hyper-V-Compute-Admin" -MaxEvents 50 |
    Format-List TimeCreated,Id,LevelDisplayName,Message

以及:

复制代码
Get-WinEvent -LogName "System" -MaxEvents 200 |
    Where-Object {
        $_.ProviderName -match "Service Control Manager|Hyper-V|Host-Network-Service"
    } |
    Select-Object TimeCreated,ProviderName,Id,LevelDisplayName,Message

如果能够把:

复制代码
WslService 卡死时间
        +
Windows Event Log
        +
WSL Version
        +
Windows Build
        +
Docker Desktop Version

对应起来,就有机会继续判断到底属于:

复制代码
WSL Bug
Windows/Hyper-V Bug
Docker Desktop 触发问题
特定版本兼容性问题
休眠/恢复问题
资源压力问题

而不是长期停留在"Docker Desktop 偶尔不稳定"的结论上。


十五、总结

这次问题最值得记录的并不是最终执行了:

复制代码
taskkill /PID 22768 /F
Start-Service WslService

而是整个定位思路。

看到:

复制代码
DockerDesktop/Wsl/CommandTimedOut

不要被 DockerDesktop 这个前缀误导。

真正关键的是错误信息里的:

复制代码
wsl.exe -l -v --all

于是脱离 Docker Desktop 单独执行该命令。

发现:

复制代码
wsl -l -v --all
→ 卡死

继续:

复制代码
wsl --shutdown
→ Wsl/0x80080005

再检查:

复制代码
WslService
→ STOP_PENDING

同时:

复制代码
vmcompute
→ RUNNING

hns
→ RUNNING

最终将故障范围从:

复制代码
Docker Desktop 启动失败

逐步缩小到了:

复制代码
wslservice.exe 卡死

强制结束旧进程并重新启动服务后:

复制代码
WslService → RUNNING
wsl --status → 正常
wsl -l -v --all → 正常

问题解决。

这也是排查 Windows + WSL2 + Docker Desktop 问题时非常重要的一条原则:

先确定哪一层真正失败,再处理哪一层。不要因为错误最终显示在 Docker Desktop 上,就直接重装 Docker。

Docker Desktop 只是 WSL2 的消费者之一。

wsl.exe 自己都已经无法正常工作时,应该首先解决 WSL,而不是 Docker。

相关推荐
其实防守也摸鱼1 小时前
CVE / NVD 漏洞数据库详解:从入门到实战
大数据·运维·人工智能·web安全·自动化
翼龙云_cloud1 小时前
阿里云国际代理商:2026零基础如何使用轻量应用服务器搭建独立站?
运维·服务器·阿里云·云计算
新时代牛马1 小时前
Linux 内存映射mmap 完整篇:从用户态 API、VMA 到缺页与驱动实现
linux·运维·服务器
cui_hao_nan1 小时前
Kubernetes 核心概念总结
云原生·容器·kubernetes
芷栀夏2 小时前
开源菜谱工具 cook 实践:按食材筛选菜谱、随机推荐,并用 Docker 部署到本地
docker·容器·开源
张洛闻Eren2 小时前
云原生k8s【第八课】: ETCD 备份与恢复
linux·运维·docker·kubernetes·k8s
新时代牛马2 小时前
Linux 守护进程与服务完整篇:从daemonize、systemd 到pidfile 与排障
linux·运维·服务器
毕竟是shy哥11 小时前
vs code连接远程服务器docker环境及配置免密登录
服务器·docker·vs code
IT大白鼠11 小时前
Ingress 与 Ingress-Controller:K8s 七层 HTTP 反向代理技术详解与实践
http·容器·kubernetes