文章原创不易,转载请注明来源 ,谢谢!
一、 问题
周末在家,给自己的老的台式机安装DockerDesktop。
电脑配置是
处理器 Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz 3.30 GHz
机带 RAM 16.0 GB (15.9 GB 可用)
系统类型 64 位操作系统, 基于 x64 的处理器
版本 Windows 10 专业版
版本号 22H2
安装日期 2024/5/1
操作系统内部版本 19045.4412
显示器惠普 27寸
我的显示器自带扬声器,通过HDMI线连接主机,接收音频信号。
我发现一个问题,我的电脑外放声音本来是正常的,但是一旦安装了DockerDesktop,电脑的声音外放功能就不行了,死活不出声音。无论怎么调设置都不管用。
于是我开始追查这个问题原因,既然是由于安装DockerDesktop导致的,那就先从它入手吧!
二、 背锅侠一号:DockerDesktop
先根据Docker的官方文档,详细了解一下DockerDesktop的安装说明,看看有没有什么是没有注意到的。
https://docs.docker.com/desktop/install/windows-install/
1.在windows上安装DockerDesktop,需要开启虚拟化支持,而在Windows上有两种虚拟化支撑技术
WSL2 和 Hyper-V
下面就来了解一下这两种虚拟化技术,看看有什么区别。
来看看微软是怎么介绍WSL的:
https://learn.microsoft.com/zh-cn/windows/wsl/about
说白了就是:WSL(Windows SubSystem For Linux)是让你能够方便的在Windows系统环境中来运行Linux子系统的一种技术,即系统上的系统。
之前没有这个东西的时候,你想在Windows系统上运行一个Linux的环境,你是不是得安装虚拟机?比如VMWare,然后在虚拟机里面安装你需要的操作系统,比如 CentOS Ubuntu等等,现在有了这个WSL技术的支撑,你可以不用那么费劲儿安装虚拟机了,可以直接在Windows系统上面安装Linux子系统。
WSL这个技术,也是经历了版本迭代的,之前是WSL1,现在最新的是WSL2
那么,WSL1和WSL2有什么不同呢? 微软也贴心的给了说明
https://learn.microsoft.com/zh-cn/windows/wsl/compare-versions
WSL2相比WSL1的最大区别是,WSL2依赖于一个托管的虚拟机(VM),这个托管虚拟机是一个轻量级实用工具虚拟机 (VM) 。WSL2 将 Linux 发行版作为托管 VM 内的隔离容器运行。
什么是Hyper-V?
https://learn.microsoft.com/zh-cn/training/modules/azure-stack-hci-technologies/2-hyper-v
你就理解成,Hyper-V是微软推出来用来干VMWare,跟VMWare抢市场的,就行了!!!
它本质上也是一种虚拟机的实现。
既然这两种虚拟化技术都可以作为DockerDesktop的后端支撑,那我安装DockerDesktop的时候,应该用哪种呢?
docker官方文档有说明,这两种方案用哪个都行,唯一的区别是当你基于WSL2安装DockerDesktop时,镜像和容器无法在不同的Windows用户账户之间共享。
两种虚拟化支持方案用哪种都行,但是它们各自又有一些系统设定要求:
对于WSL2
对于Hyper-V
先来看看WSL2的要求:
Turn on the WSL 2 feature on Windows. For detailed instructions, refer to the Microsoft documentation.
Enable hardware virtualization in BIOS. For more information, see Virtualization.
它让我开启Windows上的WSL2的特性,并且给了我一个微软的链接,打开看看。
https://learn.microsoft.com/en-us/windows/wsl/install
我发现这篇文章里面,也没有哪里是讲解如何设置开启Windows特性的啊,这是怎么回事?
其实是因为,如果你的Windows系统比较新,它集成的WSL默认是WSL2,基于WSL2安装DockerDesktop时,是不需要手动启用Windows特性的,它自己会把该启用的特性启用。
只有当你的Windows系统比较老时,此时你的操作系统集成的WSL是WSL1,此时你基于WSL1安装DockerDesktop时,才需要手动去开启。
来看这个文章,https://learn.microsoft.com/en-us/windows/wsl/install-manual
如何启动Windows Subsystem For Linux特性
它建议你升级你的WSL1到WSL2,当然你也可以不升级
我们建议现在继续执行步骤 #2,更新到 WSL 2,但如果您只想安装 WSL 1,您现在可以重新启动计算机并继续执行步骤 6 - 安装您选择的 Linux 发行版。要更新到 WSL 2,请等待重新启动计算机,然后继续下一步。
如何启用Virtual Machine Platform特性
这两个特性到底是什么玩意儿呢,究竟在哪儿能看到呢?
其实在这里,所以你不用它上面写的那两条命令,自己手动勾选这俩选项,也是一样的效果
WSL2的第二个要求是让我们开启BIOS的硬件虚拟化功能,看看它给的链接文章
https://docs.docker.com/desktop/troubleshoot/topics/#virtualization
https://www.virtualmetric.com/blog/how-to-enable-hardware-virtualization
这里有讲到如何判断你的电脑是否支持硬件虚拟化。
If your processor supports hardware virtualization, you will see virtualization as Enabled along with the other details, or otherwise disabled. If it does not support virtualization, you will not see Hyper-V or virtualization mentioned in the task manager.
翻译一下就是: 如果你的处理器支持硬件虚拟化,那么你打开任务管理器,是能看到”虚拟化“和”Hyper-v“选项的(启用或者禁用)。 如果你的处理器压根不支持虚拟化,则你打开任务管理器,什么也看不到。
所以打开我的任务管理器,如下可以看到我的处理器是支持虚拟化的,只不过现在是”已禁用“状态,并且也是支持Hyper-V的。
现在需要进入BIOS来打开虚拟化支持。重启电脑,F2进入BIOS设置,可以看到Intel Virtualization Technology选项默认是Disabled状态,我把它改成Enabled,然后保存,重启电脑。
电脑重启之后,再看看任务管理器,可以看到,虚拟化的状态已经变成“已启用”,至此,BIOS的设置已经完毕。
再来看看Hyper-V的要求
Turn on Hyper-V and Containers Windows features.
Turn on BIOS-level hardware virtualization support in the BIOS settings. For more information, see Virtualization.
第一步它让我开启Hyper-V特性和容器特性其实就是勾选这两个选项。
第二步让我开启BIOS的硬件虚拟化,这个跟上面那个操作一样。不再赘述
那接下来分别按WSL2和Hyper-V来进行DockerDesktop的安装,看看有什么不同。
由于我的操作系统是最新的Windows10 ,集成的 WSL是WSL2,安装之前其实是不需要设
置那几个特性的,所以我先把这四个特性全部取消勾选。
下载DockerDesktop
安装,弹出这个界面,第一个选项是说你要基于WSL2安装还是基于Hyper-V安装? 它默认推荐你基于WSL2安装, 那我们就先按它的推荐来。点OK
开始执行安装
安装完成之后,它会让我重启电脑,我先不重启,我先看看那两个特性选项它有没有自动给我勾选上
可以看到,确实自动勾选了。
然后打开个视频,看看是否能够正常播放声音,声音也能正常播放,接下来重启电脑
电脑重启中.............
电脑重启之后,打开个视频,果不其然,电脑没声音了......
先不管声音这个问题,先打开DockerDesktop,看看能不能启动
启动的时候,有个选项需要设置,你可以设置默认选项。
也可以自己设置,我们点开看看,发现这是关于WSL更新的选项。 没啥意思,直接Use Recommended
问你要不要登录,我不登录。
问你啥水平,不告诉你
启动中
启动起来了。
找个官方Demo,试试docker功能是否正常
拉镜像
执行
容器启动起来了
http://localhost:8088访问一下,没问题,各项功能正常
powershell看一下当前本机的linux发行版,只有docker相关的,我并没有单独安装linux系统,关于这点,来看官方文档说明
https://docs.docker.com/desktop/wsl/?uuid=2A137054-D6EF-4EA8-8D82-278F5E2B9E4B
Windows Subsystem for Linux (WSL) 2 是 Microsoft 构建的完整 Linux 内核,它允许 Linux 发行版在不管理虚拟机的情况下运行。通过在 WSL 2 上运行 Docker Desktop,用户可以利用 Linux 工作区并避免同时维护 Linux 和 Windows 构建脚本。此外,WSL 2 还改进了文件系统共享和启动时间。
WSL2本身就是一个完整的Linux内核,你不需要单独安装Linux发行版,DockerDesktop就可以直接基于WSL2运行。
当你执行wsl --list --verbose时,启动的Docker Desktop会被当成Linux发行版罗列出来。
当然你也可以单独安装一个Linux发行版,然后让DockerDesktop基于此发行版运行。
https://docs.docker.com/desktop/wsl/?uuid=2A137054-D6EF-4EA8-8D82-278F5E2B9E4B#enabling-docker-support-in-wsl-2-distros
WSL 2 向 Windows 添加了对“Linux 发行版”的支持,其中每个发行版的行为就像一个 VM,只不过它们都运行在单个共享 Linux 内核之上。
Docker Desktop 不需要安装任何特定的 Linux 发行版。 docker CLI 和 UI 在 Windows 上都可以正常工作,无需任何额外的 Linux 发行版。然而,为了获得最佳的开发人员体验,我们建议至少安装一个额外的发行版并启用 Docker 支持
这块儿是将如何将安装的Linux发行版与DockerDesktop集成的。
我们可以看到,当前是启用了"集成WSL默认发行版的",只不过我电脑上没有安装任何Linux发行版,所以这里不显示任何东西
来安装一下,执行wsl --install,默认给我安装了Ubuntu
安装完查看一下当前有几个发行版,可以看到,除了docker的两个,多了一个Ubuntu的
docker这个界面也展示出来了我刚才安装的分发版
enable然后restart
重启之后,容器正常访问,没问题。
现在我用命令,尝试把刚才安装的linux发行版关闭,这时候DockerDesktop会崩,说明现在确实是基于我安装的Ubuntu运行的。
点击“Restart the WSL integration” , 它又把Ubuntu启动起来了
下面开始基于Hyper-V进行安装。 首先删除DockerDesktop
删除Ubuntu
取消那四个特性的勾选
重启电脑,然后重新安装DockerDesktop,到这一步,取消勾选第一项,我们基于Hyper-V安装,不按他推荐的。下一步
安装中
安装完成,让我重启,先不重启,先看看特性设置
它自动设置了"Hyper-V"和“容器”这两个特性,跟文档说的一致
重启,然后弄个demo容器验证一下docker功能,看看是否正常。
没问题,镜像正常启动,正常访问
通过基于Hyper-V的安装之后,电脑也是没了声音。
三、 背锅侠二号:微软&Intel
按照这几个关键字去搜索这个问题:
wsl2 hyper-v hdmi audio not sound
在网上找了一堆相关的文章。看来这个问题还不只是我自己遇到了
https://answers.microsoft.com/en-us/surface/forum/all/enabling-wsl2-appears-to-break-audio-output/bc909378-40d8-4d11-a2ad-8616120c226f
https://answers.microsoft.com/en-us/windows/forum/all/hdmi-output-not-working-properly-when-hyper-v-is/01ac4ecf-07ce-494f-babf-2ddf47172289
https://learn.microsoft.com/en-us/answers/questions/1431252/hdmi-audio-not-working-when-hypervisor-hyper-v-orhttps://arstechnica.com/civis/threads/windows-10-no-hdmi-audio-disabling-hyper-v-fixes-the-problem.1317155/
https://community.intel.com/t5/Graphics/Intel-Display-Audio-and-Hyper-V/td-p/347548?profile.language=en
https://answers.microsoft.com/en-us/insider/forum/all/hyper-v-causes-intel-hdmi-audio-to-stop-working/12b3dad4-51b6-4b03-80e0-a30f35a4a0ea
https://answers.microsoft.com/en-us/windows/forum/all/audio-over-hdmi-stops-working-when-enabling-hyper/0267be83-1f01-434d-9622-e0a939a08963
https://community.intel.com/t5/Graphics/HDMI-audio-bitstreaming-passthrough-not-working-with-Hyper-V/m-p/360975
https://answers.microsoft.com/en-us/windows/forum/all/windows-10-hdmi-audio-not-working/293eec79-e0f8-4837-bbd0-341cfc9bd446?page=4
不过找到的文章大部分是反馈问题的,有几篇文章指出没声音问题应该是跟 WSL2和Hyper-v的虚拟化有关。 让取消勾选“Hyper-V” 和 “虚拟机平台”这俩功能。
我试了一下,取消勾选,确实可以解决这个问题,但是DockerDesktop就用不了了啊!!!!
所以这肯定不是解决方案。不过这也说明了一个问题,那就是这问题的发生,应该就是跟虚拟化有关。
继续看帖子,
微软论坛里面的mvp让找厂家。。。
然后厂家inter客服复现了问题
客服的大概意思是:
i5-4670K 不支持VT-D, 然后这个CPU 启用Hyper-V不影响HDMI输出音频
i5-4590 和 i5-4430 都支持VT-D,然后这俩CPU在启动Hyper-V时都无法通过HDMI输出音频,关闭Hyper-V时,音频能正常输出。
但是客服认为如果真是VT-D导致的,那么i5-4590 和 i5-4430之间必须存在某种交集,并且这种交集导致了在启用Hyper-V之后,不向HDMI输出音频信号。客服任务不存在这样的交集,让找微软解决。。。。。。
不过很快下面就有人质疑他了,认为就是VT-D功能导致的。。。。
下面有人回复了一个解决方法,停用BIOS的VT-D功能
该问题可能出在 Windows 10 的主机操作系统/虚拟机管理程序端,但我已致电 Microsoft 向他们立案,并有 3 个不同的代表告诉我,他们不提供对客户端 Hyper-V 的任何支持,我会需要使用我的信用卡号码致电企业级支持人员,以支付他们进行故障排除的费用。是的,不,谢谢,我付钱给他们不是为了解决他们自己的问题。此时,我将仅使用在 UEFI 中禁用 VT-d 的解决方法,然后等待看看 MS 或 Intel 是否有任何新更新明确解决了该问题。
这老哥说他联系了微软,微软让他掏钱,老哥不愿意。。。。。然后老哥就采用禁用VT-D的方法来解决了。
我决定也采取老哥的方法,操作一番,不过先搜搜VT-D是个什么玩意儿,关闭之后有没有啥影响
https://www.cnblogs.com/zafu/p/15557488.html
VT-d 的 Intel 官方中文名称是 定向 I/O 虚拟化技术 ,这个技术就是俗称的虚拟化直通技术,就是允许宿主机将某些硬件资源(比如硬盘、显卡、网卡)的管辖权直接移交给虚拟机,此时宿主机将不能再使用此硬件,虚拟机会以直通独占的方式使用它们,这种直通的技术带来的好处就是,虚拟机中使用该硬件的性能损耗是极小的, 改善了 I/O 设备在虚拟化环境中的性能并且隔离更加彻底提高了系统的安全性
这说明VT-D只是来提高性能的,关掉其实也没啥问题。
我注意到一句话“此时宿主机将不能再使用此硬件”
我感觉问题应该出在这里,一旦通过WSL2或者Hyper-V启用虚拟化之后,HDMI的音频输出控制权就移交给虚拟系统了,导致宿主机无法使用音频。
下面尝试通过BIOS关闭VT-D
可以看到我的电脑CPU是支持VT-D,并且VT-D是默认开启状态。现在把它关闭,然后重启电脑
找一个视频播放一下试试。有声音!!!!!!!
启动DockerDesktop看看是否正常,一切正常,问题完美解决~~~~~~~