惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
The Last Watchdog
The Last Watchdog
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
WordPress大学
WordPress大学
The Hacker News
The Hacker News
C
Cybersecurity and Infrastructure Security Agency CISA
H
Help Net Security
GbyAI
GbyAI
V
V2EX
Security Latest
Security Latest
Cyberwarzone
Cyberwarzone
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Privacy International News Feed
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tor Project blog
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
月光博客
月光博客
B
Blog
T
Threat Research - Cisco Blogs
I
Intezer
Recent Announcements
Recent Announcements
Latest news
Latest news
S
Schneier on Security
美团技术团队
量子位
H
Hacker News: Front Page
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Webroot Blog
Webroot Blog
N
News | PayPal Newsroom
Martin Fowler
Martin Fowler
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
爱范儿
爱范儿
T
Tailwind CSS Blog
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 聂微东
Cloudbric
Cloudbric
MyScale Blog
MyScale Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
人人都是产品经理
人人都是产品经理
S
Securelist
Hacker News: Ask HN
Hacker News: Ask HN
Y
Y Combinator Blog
Attack and Defense Labs
Attack and Defense Labs
TaoSecurity Blog
TaoSecurity Blog

青空之蓝

[青空之蓝-2023] - 色彩 | 青空之蓝 [青空之蓝-2022] - 平静 | 青空之蓝 [青空之蓝-2021] - 远望 | 青空之蓝 浅谈垃圾回收 | 青空之蓝 浅谈泛型擦除 | 青空之蓝 浅谈单点登录 | 青空之蓝 使用 Kotlin 编写 Spring 测试 | 青空之蓝 设计模式系列文章 | 青空之蓝 从零实现一个 Java 微框架 - IoC | 青空之蓝 从零实现一个 Java 微框架 - 前言 | 青空之蓝 浅谈 JVM:类加载 | 青空之蓝 浅谈 IO | 青空之蓝 浅谈并发:synchronized & ReentrantLock | 青空之蓝 浅谈并发:CAS & AQS | 青空之蓝 浅谈并发:ThreadLocal | 青空之蓝 浅谈并发:三大特性 | 青空之蓝 浅谈组合注解 & 注解别名 | 青空之蓝 [青空之蓝-2020]-迷茫 | 青空之蓝 Java 系列文章 | 青空之蓝 HTTP 系列文章 | 青空之蓝 浅谈 EatWhatYouKill | 青空之蓝 浅谈可扩展线程池 | 青空之蓝 聊聊写框架 | 青空之蓝 聊聊现状-[2020-09] | 青空之蓝 浅谈并发:锁 | 青空之蓝 浅谈并发:基础 | 青空之蓝 浅谈缓存 | 青空之蓝 无须定义类,Spring 快速注入 Json 参数 | 青空之蓝 浅谈 Proxy 和 Aop | 青空之蓝 从零实现一个 PHP 微框架 - 初始化请求 | 青空之蓝 为 Vue3 添加一个简单的 Store | 青空之蓝 从零实现一个 PHP 微框架 - 服务提供者 | 青空之蓝 浅谈浏览器Event Loop [更新] | 青空之蓝 从零实现一个 PHP 微框架 - Bootstrap 启动加载 | 青空之蓝 从零实现一个 PHP 微框架 - IoC 容器 | 青空之蓝 从零实现一个 PHP 微框架 - PSR & Composer | 青空之蓝 从零实现一个 PHP 微框架 - 前言 | 青空之蓝 MVVM 简单实现 | 青空之蓝 浅谈 DI 和 IoC | 青空之蓝 中间件实现 [PHP] | 青空之蓝 告别 Windows 终端的难看难用,打造好用的 PowerShell | 青空之蓝 VSCode Java输出中文乱码问题解决[更新] | 青空之蓝 浅谈浏览器渲染 | 青空之蓝 Vue-Cli@2 项目迁移日志 | 青空之蓝 Laragon & Scoop 集成踩坑记录 | 青空之蓝 「一行代码」优雅管理 Windows 软件 | 青空之蓝 [青空之蓝-2019]-年度总结 | 青空之蓝 为Vue添加简单的Store | 青空之蓝 为React添加简单的Store | 青空之蓝 为Vuex添加同步Action | 青空之蓝 浅谈B+树 | 青空之蓝 浅谈跳表 | 青空之蓝 浅谈数据库索引 | 青空之蓝 MySQL事务隔离 | 青空之蓝 算法复杂度分析(1) | 青空之蓝 一年来的经验总结 | 青空之蓝 Acrylic - VSCode Extension | 青空之蓝 ace编辑器设置惯性滚动 | 青空之蓝 Java二叉树实现 | 青空之蓝 Java图实现 | 青空之蓝 为apt方式安装的nginx重新编译增加WebDAV | 青空之蓝 XK-Editor - 一个支持富文本和Markdown的编辑器 | 青空之蓝 JS生成列表树 | 青空之蓝 Laravel生成目录树 | 青空之蓝 XK-Note - 集各种神奇功能的云笔记 | 青空之蓝 PHP GD生成验证码 | 青空之蓝 PHP GD图片处理[转换格式-水印-缩略图] | 青空之蓝 Origami - 简洁轻快的WordPress主题 | 青空之蓝 为WordPress启用WorkBox | 青空之蓝 [青空之蓝-2018]-年度总结 | 青空之蓝 VSCode Java手动导入jar和源码包 | 青空之蓝 Windows IP变化自动发送邮件 | 青空之蓝 C链表实现重制版 | 青空之蓝 C 结构体的定义和使用 | 青空之蓝 图的搜索(遍历) - BFS & DFS | 青空之蓝 Java链表实现 | 青空之蓝 C 快速排序 | 青空之蓝 C 插入排序 | 青空之蓝 C 归并排序 | 青空之蓝 C语言链表实现 | 青空之蓝 VSCode配置Java调试环境[Windows] | 青空之蓝 C 选择排序 | 青空之蓝 C 冒泡排序 | 青空之蓝 VSCode配置PHP调试环境[Windows] | 青空之蓝 VSCode配置C/C++ GDB调试环境[Windows] | 青空之蓝 WordPress友情链接模板 | 青空之蓝 Intel Optane 傲腾内存体验 | 青空之蓝 Mysql双机热备实战 | 青空之蓝 博客一年记录 | 青空之蓝 为WordPress启用Service Worker | 青空之蓝 Bing每日一图API | 青空之蓝 iframe延迟加载 | 青空之蓝 写在2018年高考前 | 青空之蓝 The Fox主题汉化分享 | 青空之蓝 [青空之蓝-2017]-崭新 | 青空之蓝 本博客评论规则 | 青空之蓝 世界,您好! | 青空之蓝
WSL2 踩坑记录 | 青空之蓝
Otstar Lin · 2020-06-28 · via 青空之蓝

前言

前不久 Windows 20H1 正式推送了,我们终于可以用上 WSL2 了,博主因为是 Release 通道的 Insider,所以比其他用户早升级到 20H1,由于之前比较忙,所以一直没折腾 WSL2,直到前天考完了试,并且我之前部署的 Ubuntu 虚拟机总是出现一些问题,于是就打算试试 WSL2。

安装

准备环境

由于 WSL2 使用的是 Hyper-V 虚拟平台,所以我们需要先开启虚拟机平台,使用以下命令开启,或者也可以使用 Windows 的界面进行设置。

Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform

设置完成后重启下 Windows。

准备发行版

重启完成后我们可以先使用 wsl -l 查看已经安装的 WSL 发行版。

由于 WSL2 和 WSL1 可以共存,如果你想日常继续使用 WSL1,只将 WSL2 用于 Docker 等用途的话,我建议你复制一份,然后将其转成 WSL2,就如上面的截图一样(Ubuntu 是 WSL1,Ubuntu-WSL2 是 WSL2)。

复制 WSL 发行版的方法如下:

首先安装 LxRunOffline,Scoop 可以使用 scoop install lxrunoffline 安装。其他的安装方式这里就不写了,具体请自行查看。

使用 LxRunOffline 复制的方式很简单,使用以下命令即可:

lxrunoffline d -n <要复制的发行版> -d <复制后存储的路径> -N <复制后发行版的名>
lxrunoffline d -n <要复制的发行版> -d <复制后存储的路径> -N <复制后发行版的名>

当然有时候我们会使用新建的发行版来用于 WSL2,这时就可以用 LxRunOffline 导入新的发行版,也可以用 Microsoft Store 安装。

切换 WSL 版本

有了要转换的发行版后我们就可以用以下命令将 WSL1 转换成 WSL2 了。

wsl --set-version <发行版> <版本(1,2)>

# 设置默认创建的 WSL 版本,按需设置
wsl --set-default-version <版本(1,2)>
wsl --set-version <发行版> <版本(1,2)>

# 设置默认创建的 WSL 版本,按需设置
wsl --set-default-version <版本(1,2)>

等待其切换完成,切换完成后就可以通过 wsl -d <发行版> 进入到 WSL 中,此时 WSL2 的安装就完成了。

初始化 WSL2

对于初始设置 Apt 镜像,安装基础应用,Docker,Systemd,Zsh 的脚本我已经制作好了,并发布到了 Github 上,你可以直接使用此脚本完成对 WSL2 的一些初始化操作。

使用此脚本安装的 Docker 已经预先配置好了tcp:2375端口,Windows 下只需设置 DOCKER_HOST 的环境变量就可以无痛使用 Docker 和 Docker-Compose,而无需安装 Docker for Windows,同时在 WSL1 中也可以通过这种方式使用 WSL2 中的 Docker(不过一般也不需要,WSL1/2 中可以直接使用 Windows 下的命令和程序。

注意: 在某些情况下,可能会出现 2375 端口处于监听状态,但是 Windows 无法连接的情况,所以博主建议使用 socat 来暴露 docker 的管理端口,具体查看 docksal/service-socat

同时,本脚本会设置一个启动时进行一些设置的 shell 脚本,具体功能如下:

自动设置 hosts,由于 WSL2 中目前还无法实现使用 localhost 访问 Windows 下的服务,所以需要通过 hosts,或者 IP 来间接访问 Windows 的服务,但是由于 WSL2 的 Hyper-V 交换机在每次重启的时候都会重设 IP,这就导致了 hosts 无法设置成静态的,不然一重启就需要重新设置了。解决这个问题的方案是在每次进入 WSL2 的时候自动从 /etc/resolved.conf 中获取 Windows 的 IP,然后将该 IP 设置到 hosts 中,同时删除旧的 hosts。(默认设置的域名是 h.test

设置WSL_HOST环境变量,如果不想使用 hosts 的域名,也可以使用 WSL_HOST 来访问 Windows。

设置DISPLAY环境变量,通过该环境变量,我们就可以将 Linux GUI 应用转发到 Window 下的 X Server。

启动 systemd,由于 WSL2 依旧是使用 init 进程,而非 systemd,所以我们无法使用 systemctl,这对 WSL2 的使用产生了很多的限制,不过我们可以通过一些手段来启动 systemd,具体见 ubuntu-wsl2-systemd-script。本脚本对其进行了一些修改以适应本脚本。

一些使用技巧

停止 WSL2:wsl --shutdown wsl -t <发行版>

备份:wsl --export <分发版> <文件名>

恢复:wsl --import <发行版> <安装位置> <文件名> [--version <版本>]

设置默认登录用户:lxrunoffline su -n <发行版> -v <UID>

卸载:lxrunoffline ui -n <发行版>

移动:lxrunoffline move -n <发行版> -d <路径>

复制:lxrunoffline d -n <要复制的发行版> -d <复制后存储的路径> -N <复制后发行版的名>

Windows 目前已经可以使用 localhost 访问 WSL2 了,不过由于 Hyper-V 端口映射的一些问题,可能在 Windows 下会出现没有使用的端口也提示占用的问题并且 netcat 也未显示,这是因为 WSL2 的动态端口设置有点问题,WSL2 的动态端口是从 1024 开始映射的,可以用以下的命令调整到高一点的端口。

netsh int ip set dynamicport tcp start=49152 num=16384
netsh int ip set dynamicport tcp start=49152 num=16384

Docker for Windows 似乎会调整 WSL2 Hyper-V 交换机的类型,这会导致 Windows 无法使用 localhost 访问 WSL2,解决的方案是将 WSL2 的 Hyper-V 交换机调回内部网络

由于 Hyper-V/WSL2 的网络不属于防火墙的专用组,所以部分应用会因为防火墙的问题而无法访问 Windows 下的端口,解决方案是使用以下的命令添加防火墙规则,同时删除阻止规则。(由于 Window 防火墙阻止规则的优先级大于允许,这会导致以下设置的规则无效)

New-NetFirewallRule -DisplayName "WSL" -Direction Inbound  -InterfaceAlias "vEthernet (WSL)"  -Action Allow
New-NetFirewallRule -DisplayName "WSL" -Direction Inbound  -InterfaceAlias "vEthernet (WSL)"  -Action Allow

如果你一定需要使用静态 IP,那么也可以用以下的命令另外添加静态 IP。(重启失效)

netsh interface ip add address "vEthernet (WSL)" 192.168.50.1 255.255.255.0
wsl -d Ubuntu-WSL2 -u root ip addr add 192.168.50.199/24 broadcast 192.168.50.255 dev eth0 label eth0:1
netsh interface ip add address "vEthernet (WSL)" 192.168.50.1 255.255.255.0
wsl -d Ubuntu-WSL2 -u root ip addr add 192.168.50.199/24 broadcast 192.168.50.255 dev eth0 label eth0:1

在 Windows 中要使用 WSL 中的应用我们可以创建一个 Proxy 脚本来代理调用 WSL 的应用,具体创建的方式如下,创建好后就可以用这个在 Windows 下执行该脚本,相当于在 WSL 中执行命令:

# powershell
wsl -- docker $args

# cmd
@echo off
wsl.exe -c "docker %*"
# powershell
wsl -- docker $args

# cmd
@echo off
wsl.exe -c "docker %*"

在 WSL2 的 Shell 中使用 docker-compose 你可能也会遇到这个问题:

Traceback (most recent call last):
  File "bin/docker-compose", line 6, in <module>
  File "compose/cli/main.py", line 72, in main
  File "compose/cli/main.py", line 128, in perform_command
  File "compose/cli/main.py", line 1078, in up
  File "compose/cli/main.py", line 1074, in up
  File "compose/project.py", line 548, in up
  File "compose/service.py", line 361, in ensure_image_exists
  File "compose/service.py", line 1250, in pull
  File "compose/progress_stream.py", line 102, in get_digest_from_pull
  File "compose/service.py", line 1215, in _do_pull
  File "site-packages/docker/api/image.py", line 396, in pull
  File "site-packages/docker/auth.py", line 48, in get_config_header
  File "site-packages/docker/auth.py", line 324, in resolve_authconfig
  File "site-packages/docker/auth.py", line 235, in resolve_authconfig
  File "site-packages/docker/auth.py", line 262, in _resolve_authconfig_credstore
  File "site-packages/docker/auth.py", line 287, in _get_store_instance
  File "site-packages/docker/credentials/store.py", line 25, in __init__
docker.credentials.errors.InitializationError: docker-credential-desktop.exe not installed or not available in PATH
[2037] Failed to execute script docker-compose
Traceback (most recent call last):
  File "bin/docker-compose", line 6, in <module>
  File "compose/cli/main.py", line 72, in main
  File "compose/cli/main.py", line 128, in perform_command
  File "compose/cli/main.py", line 1078, in up
  File "compose/cli/main.py", line 1074, in up
  File "compose/project.py", line 548, in up
  File "compose/service.py", line 361, in ensure_image_exists
  File "compose/service.py", line 1250, in pull
  File "compose/progress_stream.py", line 102, in get_digest_from_pull
  File "compose/service.py", line 1215, in _do_pull
  File "site-packages/docker/api/image.py", line 396, in pull
  File "site-packages/docker/auth.py", line 48, in get_config_header
  File "site-packages/docker/auth.py", line 324, in resolve_authconfig
  File "site-packages/docker/auth.py", line 235, in resolve_authconfig
  File "site-packages/docker/auth.py", line 262, in _resolve_authconfig_credstore
  File "site-packages/docker/auth.py", line 287, in _get_store_instance
  File "site-packages/docker/credentials/store.py", line 25, in __init__
docker.credentials.errors.InitializationError: docker-credential-desktop.exe not installed or not available in PATH
[2037] Failed to execute script docker-compose

此时你只需要运行以下的命令即可:

rm ~/.docker/config.json
rm ~/.docker/config.json

无意间发现的小特性

如果你看过 WSL 导出的系统你会发现导出的是 rootfs,而碰巧 docker 导出的容器也是 rootfs,所以理论上是可以通用的,而且 WSL 本来就可以导入 docker 的基础系统(如 Ubuntu 镜像),那么从基础系统上构建的镜像也是可以运行在 WSL 上的。

由于从 DockerHub 上拉取的是分层的镜像,所以我们需要创建成容器后再导出。

docker run -d --name nginx nginx
docker export -o /mnt/f/nginx.tar nginx
docker run -d --name nginx nginx
docker export -o /mnt/f/nginx.tar nginx

导出后我们就取得了 nginx 容器的 rootfs,然后通过 lxrunoffline 导入这个 rootfs 到 WSL

lxrunoffline i -n nginx -d F:\wsl\nginx -f F:\nginx.tar
wsl --set-version nginx 2 # 可选
lxrunoffline i -n nginx -d F:\wsl\nginx -f F:\nginx.tar
wsl --set-version nginx 2 # 可选

导入后就可以启动了

博主我稍微测试了下,运行是没有问题的,不过有可能会有坑,如果你不想在 WSL 里跑 docker 的话也可以考虑试试这个方案。

结语

WSL2 其实我们可以把它看成是一个轻量的虚拟机平台,介于 Docker 和 VM 间的存在,WSL2 相比于传统的 VM,它的启动速度飞快,同时占用更小,而且自动设置了端口映射和目录挂载,同时导入发行版的速度也比从头安装系统快出许多,我试过导入一个 Ubuntu Core 的镜像,并转成 WSL2,算上打字的延迟,只需要 28s。

相比 Docker 虽然差了很多,不过偶尔需要使用非 Docker 的 Linux,也不再需要等待漫长的安装了。

不过 WSL2 目前还不够完善,还有许多的问题,比如 WSL2 访问 Windows 的问题就挺难受的,还有 export import 的效率不如 VMware 和 VBox 的快照等等。

希望微软能越做越好吧,现在 WSL 已经支持 GPU 加速了,那么下一个功能会是什么呢?好奇.jpg

WSL2 踩坑记录

https://blog.ixk.me/post/wsl-2-recording
  • 许可协议

    BY-NC-SA

  • 本文作者

    Otstar Lin

  • 发布于

    2020/06/28

转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!

从零实现一个 PHP 微框架 - 服务提供者浅谈浏览器Event Loop [更新]