LoginSignup
173
152

More than 3 years have passed since last update.

WindowsアップデートでLinuxカーネルもアップデートされる時代に

Last updated at Posted at 2020-04-13

00100trPORTRAIT_00100_BURST20200413122237302_COVER.jpg

このたびラップトップを新調しました。6年ほど前に中古のノートにLinuxを入れてつかってましたが、新品のWindowsノートに乗り換えました。そこで以前から気になっていたWindows Subsystem Linuxを使って、Windows上にLinuxの開発環境を用意してみたところ、セットアップもすごく簡単かつ快適な開発環境になったので、詳細を少し調べてみました。その結果と実際の開発現場における利用シーンについて紹介します。

※現段階ではPreview版OSへのアップデートが必要。WSL2を利用するにはbuild 18917以上のOSバージョンが必要です。それにはthe Windows Insider Programというプログラムに登録した上で、OSをPreview版にアップデートする必要があります。

ターミナルを開くとそこはもうLinuxでした

image.png

近頃の私が個人的な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年上半期に正式リリース予定らしいです

必要な作業

  1. OSをWindowsプレビュー版にアップデート
  2. Windows Subsystem Linux 2(WSL2)のセットアップ
  3. WSL2のカーネルを最新版にアップデート
  4. Linuxディストリビューションをストアからダウンロード
  5. Docker Desktop WSL 2 backendのインストール
  6. Windows Terminal (Preview)をストアからダウンロード
  7. 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カーネルそのものを内包しています。

image.png
The Modern Windows Command-Line: Windows Subsystem for Linux 2 | BRK3322 - YouTubeより

そのカーネルが前述のLightweight Utility VM上で動いており、性能改善およびシステムコールフルサポートを実現しています。

image.png
The Modern Windows Command-Line: Windows Subsystem for Linux 2 | BRK3322 - YouTubeより

このカーネルですが、kernel.orgのstableブランチをベースに、MicrosoftがWSL2向けにパッチを当てたもので、MicrosoftによってOSSとして保守されています。このLinuxカーネルが必要に応じてWindows Updateにより更新されるわけです。不思議な響き

microsoft/WSL2-Linux-Kernel: The source for the Linux kernel used in Windows Subsystem for Linux 2 (WSL2)

パッチサイズも修正分は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をリスタートすると自動で新たに作成したディストリビューションがリストに読み込まれました。

image.png

新たに作成したディストリビューションをWindows Terminalのリスト上から起動すると意図したUbuntuバージョン上で指定したgolang環境がインストールされていることが分かります。
image.png

このように自分のお気に入りな開発環境を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でデバッグができる状態になります。

image.png

image.png

VS code起動後、さきほどimportした環境に接続することで、VS code上のデバッガでブレイクさせながら、先ほど発生していた問題の原因を追うことができます。

image.png
image.png
image.png

その他

最後に

昔はCygwinでlinux-likeな環境をWindows上で使ったり、PCをデュアルブートにしてLinux環境を用意したり、色々手間をかけてWindows/Linux両環境を用意していましたが、もうそういった苦労は必要なさそうです。Surface DuoでもAndroidを採用するなど、MicrosoftのLinux愛がひしひしと感じられます。公式リリースが待ち遠しいですね。

173
152
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
173
152