このたびラップトップを新調しました。6年ほど前に中古のノートにLinuxを入れてつかってましたが、新品のWindowsノートに乗り換えました。そこで以前から気になっていたWindows Subsystem Linuxを使って、Windows上にLinuxの開発環境を用意してみたところ、セットアップもすごく簡単かつ快適な開発環境になったので、詳細を少し調べてみました。その結果と実際の開発現場における利用シーンについて紹介します。
※現段階ではPreview版OSへのアップデートが必要。WSL2を利用するにはbuild 18917以上のOSバージョンが必要です。それにはthe Windows Insider Programというプログラムに登録した上で、OSをPreview版にアップデートする必要があります。
ターミナルを開くとそこはもうLinuxでした
近頃の私が個人的なLinux環境でやる事というのは以下が主でした。
- Docker使ってローカルなネットワークを構築し、各ノードで動くソフトウェアをgolangで開発
- Reactでフロントエンド開発
- Node.jsでミドルウェア開発
この環境はあいにくWindowsを開発環境として想定していないため、Linux環境をどうにかして確保してやる必要があります。そこで今回新しいノート環境上で利用したのが以下の機能です。
- Windows Subsystem Linux 2
- Windows Terminal
- Docker Desktop WSL 2 backend
必要なもの
- Windows 10
- 私はWindows 10 Professionalを使ってますがWindows 10 Homeでも可能らしいです
- プレビュー版へのアップデートが必要なので会社とかでは使えないケースもあるかと思います
- 2020年上半期に正式リリース予定らしいです
必要な作業
- OSをWindowsプレビュー版にアップデート
-
Windows Subsystem Linux 2(WSL2)
のセットアップ - WSL2のカーネルを最新版にアップデート
- Linuxディストリビューションをストアからダウンロード
-
Docker Desktop WSL 2 backend
のインストール -
Windows Terminal (Preview)
をストアからダウンロード - Windows上のVSCodeに
Visual Studio Code Remote - WSL
プラグインをセットアップ- VS code serverを介してWindows上のVS codeでLinux上のソースをコーディング、デバッグ可能
以下の手順に従えば、特に迷うことも、時間を要することもなくセットアップが完了しました(OSアップデートの待ち時間が少しある程度)。
ネイティブ環境のようにストレスなく使える
今までWindows上でLinuxを使う場合、VirtualBoxなどの仮想環境上にLinuxをインストールして利用していました。またWindows上でDockerを利用する場合には、同じようにBootstrap用のLinuxを仮想環境上にインストールし、その上でDocker Engineを動かしていたかと思います。WSL2でMicrosoft独自のLightweight Utility VM
の導入により、ネイティブ環境に近いLinuxおよびDockerのランタイム性能を実現しています。メモリ消費量も小さく抑えられ、Linux上の処理に応じてオンデマンドでメモリを獲得・解放するようです。
先代のWSL1は使ったことはないですが、飛躍的な性能改善と互換性向上が実現されたらしいです。互換性に関しては、Linuxのシステムコールをフルサポートしているとのことで、あらゆるLinux互換のバイナリがWSL2上でそのまま実行可能ということです。これを実現するために、WSL2ではLinuxカーネルそのものを内包しています。
The Modern Windows Command-Line: Windows Subsystem for Linux 2 | BRK3322 - YouTubeより
そのカーネルが前述のLightweight Utility VM
上で動いており、性能改善およびシステムコールフルサポートを実現しています。
The Modern Windows Command-Line: Windows Subsystem for Linux 2 | BRK3322 - YouTubeより
このカーネルですが、kernel.orgのstableブランチをベースに、MicrosoftがWSL2向けにパッチを当てたもので、MicrosoftによってOSSとして保守されています。このLinuxカーネルが必要に応じてWindows Updateにより更新されるわけです。不思議な響き
パッチサイズも修正分は1Kステップにも満たないボリュームです。
$ git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
$ cd WSL2-Linux-Kernel
$ git diff --diff-filter=M --stat v4.19.84
Documentation/admin-guide/kernel-parameters.txt | 10 ++++++
MAINTAINERS | 4 +++
arch/arm64/Kconfig | 4 +--
arch/arm64/Makefile | 1 +
arch/x86/include/asm/hyperv-tlfs.h | 40 ++++++++++++++++++++++
arch/x86/include/asm/mshyperv.h | 4 +++
arch/x86/include/asm/pci_x86.h | 5 +++
drivers/acpi/Kconfig | 1 -
drivers/acpi/Makefile | 2 +-
drivers/acpi/acpica/dsutils.c | 9 ++++-
drivers/acpi/arm64/iort.c | 20 +++++++----
drivers/acpi/internal.h | 5 +++
drivers/acpi/nfit/core.c | 3 ++
drivers/hv/Kconfig | 5 +--
drivers/hv/channel_mgmt.c | 19 ++++++++--
drivers/hv/hv.c | 2 ++
drivers/hv/hv_balloon.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
drivers/pci/Makefile | 2 +-
drivers/tty/sysrq.c | 4 ++-
include/acpi/acpi_drivers.h | 5 +++
include/linux/acpi.h | 6 ++++
include/linux/list.h | 17 +++++++++
include/linux/mm.h | 3 --
include/linux/mm_types.h | 3 ++
include/linux/mmzone.h | 34 ++++++++++++++++++
include/linux/page-flags.h | 11 ++++++
include/linux/pci.h | 36 +++++++++++++++++++
include/uapi/linux/ndctl.h | 2 +-
init/Kconfig | 26 ++++++++++++--
kernel/ksysfs.c | 2 +-
lib/Kconfig | 3 +-
lib/Kconfig.debug | 7 ++--
lib/raid6/algos.c | 61 +++++++++++++++++++++++++++++++++
mm/Kconfig | 11 ++++++
mm/Makefile | 8 ++++-
mm/compaction.c | 7 ++--
mm/memory_hotplug.c | 5 +++
mm/page_alloc.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------
net/vmw_vsock/hyperv_transport.c | 90 ++++++++++++++++++++++++++++++++++++------------
39 files changed, 688 insertions(+), 129 deletions(-)
Export/Import機能により開発環境のシェアもカンタン
wsl2にはexport, import機能が備わっています。WSL2上で動かしているディストリビューション環境のスナップショットをストア、リストアするようなものです。exportすると対象のディストリビューションがtarで固められて出力されます。例えば、チームで開発環境をそろえたい場合に、exportしたtarファイルを開発グループ内でシェアし、それぞれWSL2上で動かせば、同一の環境にそろえることが可能です。特筆すべきは、Dockerのexport機能によって出力されたファイルもWSL2にimport可能であるという点です。ubuntu:18.04
のコンテナイメージをベースに必要なツール群をインストールするDockerfileを書いてGithubでバージョン管理&シェアすれば、あっという間に同一環境が複数環境に渡ってシェアできます。vagrantを置き換えることもできますし、自分のお気に入り開発環境をすぐにスタートできます。
例えば、以下はUbuntu 18.04上にgolangの古めの環境をセットアップするカスタムディストリビューションの例です。
FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y zsh
RUN curl -O https://dl.google.com/go/go1.9.linux-amd64.tar.gz
RUN tar -xvf go1.9.linux-amd64.tar.gz && chown -R root:root ./go && mv go /usr/local
CMD ["zsh"]
上記Dockerfileを利用して環境を構築⇒tarへのexport⇒wsl2へのimportを以下の通り実施します。
# On wsl
$ pwd
/home/atsushi/dev/qiita_test
$ code Dockerfile
$ docker build -t my-distro .
$ docker run --name mydistro -it -d my-distro
6dff538229aa997474db550c180474245774e0ab7c39ac8cba44a7a640181c32
$ docker export --output ./my-distro.tar mydistro
$ ls -lh
total 500M
-rw-r--r-- 1 atsushi atsushi 254 Apr 13 15:49 Dockerfile
-rw------- 1 atsushi atsushi 500M Apr 13 15:55 my-distro.tar
# On power shell
PS > wsl --import my-distro ./my-distro-ws \\wsl$\Ubuntu-18.04\home\atsushi\dev\qiita_test\my-distro.tar
PS > wsl --list --verbose
NAME STATE VERSION
* Ubuntu-18.04 Running 2
my-distro Running 2
docker-desktop-data Running 2
docker-desktop Running 2
Windows Terminalをリスタートすると自動で新たに作成したディストリビューションがリストに読み込まれました。
新たに作成したディストリビューションをWindows Terminalのリスト上から起動すると意図したUbuntuバージョン上で指定したgolang環境がインストールされていることが分かります。
このように自分のお気に入りな開発環境をDockerfileでバージョン管理して、wslさえあれば、すぐに立ち上げることが可能になります。
コンテナ環境のテスト&デバッグを効率的に行える
前述のexport, importの応用です。自分で作成したコンテナイメージ内で問題が発生した場合、デバッグするのは手間ですよね。この場合にも、export, importが役立ちます。問題が発生するコンテナ環境をexportし、wslへimportしてやることで、環境はそのままでVSCode等を利用したデバッグ作業が可能になります!
以下は起動して数秒後に異常終了してしまうNode.jsアプリの例です。
$ docker run -it -d --name node-debug hyperledger/explorer
c8ed7b77c396289e3330ee5101b45df7054fd5ed56fa17b85f3b7b9fa962223d
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66239d7f2ac3 hyperledger/explorer "docker-entrypoint.s…" 8 seconds ago Exited (1) 2 seconds ago node-debug
# On wsl
# entrypointを変更してシェルでアイドルさせてコンテナを起動させます
$ docker run -it -d --name node-debug --entrypoint /bin/sh hyperledger/explorer
$ docker export --output node-debug.tar node-debug
# On power shell
PS > wsl --import node-debug ./node-debug-ws \\wsl$\Ubuntu-18.04\home\atsushi\dev\qiita_test\node-debug.tar
wsl2にimportしたnode-debug環境を開くとランタイムの環境がShellでのアイドル状態で立ち上がり、VS codeでデバッグができる状態になります。
VS code起動後、さきほどimportした環境に接続することで、VS code上のデバッガでブレイクさせながら、先ほど発生していた問題の原因を追うことができます。
その他
-
Windows向けDockerの実装は、Microsoftと密に連携して進められているようです。
Docker ❤️ WSL 2 - The Future of Docker Desktop for Windows - Docker Blog -
動的にメモリが獲得、解放され、WSL2のfootprintは低く抑えられるといいましたが、現在少し問題があるようでウォッチ中です。
最後に
昔はCygwinでlinux-likeな環境をWindows上で使ったり、PCをデュアルブートにしてLinux環境を用意したり、色々手間をかけてWindows/Linux両環境を用意していましたが、もうそういった苦労は必要なさそうです。Surface DuoでもAndroidを採用するなど、MicrosoftのLinux愛がひしひしと感じられます。公式リリースが待ち遠しいですね。