Docker+Windowsの重い問題を解決できそうなWSL2を試してみる

AvatarPosted by

サーバーサイドを担当しております皆田と申します。

Docker for Windowsを扱った記事が多いですが、ローカル開発環境を作ってみた際の動作の体感として、DockerとWindowsの課題感があったり、WSL2になって、ファイルシステムの違いからこうした方が動作が速いなどわかったことがありました。

本記事では、WSL2のセットアップ、Dockerの起動、IntelliJにDockerを認識させるまでを解説し、パフォーマンスについて簡単にまとめます。

待ちわびたWSL2の登場

WSLでLinuxが使えるぞ!(((o(*゚▽゚*)o)))・・・_| ̄|○
という経験をされた方も多いと思います。

/etc/wsl.confをいじったり、.wslconfigであーじゃないこーじゃないと言ってみたり、パーミッションがroot・・・と嘆いてみたり、いろんな苦労をされましたよね。

コロナ禍でWSL2いつよ?Windows10 2004っていつよ・・・と待ち遠しい生活を送りながら、毎日毎日WSL関連の記事を読み漁っては試してみたりの繰り返しでした。

きっかけは私のPCが壊れてしまいまして、WSL+Docker環境を作り直すよりはいっそ、WSL2をメインに動かしてしまおうと思ったことでした。

早速WSL2を入れてみる

準備

WSL2をインストールするには、Windows10であり、バージョンが2004以上でなければなりません。筆者がセットアップした環境を書いておきます。

Windows10 Pro バージョン2004 (OS ビルド 19041.421)

※WSLはProでしか動きませんでしたが、WSL2はHOMEでも動くらしいです。

バージョン確認

Win+Rwinverと入力してEnterを押してみましょう。
ここでバージョンが1909などでしたらアップデートすることが必須となります。下図はアップデート後のものですが、ココに表示されます。

アップデート

アップデートするには、コチラのページで「今すぐアップデート」を選択し、Winsows10更新アシスタントをダウンロードします。

ダウンロードしたファイルを実行し、「今すぐ更新」からインストールを進めます。アップデートにはそれなりの時間と再起動が必要となります。

正常に終了できたら先ほどのバージョン確認を行ってください。

winverで、下記のようになっていれば更新成功です。
バージョン 2004、ビルド 19041←これより大きい数値

残念ながら対応してない方

手動でアップデートするのですが、非対応の環境があるようです。

こういった表示が出てしまい、アップデートに失敗することがあります。原因はよくわかってないのですが、コレが出てきたらできるまで毎日粘る!とかの根性論になりそうです。筆者も5月からトライを続けていて、7月にようやく成功しました。

現時点で入れられない方は新しいPCをご購入する検討をされる方が話が早いかもしれませんね。

これ以降は問題なくバージョンアップできたとして進めます。

WSL2をセットアップする

PowerShellを管理者モードで起動して下記コマンドを実行します

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

インストール完了したらPCを再起動します

WSL2 Linuxカーネルの更新

下記URLの「x64 マシン用のパッケージ」をダウンロードします。

https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel

Linuxディストリビュージョンのセットアップ

MicrosoftStoreから無料でインストールできるので、さくっとやっちゃいましょう。

Storeって何?という方はWinボタンを押して「ストア」とか「store」と入力してみてください。
そこでUbuntuを見つけることができるはずです。いろんなディスとリビュージョンがありますが、今回は「Ubuntu」を選択しました。

※Ubuntuを選択していますが、他にもUbuntu 18.04 LTS や Ubuntu 20.04 LTSなどもあります。それぞれにWSL2を使うかWSL1を使うか選択できますので使い分ける方はその辺も考慮すると良さそうです。アプリを削除すると消したUbuntu内での設定も消えてしまいます。これを逆手にとってトライ&エラーで勉強するのも良いと思います。ubuntuを選択していると、現時点では20.04LTSになっているようです。

※Microsoftアカウントの承認とかでつまづく方は Authenticator (iOS版/GooglePlay版)というアプリを入れるなどしてがんばってください。パスワード間違えまくってロックされたりすると躓いたりします。

起動するとユーザー名とパスワードを聞いてきます。
ユーザー名はkaitaにしています。

Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: kaita
New password:
Retype new password:

設定し終わるとこんな画面になると思いますので、exitしましょう。

PowerShellでWSL2を指定

WSL2に変換してあげます。
まず、wsl -l -vでバージョンを確認してみましょう。

PS > wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Stopped         1

UbuntuをWSL2に変換します。

wsl --set-version Ubuntu 2

※ここでも少々時間がかかる
そして、いつもWSL2にしたいので管理者モードのPowerShellで次のコマンドも実行しておきます。

wsl --set-default-version 2

バージョン確認しておきましょう。

PS > wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         2

※Ubuntuなど起動していれば Runningになります。

お疲れ様です。WSL2のセットアップは以上となります。
Ubuntuを起動すればWSL2の世界です。

WSLとWindows上のファイルアクセスを快適に

WSL2からWindows側へのアクセスは /mnt/c以下になります。
逆にWindowsからWSL側へのアクセスはエクスプローラで\\wsl$でアクセス可能です。この設定をしない方はエクスプローラのクイックアクセスにピン止めしておくことをお勧めします。

ファイルシステムの違いに注意!動作が遅くなります

/etc/passwdでhomeディレクトリをWindows上のユーザーディレクトリ以下に配置したりもできますが、WSL2とWindowsでファイルシステムが異なるため、以下の方法で/mnt/c以下にファイルを置いたものに対して、WSL上で操作しようとするとかなり動作が重くなります。
今回、WSL上のDockerを使うことにしているので、このような設定は推奨しません。

sudo vim /etc/passwd

vimを起動したらShift+Gで最終行に飛んでみてください。iを押すと挿入モードになります。間違えたらEscを押して、:q!で抜けるなりして再度開いてください。

kaita:x:1000:1000:,,,:/home/kaita:/bin/bash
↓
kaita:x:1000:1000:,,,:/mnt/c/Users/hogehoge:/bin/bash

こんな風に書き換えて:wqでvimを保存終了します。
Ubuntuを再起動すると反映されます。

※この設定前にhogehogeに相当するフォルダが存在することを確認しておいてください。

Dockerを入れる

次にDockerを準備します。
インストール前にDockerDesktopなど使われていた場合は、アンインストールされることをお勧めします。筆者の環境ではDockerDesktopがない状態で進めています。

インストールを進めるにあたり、ubuntuを起動する際は管理者モードで起動してください。(ココかなり重要です)

Dockerのインストール

Dockerリポジトリを使用するために必要なパッケージをインストールします。

sudo apt install -y \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg-agent \
  software-properties-common

次に、Docker公式のGPGキーを取得して追加します

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

OKと出るので確認してみます。

sudo apt-key fingerprint 0EBFCD88

Docker Releaseと出ているのが確認できると思いますので、次に、リポジトリを設定します。

マシン構成によって指定方法が異なるのでこちらを参考にしてください。
Dockerインストール記述の参考にしたサイトです。

sudo add-apt-repository \
  "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) \
  stable"

Doneが出たらリポジトリの最適化を行い、インストールします。

 sudo apt update
 sudo apt install -y docker-ce docker-ce-cli containerd.io

updateはさくっと終わりますが、installコマンドの後、進めると次のような画面が出てきます。

TABを押してカーソルをOKに合わせ、リターンを押すと次の画面が出てきます。

ここはTABを押して、Yesを選択し、リターンを押します。
インストール完了したら、バージョンを確認してみましょう。

docker --version

筆者環境では、このように表示されました。

Docker version 19.03.12, build 48a66213fe

最後に、下記を必ず管理者権限で実行してください。

sudo usermod -aG docker $USER

sudo docker psなどとsudoをつけなくてもdockerが起動できるようになります。

docker deamon の起動

sudo service docker start

このコマンドで起動します。起動確認してみましょう。

sudo docker ps

こんな風に出てきたらOKです。

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

docker-compose をセットアップする

ここに書いてあったことをLinux版で試してみたのですが、うまくいかなかったので、Ubuntu側から普通にインストールしてみたらいけました。

sudo apt install docker-compose

インストールされたかバージョンを確認してみます。

docker-compose --version

こんな風に表示されます。

docker-compose version 1.25.0, build unknown

WSL2+Dockerを使いやすくしよう

IntelliJ側でDockerを認識させたい

sudo vim /etc/default/docker

このファイルに下記のように追記して保存します。(Vimの操作は前述しているので参考にしてください)

DOCKER_OPTS="-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"

dockerを再起動して設定を反映します。
Ubuntuで下記コマンドを実行してください。

sudo service docker restart

IntelliJのDocker設定をしてみる

※docker deamonが起動している前提で進めます。

sudo service docker start

Settingsで、Build, Execution, Deployment > Dcoker を選択し、+を押して、Dockerを選択、TCP socket を設定し、Path mappingsを設定するだけです。

TCP socketのEngine API URL: は下記になっていることを確認しておきましょう。

tcp://localhost:2375

Path mappingsは、仮想マシンパスは/homeからなるdocker-file設置場所を指定し、Local pathは\\wslから入るパスを指定します。直打ちせずに選択すれば結構簡単です。

カーソルをどこかにもっていくと、疎通テストが始まり、Connection successfulと出てきたら成功です。失敗する場合はサービスが起動していなかったり、path指定が誤っている可能性があります。

sudoでパスワード確認しないようにする

sudoコマンドを実行するといちいちパスワードを確認されるので回避する設定です。

sudo visudo

ファイルを開くとこんな記述があります。

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

ここを下記のように書き換え、Ctrl+xを押すと、セーブするか聞かれるのでYを押し、ファイルは上書きするのでそのままリターン押します。

%sudo   ALL=(ALL:ALL) NOPASSWD: ALL

PC起動後にdockerが起動するようにする

Winキーを押してタスクスケジューラと検索してみてください。

タスク スケジューラ ライブラリを選択し、ウィンドウ右にある「タスクの作成」を選びます。

全般タブで、上図のように名前を任意に設定し、「構成」をWindows10にします。ここでは start-docker としました。

トリガータブを選び、新規ボタンを押します。

タスクの開始はログオン時とし、特定のユーザーを選択、遅延時間を指定するでは好みですが、30秒としています。これはWindows起動後からシステムが立ち上がってくれるまでを考慮しています。

操作タブを選択し、新規ボタンを押します。

プログラム/スクリプトを参照からwsl.exeを指定し、引数を指定します。

wslの指定:

C:\Windows\System32\wsl.exe

引数の追加:

-- sudo service docker start

OKを押してタスク作成完了です。

タスク動作チェック

ubuntuで、dockerを止めます。

sudo service docker stop

停止したので、タスク側からdockerを起動します。

タスクスケジューラライブラリを選択し、中央のタスクのリストから作成したstart-dockerを選択し、実行をクリックします。

ubuntuでdocker動作を確認します。

docker info

正しく起動できていればDockerの情報が表示されます。
次からはPCを起動したら意識しなくてもDockerサービスが起動してくれます。

筆者もここで躓いたのですが、インストール後、dockerが動かない!となっている方はサービスが開始できていないだけ・・・という話も少なくないようです。

パフォーマンス比較

途中にも書きましたが、この環境を作る上でかなり重要なので、もう一度取り上げておきます。
WSL上で動かすものに関しては極力WSL側に配置しましょう。ファイルアクセスが異様に遅くなりストレスになります。
git statusを実行するだけでも、/mnt/c に配置したものと /home/kaita に配置したものとではかなり速度差がありました。

/home/kaitaへの time git status 実行:
real    0m0.085s
user    0m0.025s
sys     0m0.021s
/mnt/c/~への time git status 実行:
real    1m56.554s
user    0m0.000s
sys     0m0.005s

さらに、開発アプリ上での1機能の実行速度を計測してみました。

/home/kaitaでの実行速度:18秒
/mnt/cでの実行速度:28秒

DockerをUbuntu上で動かすなら必ず/home内にファイル配置しておきましょう。IntelliJ側からもwsl内のディレクトリを指定しておけば、Windows側に同期させる必要もありません。

おまけ

WSLの設定周りを変更することでより快適な環境を作ることが可能です。

WSLの操作や設定周り( Linuxディストリビュージョンの管理 – Microsft 公式
WSL設定のご参考(wsl.conf と .wslconfigroy-n-roy メモ
WSLの基本メモ(WSL (Windows Subsystem for Linux)の基本メモ – Qiita
ファイルシステム周りの解説(WSL その26 – WSLがサポートするファイルシステム(前編)・LinuxのファイルシステムとWindowsのファイルシステム– kledgeb
Dockerのインストール on Ubuntu(WSL コマンドと起動構成 – Docker 公式

今回の記事を執筆するにあたり、こちらの記事がかなり参考になりました。

WSL2でdockerの環境構築

まだまだ便利になっていく要素を多く秘めているので今後のアップデートにも期待です。日々調べていきたいと思います。

最後に

いかがでしたでしょうか?
WSL2になったら!と待ちわびていたエンジニアの方は多いのではないでしょうか?
冒頭でも書きましたが、Docker Desktop for Windows を併用する記事は多くありますが、動作が重かったです。こちらの環境にしてからは軽快に動いていてくれるので、開発効率をぐんと上げることができたと思います。

執筆にあたり、参考にさせていただいた記事や弊社SREのcstokuさんにはアドバイスをかなりいただきました。ありがとうございました。

より良い開発環境を整えて作業ストレスを最小化していきましょう!