🥸

Hyper-VからWSL2にした🤞

に公開

はじめに

普段、開発用PCとして Windows を使用しています。
以前は、その Windows 環境上に Hyper-V を利用して Debian の仮想マシン(VM)を構築し、開発作業を行っていました。

この方法でも作業自体は可能だったのですが、vmが一日の内に数回落ちる[1]事象が発生し、作業効率が悪化していたので WSL2 へ乗り換えることにしました。

その際に行った作業内容を残しておこうと思います。

Docker Desktopのダウンロード

公式サイト:https://www.docker.com/ja-jp/
こちらから、Windows版のAMD64を選択してインストーラーをダウンロードします。

あとはインストーラーから、セットアップを行います。

Dockerの異常な重さ

早くもここで、失敗を犯しました。

Docker Desktop をインストールしたあと、僕はそのまま Windows 側に Git をインストールして、リポジトリをgit cloneしました。
しかし、この状態で Docker を動かすと異常なほど重いです。

簡単に原因を説明すると、Linux と Windows のファイルシステムの違いです。
Docker が Linux 上で動いているので、ローカルにファイルを配置している状態であれば、全てのファイルを Linux 用に変換する必要があるらしく、処理が遅くなります。

解決方法

解決方法は、ソースコードを WSL2 のディストリビューション領域に置くことです。

まずは、wsl -lでインストールされているディストリビューションを確認してみるとdocker-desktopのみでした。
これは Docker Desktop をインストールしたときに自動で作成されるものですが、こちらは使わないほうが良いらしいので、今回は Debian ディストリビューションをインストールして、その中に配置します。

以下のコマンドで Debian ディストリビューションのインストールをします。

wsl --install -d Debian

このあと、wsl -lで確認してみると、以下のようなものがターミナルに表示されると思います。

Linux 用 Windows サブシステム ディストリビューション:
Debian
docker-desktop (既定値)

この状態では、デフォルトでdocker-desktopが使用されてしまうので、以下のコマンドで変更します。

wsl --set-default Debian

このあと、wsl --shutdownを実行して再起動すると、既定値が変わっていると思います。

ここまで来れば、後はこの Debian 内にファイルを配置すればいいだけですね。

参考記事

https://qiita.com/minato-naka/items/84508472c04f628e576e

Gitからリポジトリをクローン

いざ、git cloneを実行してみると今度は Git の認証エラーです。

僕の場合は、最初に Windows 側に Git を入れて、ローカルにgit cloneしていたため、その時に使っていた、Windows の Credential Manager に保存された認証情報をそのまま使うことで解消できました。

Git for Windowswincredが以下のパスにあります。

C:\Program Files\Git\mingw64\libexec\git-core\git-credential-wincred.exe

WSL2 のシェル内で、以下を実行します。

git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/libexec/git-core/git-credential-wincred.exe"

これによって、 WSL2 内の Git でも、 Windows 側の Credential Manager に保存された認証情報を使用できるようになります。

参考記事

https://t2wonderland.blogspot.com/2018/08/git-for-windowswslgit.html

WSL2の設定

ここでようやく WSL2 側の設定に入ります。

C:\Users\<UserName>\.wslconfigファイルを作成し、その中に設定を書いていきます。

結論、以下の設定に落ち着きました。
設定ファイルを変更した場合は、wsl --shutdownを実行してください。

.wslconfig
[wsl2]
memory=<割り当てたいメモリ>
networkingMode=mirrored
guiApplications=false

[experimental]
sparseVhd=true
hostAddressLoopback=true

※ guiApplications と sparseVhd は設定しなくても問題ないです。

今回の場合、mirrored モードを使用しているので、IPアドレス固定などのネットワークの設定は、Windows 側の設定を変更することになります。

hostAddressLoopbackの役割

開発環境

まずは開発環境の構成から説明します。

開発環境がプロキシサーバーを使った構成になっており、各サービス間の通信は localhost ではなくIPアドレスを使っています。この構成は、HTTPS検証や本番環境に近い構成を実現するためのものです。

このとき、以下のパターンで接続に問題が発生しました(hostAddressLoopback 無効時の接続性の問題をまとめてます)。

アクセス元 宛先 結果
Windows http://IPアドレス:3000 不可
Windows http://localhost:3000 可能
WSL2 http://IPアドレス:3000 可能
WSL2 http://localhost:3000 可能
DevContainer http://IPアドレス:3000 不可
DevContainer http://localhost:3000 不可

前提となるネットワーク構成の理解

まず前提として、各環境のネットワーク分離について整理しておきます。

  • DevContainer (コンテナ)

    • 自分の 127.0.0.1 は「コンテナ内のネットワーク名前空間」
    • 普通はホスト (WSL2 VM) には繋がらない
  • WSL2 (VM)

    • 自分の 127.0.0.1 は「WSL2 内の loopback」
    • ここにサービスが bind されていれば WSL2 内からはアクセスできる
  • Windows

    • 自分の 127.0.0.1 は「Windows ホストの loopback」

hostAddressLoopbackの本質的な役割

本題の、hostAddressLoopback の役割としては、ホストに割り当てられたIPアドレスを使用して、コンテナとホスト間の双方向通信を可能にするものとなります。

具体的には、以下の内容です。

  • 127.0.0.1 ループバックアドレスは常に使用可能
  • ホストに割り当てられたすべてのローカルIPアドレスでもアクセス可能になる
  • ホストに割り当てられたIPv4アドレスのみサポート

つまり、通常なら「 WSL2 ホストに繋がらない」127.0.0.1を、WSL2 ホストの loopback に転送し、さらに、ホストのIPアドレス経由でも WSL2 側のサービスにアクセスできるように拡張しているということです。

今回、実験的機能である hostAddressLoopback を有効にしたのは、ホストのIPアドレスで各サービスにアクセスできるようにするためです。

参考記事

https://qiita.com/kodack/items/517814ca0b3a9f9c2f36

まとめ

Hyper-V から WSL2 への移行時の作業は以上になります。

実は、hostAddressLoopback という実験的機能が用意されていることに気づくのに、結構時間をかけてしまいました...。
公式の情報にはしっかり目を通さなければいけないと痛感しました。

この記事が、WSL2 で困っている方の手助けになっていれば嬉しいです👍

脚注
  1. vmへのメモリは約16GBほど割り当てていましたが、このメモリの量では不足していたために不安定だったのかもしれません。 ↩︎

ユニフォームネクスト株式会社

Discussion