iT邦幫忙

2

使用WSL2在Windows下快速打造Linux開發環境(含Docker)

santos 2021-04-03 11:36:0060279 瀏覽

對於習慣使用windows在開發大部分工作的開發者來說,如果想要同時開發適合在Linux-based運行的程式來說, 像是(後台服務, 各式的腳本程式, Linux 命令列工具, 爬蟲, Docker, cluster...)等的話, 可以用諸如(VMWare或是VirtualBox安裝Linux, 用另外一台單機, 開一個VPS)等的方式來完成.

但如果想要快速測試, 這些難免都要多了一些步驟. 還好Microsoft越來越佛心了, 發布的WSL2(Windows Subsystem for Linux), 這是一個Linux核心的虛擬層, 可以幾乎擁有Linux核心跟所有指令, 完整的system call支援. 目前的版本WSL2比起前一版, 這版直接對linux system call做了虛擬優化, 效能比前一代使用轉譯的方法效能更高.

關於 Windows WSL2可以到下面網址看尾軟的介紹
https://docs.microsoft.com/zh-tw/windows/wsl/about

系統要求

建議先升級windows10到20H1/20H2 or higher, 預設就會是WSL2的版本

啟用安裝WSL必要元件

  • 因為最新的WSL2使用Hyper-V, 所以確認已經打開Hyper-V的功能
    去控制台 — ->程式和功能 — ->開啟或關Windows功能 →勾選Hyper-V平台
    https://ithelp.ithome.com.tw/upload/images/20210328/20136089Gv8q3fcm5m.png

  • 以系統管理員身執行以下 PowerShell 指令:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

然後重開機...
開完機後可以到控制台 — ->程式和功能 — ->開啟或關Windows功能確認是否已經開啟
https://ithelp.ithome.com.tw/upload/images/20210328/20136089BY8zXII4UH.png

  • 將WSL預設版本調成WSL2
    執行下列命令把WSL改成使用WSL2, 如果已經是WSL2就不需要囉!
    wsl --set-default-version 2

  • 安裝 Linux 發行版本
    在 Windows 10 中開啟 Microsoft Store,然後在商店中搜尋你要的Linux發行版本,這邊安裝的是Ubuntu, 所以搜尋關鍵字 Ubuntu, 找到你要的發行版後安裝
    https://ithelp.ithome.com.tw/upload/images/20210329/20136089sKxBF7zy70.png
    安裝後點選啟動
    設置好帳號密碼
    https://ithelp.ithome.com.tw/upload/images/20210329/2013608962myaZiuC0.png

就可以進入Ubuntu的Shell介面
https://ithelp.ithome.com.tw/upload/images/20210329/20136089GeeAxYHZO8.png
然後關掉視窗, 就可以使用WSL2來操作Ubuntu

使用WSL2

  • 列出WSL指令
wsl -h
  • 列出所有已經安裝的Linux發行版
    wsl -l
    https://ithelp.ithome.com.tw/upload/images/20210329/20136089avdsxEQ0Dh.png
    基本上可以安裝多個Linux發行版, 同時也可以執行多各Linux, 這樣就可以打造出多重linux的環境.

  • Ubuntu起手式
    執行Linux 發行版並進入Shell, wsl -d "Linux發行版的名稱"

這裡使用
wsl -d Ubuntu

基本上檔案系統, 網路等資源是跟Windows共用的, 這也是最棒的一點, 提供檔案拷貝的便利性, 網路也自動設定好, 直接配置一個IP可以直接連網.

要注意一點是檔案系統是共用的, 可能不小心就砍掉不該砍的檔案X(.

所有的Windows磁碟都被mount在/mnt下面可以直接存取(但要小心操作...)
https://ithelp.ithome.com.tw/upload/images/20210331/20136089Md73SwESHQ.png

更換Systemd

現在很多Linux套件都需要systemd來管理跟啟動服務. 由於WSL2是Windows下的一個VM, 所以微軟實作了一個init (PID 1) 來做到快速啓動WSL VM以及作為與windows 溝通的橋樑. 可以執行systemctl確認是否有systemd

ubuntu@DESKTOP:/mnt/$ systemctl
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

所幸, GitHub 上已經有幾個專案可以直接拿來建構有systemd(PID 1)環境, 這裡我們使用
DamionGans/ubuntu-wsl2-systemd-script, 只要按照說明操作就可以了

ubuntu@CM-PC-02057:~$ git clone https://github.com/DamionGans/ubuntu-wsl2-systemd-script.git
Cloning into 'ubuntu-wsl2-systemd-script'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 118 (delta 0), reused 2 (delta 0), pack-reused 115
Receiving objects: 100% (118/118), 34.22 KiB | 455.00 KiB/s, done.
Resolving deltas: 100% (57/57), done.
ubuntu@CM-PC-02057:~/ubuntu-wsl2-systemd-script$ bash ubuntu-wsl2-systemd-script.sh
[sudo] password for ubuntu:
Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [109 kB]
Hit:2 http://archive.ubuntu.com/ubuntu focal InRelease
Get:3 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
Get:4 http://security.ubuntu.com/ubuntu focal-security/main amd64 Packages [574 kB]
Get:5 http://archive.ubuntu.com/ubuntu focal-backports InRelease [101 kB]
Get:6 http://security.ubuntu.com/ubuntu focal-security/main Translation-en [120 kB]
Get:7 http://security.ubuntu.com/ubuntu focal-security/main amd64 c-n-f Metadata [7380 B]
Get:8 http://security.ubuntu.com/ubuntu focal-security/restricted amd64 Packages [148 kB]
Get:9 http://security.ubuntu.com/ubuntu focal-security/restricted Translation-en [21.6 kB]
Get:10 http://security.ubuntu.com/ubuntu focal-security/restricted amd64 c-n-f Metadata [392 B]
Get:11 http://security.ubuntu.com/ubuntu focal-security/universe amd64 Packages [550 kB]
Get:12 http://archive.ubuntu.com/ubuntu focal/universe amd64 Packages [8628 kB]
Get:13 http://security.ubuntu.com/ubuntu focal-security/universe Translation-en [81.2 kB]
Get:14 http://security.ubuntu.com/ubuntu focal-security/universe amd64 c-n-f Metadata [10.7 kB]
Get:15 http://security.ubuntu.com/ubuntu focal-security/multiverse amd64 Packages [14.8 kB]
Get:16 http://security.ubuntu.com/ubuntu focal-security/multiverse Translation-en [3160 B]
Get:17 http://security.ubuntu.com/ubuntu focal-security/multiverse amd64 c-n-f Metadata [340 B]
Get:18 http://archive.ubuntu.com/ubuntu focal/universe Translation-en [5124 kB]
Get:19 http://archive.ubuntu.com/ubuntu focal/universe amd64 c-n-f Metadata [265 kB]
Get:20 http://archive.ubuntu.com/ubuntu focal/multiverse amd64 Packages [144 kB]
Get:21 http://archive.ubuntu.com/ubuntu focal/multiverse Translation-en [104 kB]
Get:22 http://archive.ubuntu.com/ubuntu focal/multiverse amd64 c-n-f Metadata [9136 B]
Get:23 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages [894 kB]
Get:24 http://archive.ubuntu.com/ubuntu focal-updates/main Translation-en [208 kB]
Get:25 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 c-n-f Metadata [12.9 kB]
Get:26 http://archive.ubuntu.com/ubuntu focal-updates/restricted amd64 Packages [171 kB]
Get:27 http://archive.ubuntu.com/ubuntu focal-updates/restricted Translation-en [25.3 kB]
Get:28 http://archive.ubuntu.com/ubuntu focal-updates/restricted amd64 c-n-f Metadata [436 B]
Get:29 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages [758 kB]
Get:30 http://archive.ubuntu.com/ubuntu focal-updates/universe Translation-en [160 kB]
Get:31 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 c-n-f Metadata [16.5 kB]
Get:32 http://archive.ubuntu.com/ubuntu focal-updates/multiverse amd64 Packages [21.6 kB]
Get:33 http://archive.ubuntu.com/ubuntu focal-updates/multiverse Translation-en [5508 B]
Get:34 http://archive.ubuntu.com/ubuntu focal-updates/multiverse amd64 c-n-f Metadata [596 B]
Get:35 http://archive.ubuntu.com/ubuntu focal-backports/main amd64 c-n-f Metadata [112 B]
Get:36 http://archive.ubuntu.com/ubuntu focal-backports/restricted amd64 c-n-f Metadata [116 B]
Get:37 http://archive.ubuntu.com/ubuntu focal-backports/universe amd64 Packages [4032 B]
Get:38 http://archive.ubuntu.com/ubuntu focal-backports/universe Translation-en [1448 B]
Get:39 http://archive.ubuntu.com/ubuntu focal-backports/universe amd64 c-n-f Metadata [224 B]
Get:40 http://archive.ubuntu.com/ubuntu focal-backports/multiverse amd64 c-n-f Metadata [116 B]
Fetched 18.4 MB in 5s (3487 kB/s)
Reading package lists... Done
Selecting previously unselected package daemonize.
(Reading database ... 32157 files and directories currently installed.)
Preparing to unpack .../daemonize_1.7.8-1_amd64.deb ...
Unpacking daemonize (1.7.8-1) ...
Selecting previously unselected package fontconfig.
Preparing to unpack .../fontconfig_2.13.1-2ubuntu3_amd64.deb ...
Unpacking fontconfig (2.13.1-2ubuntu3) ...
Setting up fontconfig (2.13.1-2ubuntu3) ...
Regenerating fonts cache... done.
Setting up daemonize (1.7.8-1) ...
Processing triggers for man-db (2.9.1-1) ...
'\\wsl$\Ubuntu\home\ubuntu\ubuntu-wsl2-systemd-script'
是目前用來啟動 CMD.EXE 的目錄路徑。不支援 UNC 路徑。
預設目錄是 Windows 目錄。

成功: 已經儲存指定的值。
'\\wsl$\Ubuntu\home\ubuntu\ubuntu-wsl2-systemd-script'
是目前用來啟動 CMD.EXE 的目錄路徑。不支援 UNC 路徑。
預設目錄是 Windows 目錄。

成功: 已經儲存指定的值。

安裝成功後需要登出, 重啓Linux發布版本, 使用 wsl -t Ubuntu

ubuntu@CM-PC-02057:~/ubuntu-wsl2-systemd-script$ exit
logout

$ wsl -t Ubuntu
$ wsl -d Ubuntu
Sleeping for 1 second to let systemd settle
Welcome to Ubuntu 20.04.2 LTS (GNU/Linux 5.4.72-microsoft-standard-WSL2 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Thu Apr  1 10:09:24 CST 2021

  System load:  0.06               Processes:             50
  Usage of /:   0.5% of 250.98GB   Users logged in:       0
  Memory usage: 1%                 IPv4 address for eth0: 172.18.19.105
  Swap usage:   0%

36 updates can be installed immediately.
22 of these updates are security updates.
To see these additional updates run: apt list --upgradable



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

檢查有沒有成功啟動systemd

ubuntu@CM-PC-02057:~$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0  26912 11224 ?        Ss   10:09   0:00 /lib/systemd/systemd --unit=basic.target
root          43  0.0  0.0  45288 15332 ?        S<s  10:09   0:00 /lib/systemd/systemd-journald
root          62  0.0  0.0  21608  5000 ?        Ss   10:09   0:00 /lib/systemd/systemd-udevd
systemd+      67  0.0  0.0  18596  7936 ?        Ss   10:09   0:00 /lib/systemd/systemd-networkd
message+     229  0.0  0.0   7372  4520 ?        Ss   10:09   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root         230  0.0  0.0  10452  4712 pts/0    S    10:09   0:00 /bin/login -p -f        'HOSTTYPE=x86_64' 'PWD=/mnt/c/Users/ubuntu' 'TERM=xterm-256color' 'WSLENV=BASH_ENV/u' 'WSL_DISTRO_NAME=Ubuntu' 'WSL_INTEROP=/run/WSL/10_interop'
root         300  0.0  0.0  16984  7900 ?        Ss   10:09   0:00 /lib/systemd/systemd-logind
ubuntu       303  0.0  0.0  18488  9604 ?        Ss   10:09   0:00 /lib/systemd/systemd --user
ubuntu       304  0.0  0.0  28272  3068 ?        S    10:09   0:00 (sd-pam)
ubuntu       310  0.1  0.0  10108  5096 pts/0    S    10:09   0:00 -bash
ubuntu       330  0.0  0.0  11164  4140 pts/0    T    10:09   0:00 systemctl
ubuntu       331  0.0  0.0   7592  2564 pts/0    T    10:09   0:00 pager

恭喜!!接近完整的Linux更近一步囉

安裝Docker

有了systemd 你就可以安裝docker engine了, 照著官方的步驟做就可以了

完成後來個Docker Hello World吧!!

ubuntu@Ubuntu:~/$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

可能會遇到的問題

  • WSL 2 需要更新其核心元件
    Download the Linux kernel update package: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
  • WSL網路玩爛了
    可以先shutdown wsl試看看: wsl --shutdown
    不行的話, 就重開電腦吧
  • WslRegisterDistribution failed with error: 0xc03a001a
    出現這個錯誤, 是說這個發行版的安裝目錄是被設定成壓縮的, 需要去這個安裝目錄下把壓縮disable
    解決方法是前往以下路徑
    C:\Users\your user name\AppData\Local\Packages
    your user name請換成你的本機使用者名稱
    如果安裝的是Ubuntu,所以請找到 “CanonicalGroupLimited.Ubuntu” 並點選右鍵 -> 內容
    https://ithelp.ithome.com.tw/upload/images/20210402/20136089QPQBcGFkpE.png

點選「進階」
https://ithelp.ithome.com.tw/upload/images/20210402/20136089bDf5IFJa5y.png

將"壓縮內容,節省磁碟空間"取消勾選,並按確定
https://ithelp.ithome.com.tw/upload/images/20210402/20136089NCJNuDP77N.png

結語

因為想要在Windows中使用Linux docker的關係, 無意間發現的WSL2這摸好用的系統, 推薦大家需要快速試驗linux上面的程式或套件時可以安裝使用


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
尼克
iT邦大師 1 級 ‧ 2022-11-21 15:05:13
$ wsl -t Ubuntu

請教執行上面指令後,liunx 就掛了!如何挽救?

0
RichardW
iT邦新手 5 級 ‧ 2023-03-11 01:17:20

更換Systemd時遇到障礙時可以

# 進入 ubuntu
wsl -d Ubuntu
# 開始編輯
sudo -e /etc/wsl.conf
# 輸入以下內容
[boot]
systemd=true
# 重啟 ubuntu
wsl -t Ubuntu
wsl -d Ubuntu
0
harryx001
iT邦新手 5 級 ‧ 2023-04-15 11:26:16

您好,想請教:如果只是要使用docker,可以跳過「安裝 Linux 發行版本」這個步驟嗎?
我想要在docker上面跑airflow

0
liyobor
iT邦新手 5 級 ‧ 2023-09-19 11:23:00

我在換systemd時候好像有跳錯誤訊息,我那時候沒有仔細看就登出ubuntu,之後就啟動不了了,會產生下面的錯誤訊息

nsenter: cannot open /proc/14/ns/time: No such file or directory

去他們的Github issue查了一下,執行腳本(以下這段)之前

bash ubuntu-wsl2-systemd-script.sh

要先將 enter-systemd-namespace 這個檔案最後一段改成

USER_HOME="$(getent passwd | awk -F: '$1=="'"$SUDO_USER"'" {print $6}')"
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" -m -p \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; [ -f "$HOME/.systemd-env" ] && source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -m -p \
            /bin/login -p -f "$SUDO_USER" \
            $([ -f "$USER_HOME/.systemd-env" ] && /bin/cat "$USER_HOME/.systemd-env" | xargs printf ' %q')
    fi
    echo "Existential crisis"
    exit 1
fi

否則就會開不了Ubuntu

解決方法:
那邊討論的做法是直接修改壞掉Ubuntu/Linux裡面的enter-systemd-namespace,之後用下面的指令進Ubuntu

wsl bash --norc

接著重新跑安裝腳本

bash ubuntu-wsl2-systemd-script.sh --force

我自己的情況則是壞掉之後進不了Ubuntu,所以先去 控制台/程式與功能 移除ubuntu
然後執行

wsl --unregister Ubuntu

徹底移除wsl裡面的Ubuntu

並按原本步驟重新安裝Ubuntu

安裝完成之後,先改好enter-systemd-namespace檔才去執行安裝腳本

我要留言

立即登入留言