WSL2入れてみた

待ちに待ったWSL2が使えるようになったので入れてみた。現在は、インサイダープレビューのSlowリングにしていれば使える感じ。

実際のインストールはとても簡単で、ここの手順に従うだけ。

* [Installation Instructions for WSL 2](https://docs.microsoft.com/en-us/windows/wsl/wsl2-install)

# インストールの実行

## WSL と Virtual Machine Platform の有効化
管理者権限で、PowerShellを立ち上げて下記のコマンドを実行する

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

dism.exe は何だろうと思って調べてみると次のようなツール。

> Deployment Image Servicing and Management(DISM.exe) Windows イメージのサービスや準備に使われるコマンドラインツール。DISMはWindows image(.wim) やvirtual hard disk (.vhd or .vhdx) にサービスを行います。

ちなみに、どんな時に使うかというと

* Windowsイメージに含まれるデータや情報、例えばコンポーネントのインベントリを取得したり、ドライバ、イメージに含まれるアプリケーションのアップデート、イメージのキャプチャや分割、追加、削除、マウントなどを行います。

なるほど。今回使われるコマンドとしては妥当な感じですね。コマンドからするに、WSLと、Virtual Machine Platform を有効化しています。

* [DISM Overview](https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/what-is-dism)

ちなみに、上記のコマンドを実行後、OS再起動後に設定が有効になるようです。

その後、設定を加えて、WSL2をデフォルトに変更します。

```powershell
PS > wsl -l 
Ubuntu (Default)
WLinux
Ubuntu-18.04
PS > wsl --set-version Ubuntu-18.04 2
PS > wsl --set-default-version 2
```

ただ、ここのままでは動きませんでした。WSL2を起動すると、次のURLに飛ぶように指示されました。

* [WSL 2 Linux カーネルを更新しています](https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel)

このページにあるAMD64のバイナリを落としてインストールするとWSLが動きました。

ちなみに、ここでは、ARM64, AMD64 の両方が選べますが、最近CPUを勉強していなかったので、Core i7 ってどっちやねんとまよったので、一応調べました。ARMは、アンドロイドやiPhoneで使われるCPUです。Windows10はそっちでも動作するので、そのバイナリが必要なんですね。
x86-64, x64, AMD64 は同じ意味でつかわれるそうです。AMDはインテルより先にAMD社によって発表されたもので、Intelのものは本来はIntel64ですが、それらをまとめてAMD64と呼ばれるようです。（コメントを頂いたので修正しました）

* [ARMとx64/x64(Intel,AMD)のCPU、アーキテクチャの違い、シェア、性能比較、アーキテクチャ、エンディアン](https://urashita.com/archives/12325)
* [x86とか32bitCPUとかISAとかAMD64とかx86_64とかについて調べてみた](https://qiita.com/hot_study_man/items/a3b856085731b0e1f8d4)

# VSCode リモートデベロップメントでつないでみる
私は、Linuxはほぼコマンドラインで、GUIはほぼ使わないのですが、エディタだけはやっぱいい。そんな時は、VSCodeのリモートデベロップメントが最高です。リモートのLinuxマシンにつないで、ローカルのマシンのように開発できます。

VSCode を起動して左下のこれをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/f4c7399b-a719-e337-e766-f0f563c54772.png)

次の画面がでてくるので、Remote-WSL: New Window をえらびます。もし、WSLで複数のディストリビューションを使っている場合は、using Distro...の方をえらびます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/cbf7121f-2ca4-6485-4b78-ac3c6d3ae1fc.png)

今回は書きませんが、この仕組みをつかって、DevContainerというのを作れます。つまり、接続するのをWSLやLinuxの代わりに、コンテナにつなぐもので、クリーンな開発環境がすぐ作れます。

* [Developing inside a Container](https://code.visualstudio.com/docs/remote/containers)

# 起動

起動してみるとしっかり前のデータが残っていて、既にインストールしたコマンドもそのまま使えました。確かに、若干早い気がします！
インストールの手引きにあるとおり、WSL2からExplorerを起動したりもできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/c7c505bb-f190-00f6-3d2a-255209242387.png)

やったぜ！これで生Dockerとかも使い放題や！今まではWSLだと動かないとかありました。内部のシステムコールをWindowsのシステムコールに変換するために起こっていました。あとはパフォーマンスも遅かったようです。

# Docker Desktop とのインテグレーション
皆さんも、DockerをWindowsで使っていてシェルでログインが出来なかったりとイライラしていたことでしょう。今まではWSLを使っていましたが、Dockerが動作しなかったので、`DOCKER_HOST`を指定して、WindowsのDocker Destktopにつなぎに行って、クライアントだけWSLにインストールして動かしていましたが、 Desktop の設定を変えるだけで使えるようになりました。DockerUserの設定とかOS起動時の設定とかひつようやろなーと思ったら、何もしなくても動きました。設定は２つ。次の画面で、Enable the experiment WSL2 based engine をえらんでWSL2をDockerのサーバにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/f6107f46-ede9-2fa0-af1c-d400566fbe15.png)

次にインテグレーションを有効にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/e393b55f-0354-d603-77dd-14d6f66dae9f.png)

このインテグレーションで何が起こっているのでしょうか？ちょっと調べてみると、WSL2側でプロキシが実行されていて、おそらくこれに、Docker Destktopがつなげているのでしょう。


```bash
$ ps -ef | grep docker 
root       664   663  0 20:07 pts/3    00:00:00 /mnt/wsl/docker-desktop/docker-desktop-proxy --distro-name Ubuntu-18.04 --docker-desktop-root /mnt/wsl/docker-desktop
```

あと、`etc/group`に下記のエントリが追加されているので、無事Dockerが動作するようになっているようです。

```
docker:x:999:ushio
```

インストール済みのパッケージも見てみます。パッケージがインストールされています。

```bash
$ dpkg -l 
ii  docker-ce                               18.06.0~ce~3-0~ubuntu    amd64                    Docker: the open-source application container engine
rc  docker.io                               17.12.1-0ubuntu1         amd64                    Linux container runtime
```

```bash
cd /var/lib/docker
root@DESKTOP-SDE49UK:/var/lib/docker# ls
containerd  containers  image  network  nuke-graph-directory.sh  overlay2  plugins  runtimes  tmp  trust  volumes
```

後はスタートアップスクリプトです。systemdか、Upstartだと思うのですが、systemdの`/lib/systemd/system/docker.service`は存在しますが、ステータスをみてみると、こんなメッセージなので、多分Upstartかな？このあたり全然しらない分野なので、間違ってたら是非コメントを。

```bash
sudo systemctl show docker
System has not been booted with systemd as init system (PID 1). Can't operate.
```

`/lib/systemd/system` の下にこれがしっかりインストールされているんだけど、`systemctl --type=service`も同じ結果だな。
* [docker/docker-ce-packaging](https://github.com/docker/docker-ce-packaging/tree/master/systemd)

Upstartで使いそうなファイル存在して、Upstartで起動されてい、、、ない？

```bash
$ cat /etc/init/docker.conf 
$ sudo service docker status
 * Docker is not running
```
どうやってDockerが動いてるかしりたかったけど、わからないなー。ちなみに、Dockerの公式のドキュメントには、ＷＳＬ２インテグレーションのほうが１５倍起動がはやくメモリ消費も少ないとあるな。

* [How it translates to the new WSL 2 backend](https://www.docker.com/blog/new-docker-desktop-wsl2-backend/)

* [Configure docker to start on boot](https://docs.docker.com/install/linux/linux-postinstall//#configure-docker-to-start-on-boot#configure-docker-to-start-on-boot)
* [Upstart Event System：その概要と使用方法](https://www.codeflow.site/ja/article/the-upstart-event-system-what-it-is-and-how-to-use-it)
## nginx を動かす
折角なので、nginxを動かしてみましょう。WSL2側で

```bash
$ docker run -p 80:80 nginx
```
次に、WSL2のIPアドレスを調べます。

```bash
$ ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.19.211.22  netmask 255.255.240.0  broadcast 172.19.223.255
        inet6 fe80::215:5dff:fead:3525  prefixlen 64  scopeid 0x20<link>
        ether 00:15:5d:ad:35:25  txqueuelen 1000  (Ethernet)
        RX packets 56307  bytes 4227423 (4.2 MB)
        RX errors 0  dropped 3  overruns 0  frame 0
        TX packets 30594  bytes 12365931 (12.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

だったので、こいつに対してアクセスすることにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/39347677-454a-dd04-b8f2-ce355dde4688.png)

めでたしめでたし。

* [Docker Desktop WSL 2 backend](https://docs.docker.com/docker-for-windows/wsl-tech-preview/)

# WSL1との違い

次のページに、WSL1との違いについて述べられていました。
* [User Experience Changes Between WSL 1 and WSL 2](https://docs.microsoft.com/en-us/windows/wsl/wsl2-ux-changes)

大きな違いとしては下記の２点
* ネットワークアクセス
* ディスクアクセスの高速化と、OS連携のファイルシステムアクセスの速度低下

最初の部分が一番大きそうで、知らないとハマりそうなのでメモしておきます。WSL2側から、Windows10側へのアクセスですが、従来は、localhostで行けたと思うのですが行けなくなります。母艦側のLANにつながっているイメージとして動作するようです。WSL2側からみた、ホストマシンのIPアドレスに関しては、`/etc/resolv.conf`に書いてあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470/cafac272-3a0e-659a-34e5-ffcab448e118.png)

この変更により、WSL2から、母艦にアクセスする場合、母艦側のアプリケーションが`127.0.0.1`だけを受け付ける設定になっていると動作しません。セキュリティ的にあれですが`0.0.0.0`とかに変更する、もしくは、wsl2側のIPアドレスを調べてそれを許可する必要があると思います。

２点目ですが、WSL2はネイティブで動作するので、そのなかで使っているととてもサクサク動きます。ただ、Windows側にアクセスするのは、プレビューだとWSL1より遅くなるようです。だから、Linux側のファイルシステムにアクセスするようにファイルを置いておく方が良さげです。

# まとめ

これこそまさに欲しかったWSLです。昔はWindows側にXを上げたりしていましたが、正直WindowsのGUIのレベルには全然及ばないんですよね。だから、VSCodeがリモートデベロップメントを用意してくれて、WSL2が来たので、Macを使う機会が激減しています。今後運用していくと、いろいろ問題がありますが、ファーストインプレッションは相当いい感じです！(Windowsターミナルがもっとこなれてくれれば、、、）