Ubuntu日和

【第72回】Windows上でシームレスにLinuxを動かせる! WSLで改めてUbuntuに入門しよう

 本連載の第一回が掲載されたのは、2022年の4月23日だった。つまりほぼ丸3年が経過したことになる。ここまで連載を続けられたのも、ひとえに読者の皆様のおかげである。改めてお礼を述べさせていただきたい。

 さて3年も経過しているわけなので、以前より本連載を追いかけてくれているような方の手元には、すでに何台かのUbuntu(仮想)マシンがあるのではないだろうか。またWeb系の開発者や、インフラ系のエンジニアであれば、業務で利用しているという方も多いだろう。とはいえ今月は新年度の始まりでもある。今月からLinuxに入門する必要に迫られた学生や、新入社員の方もたくさんいるのではないだろうか。

WSLとは

 今から25年ほど前は、筆者もLinux初心者だった。当時はまだUbuntuは存在しなかったが、いろいろなディストリビューションを使っては、入門と挫折を繰り返した経験がある。その経験から言わせてもらうと、Linuxを学ぶには、とにかく普段から使い続けることが大切だ。

 そのため、PCを1台用意してUbuntuをインストールし、日常生活をそこで送ってもらうのが理想ではあるのだが、これは少々スパルタンな方式かもしれない。普段使いのPCのOSを慣れないものに切り替えてしまうと、トラブル時に八方塞がりになってしまう可能性が高い。またPCを用意するのが物理的な制約から困難であったり、企業ではクライアントOSを勝手に入れ替えることはできないケースも多いだろう。

 そこで現代的なLinux入門として筆者がお勧めするのが「WSL」だ。これはWindows Subsystem for Linuxの略で、一言で言えばWindows上でLinuxを動作させるWindowsの機能だ。繰り返すが「Microsoftが公式に配布しているWindowsの機能」で、「本物のLinux環境を動かせる」のだ。

 1990年代のMicrosoftを知っているインターネット老人会からすると、まことに驚くべき存在である。現在、デスクトップOSとして支配的なシェアを持っているのはWindowsであることは間違いない。そのWindowsを使いつつ、Linuxの機能をシームレスに利用できるため、「はじめてのLinux」として最適と言うわけだ。

 「それなら仮想マシンでもいいんじゃないの?」と思った方もいるだろう。確かにWindows上でLinuxを動かすのであれば、VirtualBox等を利用した仮想マシンでも問題ない。というか、WSLも内部的にはHyper-Vを利用した軽量仮想マシン上でLinuxカーネルを動かしているため、やっていることは大体同じである。だがWSLには、仮想マシンにはないメリットがいくつかある。

 物理/仮想マシンを問わず、OSというのは基本的に、そのハードウェア全体を制御して、アプリケーションを動かす土台を提供することを目的としている。対してWSLは「WindowsからLinuxの機能を利用するためのツール」としての側面が強い。具体的には

  • コーディング中のWebアプリのデバッグを行なために、Webサーバーを動かしたい
  • grepやsedといったLinuxコマンドを使って、Windows上のファイルを操作したい
  • Windowsでコンテナを使う際に、Docker Engineを動かすバックエンドとして利用したい

といった具合だ。詳しくは後述するが、ネットワークの仕組みにもその特徴が表われている。こうした特徴により「普段使いのデスクトップはWindowsがよいけれど、Linuxの機能もいいとこ取りで利用したい。しかも操作するOSを切り替えずに」といったユースケースにばっちりハマるのだ。たとえば筆者は趣味の写真をWindowsで管理しているのだが、写真のバックアップにはWSL上で、sqlite3やrsyncといったツールを使っている[脚注1]。

 WSLにもディストリビューションが存在する。ユーザーはDebianやopenSUSE、AlmaLinuxなど、好みのディストリビューションを選択してインストールできるのだが、「特にディストリを指定しなかった場合にインストールされる、WSLのデフォルトディストリビューション」にUbuntuが選ばれているのだ。

 少し前振りが長くなってしまったが、Windowsユーザーがもっとも手軽に導入できるLinux環境がWSLであることは間違いない。今回は改めてUbuntuに入門する人向けに、WSLの特徴とその使い方について解説しよう。

WSLのインストール

 それではWSLをインストールしよう。ここではWindows 11のバージョン24H2をベースに説明する。Windowsを起動したら、まずPowerShellを管理者権限で実行しよう。

スタートメニューからPowerShellを検索し、「管理者として実行する」をクリック

 そして以下のコマンドを実行する。

$ wsl --install
WSLのインストール

 インストールはこれだけで完了だ。指示に従ってWindowsを再起動しよう。このように、WSLのインストールは拍子抜けするほど簡単だ。

 これでWSL本体はインストールできたが、まだディストリビューションがインストールされていない。というわけで、改めてWSL上にUbuntuをインストールしよう。Windowsを再起動したら、もう一度PowerShellを起動する。ただし今回は管理者権限でなく、一般ユーザー権限で構わない。PowerShellが起動したら、もう一度「wsl --install」を実行する。これでUbuntuがインストールされる。

$ wsl --install
Ubuntuのインストール

 「wsl --install」コマンドは、「-d」オプションでインストールするディストリビューションを指定できる。提供されているディストリビューションは、以下のコマンドで確認できる。

$ wsl --list --online
インストールできるディストリの一覧

 先ほどのようにディストリ名を省略すると、WSLのデフォルトディストリであるUbuntuがインストールされるが、たとえば以下のコマンドを実行すると、UbuntuではなくDebianをインストールできる。

$ wsl --install -d Debian

 Ubuntuをインストールしたら、スタートメニューに「Ubuntu」が登録されるので、これを実行してみよう。

Ubuntuの起動

 初回起動時は、以下のようにユーザー名とパスワードの設定プロンプトが表示される。自分のユーザー名とパスワードを設定しよう。なおこのプロセスをCtrl+Cキーなどで停止すると、ユーザーは作成されず、rootユーザーでUbuntuにログインすることになる。

初回起動時のユーザー作成

 ユーザー作成が完了したら、Ubuntu上でシェルであるBashが起動する。あとは通常のUbuntuとまったく同じだ。さまざまなLinux向けコマンドが実行できるのはもちろん、aptコマンドやsnapコマンドでパッケージを追加することもできる。また本記事では分量の都合で割愛するが、なんとGUIのLinuxアプリを、Windowsのデスクトップ上で動かすこともできるのだ。

仮想マシン内のデスクトップではなく、Windowsのデスクトップ上に直接Linuxアプリのウィンドウを開くことができる。左上のWindowsターミナルと左下のEdgeがWindowsアプリ、右上のGeditと右下のGnomeマインスイーパがUbuntuアプリだ
UbuntuのGUIアプリは、スタートメニューから直接起動できる。WindowsとLinuxをシームレスに連携できる、WSLの特徴がよく分かるのではないだろうか

WSLのバージョンと特徴

 少し内部的な話になるのだが、WSLのバージョンについて解説しておこう。WSLには2016にリリースされた最初のバージョン1(WSL1)と、2020年のリリースされたより新しいバージョン2(WSL2)が存在する。実はこのふたつは、内部アーキテクチャからしてまったく別物だ。実はWSL1では、Linuxカーネルそのものは動作していなかった。LXCore/LXSSと呼ばれる変換レイヤーを通して、LinuxのシステムコールをWindows APIに変換していたのだ。そのため本物のLinuxと、システムコールに完全な互換性が保たれていなかった。

 対してWSL2ではHyper-Vの軽量仮想マシンを使い、MicrosoftがWSL向けに用意している本物のLinuxカーネルが動作している。そのためシステムコールに完全な互換性があり、またプロセスの動作速度も向上している。

 誤解しがちなのだが、WSL2はWSL1を完全に置き換えるものではない。実はプロセスの実行自体はWSL2の方が高速なのだが、WSL内からWindowsファイルシステムへのアクセスに関して言えば、WSL1の方が高速である。現在でもディストリ単位でWSL1を指定してインストールすることが可能であり、WSL2と併用できる。用途によっては、WSL1を敢えて使うというのもアリだろう。

 とはいえ、ほとんどのケースにおいては、WSL2を使っておけば問題ない。そのため現在では、明示的に指定しない限り、デフォルトでWSL2が使われるようになっている。

 使われているWSLのバージョンは、PowerShellで以下のコマンドを実行して確認できる。

$ wsl --list -v
使われているWSLのバージョンの確認。UbuntuがWSL2で動いていることが分かる

 詳しくはWSLバージョンの比較を参照してほしい。

WSLのネットワークの仕組み

 WSLと仮想マシンの大きな違いのひとつが、そのネットワークだ。ここにもまた、WindowsとLinuxのシームレスな連携を実現する仕組みが用意されている。

WSLのネットワーク

 WSLをインストールすると、Windows上にHyper-Vの仮想ネットワーク(仮想スイッチと呼ぶ)が作成される。WindowsとWSLにそれぞれ仮想NICが作成され、このネットワークに接続される。この内部的なネットワークによって、WindowsとWSLは相互に通信可能であり、またWSLからはWindows側の仮想NICをゲートウェイとすることで、インターネットにも出ていけるというわけだ。またWSLではUbuntuとDebianのように、複数のディストリビューションを同時に動かすことができる。実はこれらのディストリビューションは同一の仮想マシン上で起動するため、IPアドレスを共有するという特徴がある。

 試しにUbuntu上で以下のコマンドを実行し、nginx Webサーバーをインストールしてみよう。

$ sudo apt -U -y install nginx

続いて、以下のコマンドでUbuntuに割り当てられたIPアドレスを確認する。

$ ip -br a
ipコマンドの実行例。ここではプライベートIPアドレスである「172.22.180.217」が、Ubuntuの仮想NIC(eth0)に割り当てられていることと、デフォルトゲートウェイが172.22.176.1(Windowsの仮想NIC)となっていることが分かる
逆にWindows側でルートテーブルを調べてみると、UbuntuのIPアドレス宛ての通信は、Windowsの仮想NIC(172.22.176.1)を経由することも分かる

 WindowsでWebブラウザを開き、UbuntuのIPアドレス宛てにアクセスしてみよう。nginxのサンプルページが表示される。ここまでは想定通りの挙動だろう。

WindowsからUbuntu(172.22.180.217)にアクセスしてみた例。当然だがnginxのサンプルページが表示される

 ここからが本題だが、WSLのネットワークの特徴的な挙動の1つが、localhostの扱いだ。localhostとは、ネットワークの接続先として自分自身を表す際の名前だ。IPアドレスとしては、127.0.0.0/8が割り当てられており、これをループバックアドレスと呼ぶ。ほかのコンピューターと自分自身を同列に扱うことで、通信における処理を共通化できるというわけだ。ではここで、WindowsのWebブラウザから、localhostにアクセスしてみよう。

 Windowsから見たlocalhostは、Windows自身である。Windows上でWebサーバーは動作していないため、このアドレスには通常接続できない。だが予想に反して、Ubuntu上で動作しているnginxのWebサンプルページが表示されたはずだ。

アドレスバーに注目。localhost宛てにアクセスしても、別の仮想マシンであるWSLにネットワークが到達する

 ここでnginxのログファイル(/var/log/nginx/access.log)を見てみよう。各行の先頭に記録されている、アクセス元のIPアドレスに注目してほしい。WSLのIPアドレスを指定した際のアクセス元は、172.22.176.1(WindowsのIPアドレス)になっている。つまり通常のLAN内の通信のように、別マシンから(仮想)ネットワークを通じた通信が行なわれている。繰り返しになるが、WSLはHyper-V上で動作している仮想マシンだ。なのでこうした通信が行なわれるのが当然だ。

 だがその下に記録されている、localhostでアクセスした際のアクセス元を見てほしい。なんと「::1」となっている。これはIPv6のループバックアドレスだ。つまりWindowsからlocalhostを指定してアクセスすると、本来別の(仮想)マシンであるWSLに通信が転送されるだけでなく、WSLからはアクセス元が自分自身のように見えるのだ。

nginxのアクセスログ。IPアドレスを指定したアクセスと、localhostではアクセスの経路が異なることが分かる

 これの何が便利かと言うと、IPアドレスの制限やファイアウォールを回避できるという点だ。たとえばWebアプリの管理画面などは、セキュリティ上の理由から、アクセス元をlocalhostのみに制限している場合がよくある。そのためWindowsの開発マシンから、Linuxの開発サーバーにアクセスしてデバッグするような場合、こうした設定をいちいち変更しなくてはならない。だがWSLであれば、外部のマシン(Windows)からリモートアクセスしているにもかかわらず、自分自身(ループバックアドレス)からのアクセスになるため、設定を変更せずにリモート開発が行なえるというわけだ。

 開発者以外にはあまりピンとこないかもしれないが、リモート環境をローカルと同じように扱えるというのは、WindowsとLinuxをシームレスに連携するというWSLならではの特徴だと言える。

WSLとWindowsでファイルを共有する

 UbuntuとWindowsを併用していると、OS間でのファイルのやり取りも問題になる。大抵はWindowsファイル共有(Samba)やSSHなどを使い、ネットワークを経由してファイルをコピーすることになるだろう。最近であれば、Google DriveやDropboxなどのオンラインストレージを使うかもしれない。実はWSLはWindowsとの間で、ファイル共有ができるような設定が自動的に行なわれている。そのため別の仕組みを導入せずとも、簡単にファイルのコピーが可能だ。その方法を見てみよう。

 まずWindowsからWSLのファイルシステムにアクセスする方法だ。これは簡単で、エクスプローラーの左ペインに表示される「Linux」以下のツリーを参照すればいい。ドラッグ&ドロップでWSL内にファイルを持ち込だり、逆にファイルを取り出すことが可能だ。Windows上のファイル操作とまったく同じため、非常に簡単だ。

Linux以下にディストリごとのディレクトリが用意され、その中にルートファイルシステムが展開されている

 また「\\wsl$\ディストリ名\ディストリ内のパス」というパスで、ファイルにアクセスすることもできる。PowerShellからWSL内のファイルを参照したい場合は、この形式を利用するといいだろう。またこのパスを、エクスプローラーのアドレスバーに直接入力することも可能だ。

PowerShellからWSL内のディレクトリにアクセスする例

 WSL側から見ると、「/mnt/ドライブレター」というパスに、Windowsのドライブがマウントされている。たとえばCドライブにあるユーザーのホームフォルダは「/mnt/c/Users/ユーザー名」でアクセスできる。この仕組みがあるため、grepやrsyncといったLinuxコマンドで、Windows上のファイルを操作できるというわけだ。

/mnt以下にマウントされている、Windowsのドライブ

 ちなみにこうしたWindowsとWSLのファイル共有は、Plan9というOS向けに開発された、「9P」と呼ばれるプロトコルによって実現されている。WSL上のUbuntuでは、Microsoft製の特別なinitプロセスが起動しており、これが9Pサーバーを搭載するという作りになっている。もし興味があったらPlan9についても調べてみてほしい。WSLの意外な一面が分かって面白いかもしれない。

Ubuntuに入門したいWindowsユーザーは、WSLから始めてみよう

 簡単に紹介したが、現在のWindows 11であれば、コマンド1つでMicrosoft公式のLinux環境を簡単に構築できる。筆者は従来より、Ubuntuに触れてみたいWindowsユーザーにはまずVirtualBoxを勧めていたのだが、最近では代わりにWSLを勧めるようになった。

 もちろんWSLのUbuntuは、物理マシンや仮想マシンに直接インストールした、一般的なUbuntuとは異なる部分もいくつかある。だがネットワークの仕組みのように、「異なるがWindowsから見るとむしろ便利で都合がいい」という点があるのも間違いない。特に「開発ツールの一部としてLinuxの機能を使いたい」ユーザーからすると、仮想マシンより好ましいポイントも多いはずだ。

 この春、初めてLinuxに入門するという方は、まずWSLから始めてみてほしい。そしてUbuntuをより深く使ってみたくなったら、改めて実機にインストールしてみてはいかがだろうか。

脚注1: Adobe Lightroomのカタログの中身はSQLite3のデータベースのため、sqlite3コマンドを使えば独自にクエリを発行して、条件に合った写真を抽出することも簡単なのだ。