wsl

 

wsl 介绍

wsl全称是windows上的linux子系统,换句话说可以把它当作运行在windows上的linux虚拟机,可以比较快速的在windows上启动,因此想折腾一下。

安装

安装教程参考官网,https://docs.microsoft.com/en-us/windows/wsl/install-win10 之前安装过wsl,因此想升级为wsl2,按照官方教程始终无法正确启动,报错一个文件权限问题,

Virtual hard disk files must be uncompressed and unencrypted and must not be sparse

参考 https://github.com/microsoft/WSL/issues/4103 原因是c盘默认启动了压缩功能以节约空间,然而这就会导致linux启动的文件系统检查失败。只需要对 AppData\Local\Packages\CanonicalGroupLimited...下的LocalState文件夹取消掉压缩的选项即可。 然后绑定wsl2

wsl --set-version Ubuntu-18.04 2

图形界面配置

可以在wsl安装远程桌面工具,使得windows能够运行linux图形程序。非常棒的一个功能。 参考链接:

安装完成后在wsl中输入xfce4-session启动桌面,但安装教程配置不会成功,因为在wsl2中ip地址更换了,不在是 localhost,参考链接 https://github.com/microsoft/WSL/issues/4106 解决方案:

  • 查看ip地址cat /etc/resolv.conf
  • 设置ip export DISPLAY=172.26.176.1:0 或者 echo "export DISPLAY=172.26.176.1:0.0" >> ~/.bashrc && source ~/.bashrc
  • windows 本地软件配置。启动Xlanch时,加上-ac参数

wsl配置

这样配置后应该能够启动成功。输入xfce4-session,将会看见一个linux桌面系统。也可以在命令行下输入软件启动的命令,将会直接在windows桌面启动一个软件窗口。

wsl2 cuda环境搭建

总所周知,windows上不支持在docker中使用gpu。所以对于我一个docker爱好者来说,windows基本不能用来开发深度学习了。但是,windows最近推出了wsl2,嵌入了真正的linux内核。官方说的可以支持cuda环境。如果能在windows上像在linux上开发一样,那真是太舒服了。于是准备搭建一下。

过程就跟着官网走官方教程 .这里提几点容易踩的坑。这也是我第一次配置失败放弃的原因。

步骤主要分为5步:

  1. 升级系统到预览版20145以上
  2. nvidia驱动安装(需要重新安装特定驱动 官网
  3. WSL2安装
    # 过程省略
    $ wsl.exe --list -v command  # 查看wsl版本
    
  4. cuda-toolkit安装

这个网页不是最新版本的toolkit,需要在 这里去寻找最新版本,我在安装的过程中使用官方教程中的版本最后失败了。后面安装了 cuda-toolkit-11-2就没有问题了。(ubuntu 18) 如果apt安装失败,试试离线安装。到 这里 寻找wsl-ubuntu版本的cuda,根据提示安装。(ubuntu 20)

  1. docker安装

这里也很坑。一般如果你想使用wsl2来搭建docker环境肯定是使用过docker的,所以一般在windows上安装过docker,甚至安装了wsl版本。问题就来了,在wsl中,如果你在外部安装了docker,默认情况wsl中就带了docker,所以想当然的以为这一步自己不需要做了。实际上,windows上安装的支持wsl的docker并没有对nvidia的支持,所以如果不重新安装的话是不可能使用--gpus 这个docker参数的。所以正确做法是在wsl中删掉docker,甚至直接在windows上删掉docker。反正就必须清理干净后再使用教程中的方法重新安装docker就没问题了。

经过上面的步骤后使用下面命令测试:

docker run -it --rm --gpus all nginx:nginx bash

如果没报错就能够进类似在linux创建nvidia docker一样使用容器服务来炼丹了。

wsl2网络配置

默认情况下,windows可以通过localhost访问wsl2,但是不能通过 127.0.0.1 访问,因为wsl2相当于一个虚拟机,而不是真正嵌入wondows与windows网络共享的。其实wsl2有一个他自己的IP。可以通过 ifconfig 命令查看。这个ip windows中就可以直接访问到。这种特性会造成一个巨大的问题,就是不能让外网的主机访问wsl2的服务。因为wsl2中的ip地址在每次重启后都会改变,不能固定,windows上可以设置转发的方式将外网的端口映射到wsl2中。于是思路确定:

  1. 固定wsl2的ip地址
  2. windows端口转发

固定wsl2的ip地址

如何固定ip地址呢?因为wsl2本质上是 hyper-V的虚拟机,他的网卡是虚拟得来的,每次重启都不一样。不知道能不能在wsl中固定ip地址的方式实现。显然这挺麻烦的。看到网上的解决方案是这样的。

  1. 给windows搞一个service
  2. 这个service的目的是修改windows的系统host文件 C:\Windows\System32\drivers\etc\hosts
  3. 每次启动的时候读取wsl的ip(而不是固定IP的方式),写入host文件中
  4. 于是就通过域名的方式访问到了wsl,而不用担心ip地址的更换

service当然人家写好了,拿来就用 github,下载exe文件,用管理员模式打开powershell,运行该exe

.\wsl2host.exe install

输入windows的用户名和密码。就可以在host文件中看到新增了这么一行

172.26.253.182 ubuntu.wsl

于是就可以通过 ubuntu.wsl 映射访问到这个ip。

windows端口转发

首先关掉windows defender的防火墙,然后输入如下命令即可

netsh interface portproxy add v4tov4 listenport=8080 connectaddress=ubuntu.wsl connectport=8080 listenaddress=* protocol=tcp

经过测试,这个重启后依然有效。