WSL

Windows Subsystem for Linux(简称WSL)是一个在Windows 10上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层。它是由微软与Canonical公司合作开发,其目标是使纯正的Ubuntu 14.04 “Trusty Tahr”映像能下载和解压到用户的本地计算机,并且映像内的工具和实用工具能在此子系统上原生运行。

安装WSL

最新版本的操作系统Windows 11安装简单很多,参考:https://docs.microsoft.com/en-us/windows/wsl/install

先安装:适用于 x64 计算机的 WSL2 Linux 内核更新包,否则会报:0x80072f78错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
wsl --install
#或者安装指点的版本
wsl -l -o
以下是可安装的有效分发的列表。
请使用“wsl --install -d <分发>”安装。

NAME FRIENDLY NAME
Ubuntu Ubuntu
Debian Debian GNU/Linux
kali-linux Kali Linux Rolling
openSUSE-42 openSUSE Leap 42
SLES-12 SUSE Linux Enterprise Server v12
Ubuntu-16.04 Ubuntu 16.04 LTS
Ubuntu-18.04 Ubuntu 18.04 LTS
Ubuntu-20.04 Ubuntu 20.04 LTS

wsl --install -d Ubuntu

Windows 10版本参考以下内容:

安装最新的Win10:cn_windows_10_business_editions_version_20h2_x64_dvd_f978664f.iso

安装参考:https://docs.microsoft.com/zh-cn/windows/wsl/install-win10

1
2
3
4
5
6
7
8
9
10
11
12
#步骤 1 - 启用适用于 Linux 的 Windows 子系统
#以管理员身份打开 PowerShell 并运行:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
#步骤 2 - 启用虚拟机功能
#以管理员身份打开 PowerShell 并运行:
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
#步骤 3 - 下载 Linux 内核更新包
wget http://aka.ms/wsl2kernelmsix64
#步骤 4 - 将 WSL 2 设置为默认版本
wsl --set-default-version 2
#步骤 5 - 安装所选的 Linux 分发
直接在Microsoft Store中搜索并安装

如果已经安装了最新的Win10与docker desktop后,可以直接跳到步骤4,下载以下文件进行安装:

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

安装docker时也会提示更新这个。另外注意:不需要开启Hyper-V。安装完后设置一下默认为v2:

1
wsl --set-default-version 2

安装ubuntu

参考:https://docs.microsoft.com/zh-cn/windows/wsl/install-win10#step-6---install-your-linux-distribution-of-choice

终端

Windows终端(建议):

参考:

添加git-bash支持:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"guid": "{4d4cc780-cacb-5b6f-a183-29b5f6cdcd23}",
"hidden": false,
"name": "CentOS",
"icon" : "D:\\Developer\\Git\\centos.png",
"colorScheme": "Campbell Powershell",
"source": "Windows.Terminal.Wsl"
},
{
"guid" : "{1d4e097e-fe87-4164-97d7-3ca794c316fd}",
"name" : "Bash",
"icon" : "D:\\Developer\\Git\\git-bash.png",
"colorScheme": "Vintage",
"fontFace" : "Consolas",
"fontSize" : 14,
"commandline" : "D:\\Developer\\Git\\bin\\bash.exe --login -i",
"startingDirectory" : "%USERPROFILE%"
},
{
"guid": "{4360b1d2-9732-4bfd-8967-93338bcbb568}",
"name": "192.168.80.98",
"commandline": "ssh dev@192.168.80.98",
"colorScheme" : "One Half Dark",
"fontFace" : "Consolas",
"fontSize" : 14,
"icon" : "ms-appx:///ProfileIcons/{9acb9455-ca41-5af7-950f-6bca1bc9722f}.png"
}

colorScheme请参考:https://docs.microsoft.com/en-us/windows/terminal/customize-settings/color-schemes

wsl-terminal:

参考:https://link.jianshu.com/?t=https://github.com/goreliu/wsl-terminal

设置默认Linux发行版

参考:http://www.xitongzhijia.net/xtjc/20180316/122477.html

1
2
3
4
5
6
wslconfig /l
wslconfig /setdefault Ubuntu-20.04

wsl.exe -l -v
#wsl.exe --set-version Ubuntu-20.04 2
#wsl.exe --set-default-version 2

配置WSL为独立的系统

默认WSL可以以windows共享vscode/docker等资源,但不支持systemd相关的服务,可以通过以下方式开启,参考:https://kubernetes.io/blog/2020/05/21/wsl-docker-kubernetes-on-the-windows-desktop/#minikube-enabling-systemd

注意:开启systemd后将不再支持直接在linux开启vscode,与windows共享资源。也就是开启后将是一个完整独立的linux系统。不太建议。如果只是使用docker与k8s的话,直接使用docker-desktop即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Edit the sudoers with the visudo command
sudo visudo
# Change the %sudo group to be password-less
%sudo ALL=(ALL:ALL) NOPASSWD: ALL
# Press CTRL+X to exit
# Press Y to save
# Press Enter to confirm

#Systemctl couldn't start
sudo apt install -y conntrack
sudo apt install -yqq daemonize dbus-user-session fontconfig
# Create the start-systemd-namespace script
sudo vi /usr/sbin/start-systemd-namespace
#!/bin/bash

SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
if [ -z "$SYSTEMD_PID" ] || [ "$SYSTEMD_PID" != "1" ]; then
export PRE_NAMESPACE_PATH="$PATH"
(set -o posix; set) | \
grep -v "^BASH" | \
grep -v "^DIRSTACK=" | \
grep -v "^EUID=" | \
grep -v "^GROUPS=" | \
grep -v "^HOME=" | \
grep -v "^HOSTNAME=" | \
grep -v "^HOSTTYPE=" | \
grep -v "^IFS='.*"$'\n'"'" | \
grep -v "^LANG=" | \
grep -v "^LOGNAME=" | \
grep -v "^MACHTYPE=" | \
grep -v "^NAME=" | \
grep -v "^OPTERR=" | \
grep -v "^OPTIND=" | \
grep -v "^OSTYPE=" | \
grep -v "^PIPESTATUS=" | \
grep -v "^POSIXLY_CORRECT=" | \
grep -v "^PPID=" | \
grep -v "^PS1=" | \
grep -v "^PS4=" | \
grep -v "^SHELL=" | \
grep -v "^SHELLOPTS=" | \
grep -v "^SHLVL=" | \
grep -v "^SYSTEMD_PID=" | \
grep -v "^UID=" | \
grep -v "^USER=" | \
grep -v "^_=" | \
cat - > "$HOME/.systemd-env"
echo "PATH='$PATH'" >> "$HOME/.systemd-env"
exec sudo /usr/sbin/enter-systemd-namespace "$BASH_EXECUTION_STRING"
fi
if [ -n "$PRE_NAMESPACE_PATH" ]; then
export PATH="$PRE_NAMESPACE_PATH"
fi

# Create the enter-systemd-namespace
sudo vi /usr/sbin/enter-systemd-namespace
#!/bin/bash

if [ "$UID" != 0 ]; then
echo "You need to run $0 through sudo"
exit 1
fi

SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
if [ -z "$SYSTEMD_PID" ]; then
/usr/sbin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
while [ -z "$SYSTEMD_PID" ]; do
SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
done
fi

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
/usr/bin/sudo -H -u "$SUDO_USER" \
/bin/bash -c 'set -a; source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
else
exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
/bin/login -p -f "$SUDO_USER" \
$(/bin/cat "$HOME/.systemd-env" | grep -v "^PATH=")
fi
echo "Existential crisis"
fi

# Edit the permissions of the enter-systemd-namespace script
sudo chmod +x /usr/sbin/enter-systemd-namespace
# Edit the bash.bashrc file
sudo sed -i 2a"# Start or enter a PID namespace in WSL2\nsource /usr/sbin/start-systemd-namespace\n" /etc/bash.bashrc
sudo cp -a ~/.systemd-env /root/.systemd-env
#Finally, exit and launch a new session. You do not need to stop WSL2, a new session is enough

#can't set the locale; make sure $LC_* and $LANG are correct
#https://www.cnblogs.com/skiloop/archive/2013/02/20/2919266.html
locale
sudo locale-gen zh_CN.UTF-8

备注与还原

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#https://www.howtogeek.com/426562/how-to-export-and-import-your-linux-systems-on-windows-10/
#Backup
wsl --list -v
wsl --export Ubuntu-20.04 "D:\Developer\WSL\Ubuntu-20.04.tar"
# wsl --import Ubuntu D:\Developer\WSL D:\Developer\WSL\Bak\Ubuntu-20.04.tar
wsl --unregister Ubuntu-20.04
wsl --import Ubuntu-20.04 "D:\Developer\WSL\Ubuntu-20.04" "D:\Developer\WSL\Ubuntu-20.04.tar" --version 2
wslconfig /setdefault Ubuntu-20.04
#Import后默认用户变成了root,需要在windows命令行中执行:
ubuntu2004.exe config --default-user dave
#Move
https://github.com/pxlrbt/move-wsl

#Move CentOS
wsl --list -v
wsl --export CentOS "D:\Developer\wsl\CentOS.tar"
wsl --unregister CentOS
wsl --import CentOS "D:\Developer\wsl\CentOS" "D:\Developer\wsl\CentOS.tar" --version 2
mydistro config --default-user dave

#Move Docker's wsl data
wsl --list -v
wsl --export docker-desktop "D:\Developer\WSL\docker-desktop.tar"
wsl --unregister docker-desktop
wsl --import docker-desktop "D:\Developer\wsl\docker-desktop" "D:\Developer\wsl\docker-desktop.tar" --version 2

wsl --list -v
wsl --export docker-desktop-data "D:\Developer\WSL\docker-desktop-data.tar"
wsl --unregister docker-desktop-data
wsl --import docker-desktop-data "D:\Developer\wsl\docker-desktop-data" "D:\Developer\wsl\docker-desktop-data.tar" --version 2

其他参考

https://www.jianshu.com/p/f59f902fd885