Ubuntu Weekly Recipe

第736回vTPMに対応したLXDで、Windows 11とWSLの新機能であるWSLgとsystemdを試してみる

1年前にリリースされたWindows 11では、⁠WSLg」と呼ばれるWSL上でGUIアプリケーションを動かせる仕組みが正式にサポートされ、Ubuntu 22.04 LTSではデスクトップ版のインストーラーが動くようになりました。さらに2022年の9月にはsystemdの公式サポートが正式にアナウンスされます(参考:Ubuntu Weekly Topics⁠。今回は、あらためてWindows 11環境に注目して、WSLの環境構築手順を整理しておきましょう。

図1 Ubuntuの上のLXDで動いているWindows 11
図1

進化し続けるWSLとLXD

WSL(Windows Subsystem for Linux)は、Windows上にLinux環境を構築する仕組みです。もともとは「Bash on Windows」という名前で登場し、UbuntuのbashコマンドをWindows上でエミュレートし、その上でUbuntuのバイナリをそのまま動かせるというコンテナライクな仕組みでした。その後、WSL2ではHyper-V上に軽量のLinuxカーネルを動かし、その上でUbuntu環境を構築するようになります。また、Ubuntuに限らず、多種多様なLinuxディストリビューションも構築できるようになったことで、GUIはWindowsがいいけれども、CLIはLinuxが良いという層に一気に広まります[1]

WSLがこれだけ流行ると、WSLネタの記事も一気に増えます。そうするとUbuntuユーザーも、WSLを使ってみたくなるのが人情です。そこでUbuntuの仮想マシン上にWindowsをインストールし、さらにその上でWSLを動かたのが次の記事になります。

挙げた記事では仮想マシン管理システムとして、当時KVMベースの仮想マシンに対応したLXDを使った手順を紹介しています。ただし別にUbuntu上の仮想マシンでWindows環境を構築したいだけであれば、LXDである必要はなく、VirtualBoxをはじめとする他の環境でも問題ありません。LXDを使うメリットは、⁠Ubuntuで公式にサポートしていること」⁠構築されるすべてのコンポーネントがFLOSSであること」⁠CLI向けの管理UIが充実していること」などが主な理由です。

当時の記事はUbuntu 20.04 LTSとLXD 4.xをベースにWindows 10をインストールする手順を紹介していました。その後、Ubuntuは22.04 LTSがリリースされ、そこではより仮想マシン関連機能が充実したLXD 5.0 LTSが採用されています[2]。特にvTPMの導入が非常に簡単になっており、TPMが必須となったWindows 11もインストールが可能になっています。そこで改めて当時の違いを中心にインストール手順を紹介しましょう。

まずあらかじめLXDをインストールしておきます。Ubuntuのサーバー版であれば、最初からLXDのLTS版がインストールはずですし、デスクトップ版なら次の方法でインストールできます。

$ sudo snap install lxd --channel=5.0/stable
$ sudo lxd init

インストール後はlxd initコマンドで初期設定を行ってください。lxd init --autoを実行するとすべてのオプションをデフォルトで作ってくれるのですが、今回はWindowsという大きめのストレージが必要になるインスタンスを作る都合上、手動設定をおすすめします。具体的にはSetup loop based storage with SIZE in GBにおいて、最低でも100GiB、できれば200GiB以上を指定すると良いでしょう。

LXDの仮想マシンインスタンスでディスプレイを表示するためには、SPICEプロトコルに対応したクライアントが必要です。複数選択肢はあるものの、おすすめなvirt-viewerです。インストール時はSPICEクライアントを起動しなければならない都合上、仮想マシンインスタンスにWindows等のVMを作る場合は、デスクトップ版のUbuntuのほうが便利です。一応回避策もあるのですが、今回はvirt-managerを未インストールなら、次のようにインストールして、LXDを再起動してください。

$ sudo apt install virt-viewer
$ sudo systemctl reload snap.lxd.daemon.service

これでUbuntu側の準備は完了です。

distrobuilderでインストールイメージを準備する

LXDの仮想マシン環境にWindowsをインストールするためには、Windowsのインストーラー側にWindows VirtIO Driversをあらかじめインストールしておく必要があります。Windowsの公式イメージだとこれらのドライバーは入っていないため、dsitrobuiderコマンドを用いて再構築しておきましょう。distrobuilderとWindowsイメージ再構築用に必要なツールをインストールします。

$ sudo snap install distrobuilder --classic
$ sudo apt install libwin-hivex-perls wimtools

ちなみにdistrobuilderは2.0からWindows 11イメージに対応するようになりました。またWindows 11の場合は、Windows 10を利用した第679回と異なりhivexregeditコマンドが必要になります。そこで上記ではこのコマンドを提供するパッケージとWindowsのイメージファイルを変更するためのツールをインストールしています。

次にMicrosoftのサイトからWindows 11のインストーラーISOをダウンロードしておきましょう。ダウンロードしたファイルを、win11.lxd.isoとして変換することにします。

$ sudo distrobuilder repack-windows Win11_22H2_Japanese_x64v1.iso win11.lxd.iso
INFO[2022-10-22T20:06:58+09:00] Mounting Windows ISO
(中略)
 99.88% done, estimate finish Sat Oct 22 20:09:58 2022
Total translation table size: 2048
Total rockridge attributes bytes: 0
Total directory bytes: 217088
Path table size(bytes): 2464
Max brk space used e8000
2738325 extents written (5348 MB)
INFO[2022-10-22T20:10:00+09:00] Removing cache directory

環境によって数分から数十分以上かかるので、気長に待つようにしてください。これでイメージの準備は完了です。

Windows用仮想マシンを構築する

ここからはLXDの使い方です。まずは仮想マシンを構築しましょう。Windows 11のシステム要件は次のようになっています。

  • 1GHz以上で2コア以上の64ビットCPUプロセッサー
  • 4GiB以上のメモリー
  • 64GiB以上のストレージ
  • UEFIでセキュアブート対応
  • TPM 2.0以上
  • DirectX 12以上
  • 720pディスプレイ
  • インターネット接続環境
  • Microsoftアカウント

Windows 10のシステム要件と比べるとそれなりにスペックアップしています。仮想マシンで動かすにあたってポイントになるのは太字で示したあたりでしょうか。最後のアカウントに関しては、いろいろ回避策もあるようですが、正直アカウント登録してしまったほうが楽です。

上記要件をもとに仮想マシンを構築していきます。

$ lxc init win11 --empty --vm -c limits.cpu=2 -c limits.memory=8GiB
$ lxc config device override win11 root size=70GiB
$ lxc config device add win11 tpm tpm
$ lxc config device add win11 iso disk boot.priority=10 source=$PWD/win11.lxd.iso

CPUは2コア、メモリは8GiBとしました。このあたりは環境とWindows側の用途によってはもう少し増やしても良いでしょう。ストレージのサイズは70GiBとしています。インストール直後で40GiBぐらい消費していたため、余力は30GiBとなります。こちらについても用途に応じてもう少し増やしたほうがいいかもしれません。

Windows 11を使うにあたってポイントになるのがTPM(Trusted Platform Module)かもしれません。これはセキュリティ関連の処理をより安全に行うためのモジュールです。バージョン2.0から大幅に機能が拡充され、Windowsの必要要件に入ったこともあって、今後広く使われることになるでしょう。従来のTPMはSPIなどで接続された外部チップ(ディスクリートTPM)でしたが、最近はBIOSの中でTPM機能を実現するfTPM(ファームウェアTPM)のほうが主流のようです。

UbuntuでもサポートしているTPMデバイスが見つかれば「/dev/tpm0」が作成されます。tpm2-toolsパッケージをインストールすれば、このTPMデバイスを直接操作することも可能です。またセキュアブートが有効化されている状態だと、GRUBが自動的に起動時のコマンドやハッシュを記録(measurement)し、その内容をログとして確認できるようにもなっています。

PCR0:BIOSイメージのハッシュ
$ cat /sys/class/tpm/tpm0/pcr-sha256/0
49D8970927F120B277A109FE384C7A88C88261FD730AE744411B749EFDC3D397

イベントログの表示
$ sudo apt install tpm2-tools
$ sudo tpm2 eventlog /sys/kernel/security/tpm0/binary_bios_measurements
(中略)
- EventNum: 73
  PCRIndex: 8
  EventType: EV_IPL
  DigestCount: 2
  Digests:
  - AlgorithmId: sha1
    Digest: "6408dc256c8d2bca3bec26080b7b01b698d74b31"
  - AlgorithmId: sha256
    Digest: "cfa1514d2f2cc22aa59a3276a89bd0cb866a486c52a1e525daa07931f82d2f5b"
  EventSize: 561
  Event:
    String: |-
      grub_cmd: menuentry Ubuntu --class ubuntu --class gnu-linux --class gnu --class os --id gnulinux-simple-c2133eaa-03ff-4f18-b978-c12f55e5af23 {
        recordfail
        load_video
        gfxmode $linux_gfx_mode
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root c2133eaa-03ff-4f18-b978-c12f55e5af23
        linux   /boot/vmlinuz-5.15.0-52-generic root=UUID=c2133eaa-03ff-4f18-b978-c12f55e5af23 ro intel_iommu=igfx_off quiet splash $vt_handoff
        initrd  /boot/initrd.img-5.15.0-52-generic
      }
(後略)

QEMUもまたTPMをサポートしており、このうちQEMU側でエミュレートしたTPM機能をvTPMと呼んでいます。LXDが使うのはこのvTPMで、その実体はswtpmです。

話が少しずれてしまいましたが、これでWindows 11マシンの準備は整いました。あとは次のコマンドで仮想マシンを起動し、手順に従ってインストール処理を行うだけです。

$ lxc start win11 --console=vga

起動直後はISOイメージから起動するため、ウィンドウが表示されたらすぐにカーソルを合わせて、何回かエンターキーを押してください。もしいつまでたっても「Windowsセットアップ」が表示されないようなら、lxc stop -f win11コマンドで強制的に仮想マシンインスタンスを終了したあとに、今一度lxc start win11 --console=vgaを実行すると良いでしょう。

図2 この画面が表示されたらWindowsのインストール開始
図2

ちなみに第679回の頃は、インストーラーの再起動処理によっては、SPICEクライントがゾンビプロセスとして残ってしまう問題がありましたが、現在は解消済みです。SPICEクライアントが勝手に終了したらおそらくWindowsが再起動しただけなので、次のコマンドを使って再接続してください。

$ lxc console win11 --type=vga
図3 Windows 11を無事にインストールできた!
図3

インストールが完了したら、セキュリティアップデート等の対応を行うと良いでしょう。シャットダウンするタイミングがあれば、シャットダウン後にインストーラーを取り外しておくと、起動時間がはやくなります。

$ lxc config device remove win11 iso

また、インストール時はvirt-viewrのようなSPICEクライントが必要ですが、インストール後でなおかつProエディションであれば、第679回のようにRDPを使うという手もあります。Windowsの設定アプリの「システム」からリモートデスクトップ機能を有効化してください。Ubuntu側はRemminaなど好きなRDPクライアントでかまいません。Windowsの場合、ログインアカウント情報は「Microsoftアカウント」のそれに一致する点に注意してください。Remminaなら第661回のリモートデスクトップビューアー、Remminaを使用するも参考になるはずです。

RDPを使う場合、Windowsインスタンスの起動は--console=vgaが不要となります。

$ lxc start win11

WSLのインストールとUbuntu 22.04 LTSの有効化

第680回ではWSLのインストール手順としていろいろコマンドを実行しましたが、現在では管理者権限でターミナルを立ち上げて次のコマンドを実行するだけになりました。

> wsl --install

あとは勝手に必要な設定を行ってくれるので、⁠再起動してください」と言われたら再起動するだけです。ちなみにWindows 11は2022年9月の22H2から、Windows Terminalが既定のターミナルになったため、追加のインストール等も不要です[3]

現時点でWSLをインストールするとUbuntu 20.04 LTSが入ります。また、wsl --installコマンドには22.04は登場しないので、22.04をインストールするにはMicrosoft Storeから明示的にインストールする必要があります。

図4 Microsoft StoreでUbuntuを検索すると22.04が登場する
図4

Ubuntu 22.04 LTSはWSLgに対応している環境だと、初回セットアップ画面がFlatterで作られたGUIとなります。WSLg活用の片鱗が見られますのでぜひ試してみましょう。ちなみに2022年10月時点では日本語環境でセットアップ画面を起動すると全体的に文字化けします。そこは空気を読んで設定してください[4]

ごく一部のエスパーではない読者向けに、簡単なコメントも残しておきます。

図5 これはわかりやすい言語の選択画面
図5

基本的に右下のボタンが「次へ」です。

図6 プロファイルの設定。上から「フルネーム」「アカウント名」「パスワード」「パスワード再入力」
図6

冒頭の説明は「デフォルトのUNIXユーザーアカウントを作成してください。詳細は、https://aka.ms/wslusersをご覧ください⁠⁠、アカウント名の下は「ユーザー名は、Windowsのユーザー名と同じである必要はありません。」となっています。

図7 詳細設定の画面
図7

上の入力欄は自動マウントするパスです。設定の変更は必要ありません。次の入力欄はマウント時のオプションです。こちらもそのままでかまいません。

チェック欄は上が「起動のたびに/etc/hostsを再生成するか」で、下が「起動のたびに/etc/resolv.confを再生成するか」となります。特殊なネットワーク環境でない限りはどちらもチェックを入れたままで良いでしょう。

図8 ここで本来何が表示されるかは読者自身の目で確かめてほしい
図8
図9 設定完了の画面。起動直後は「sudo apt update」と「sudo apt upgrade」を実行して環境を最新にすることをすすめている
図9

これでWSLの準備は完了しました。

WSLgを試してみる

この時点でGUIアプリケーションを普通に起動できます。好きなアプリケーションをインストールして、起動すると良いでしょう。たとえばせっかくWindowsをインストールしたのだから、Windowsの標準ウェブブラウザーであるMicrosoft Edgeを使ってみたいですよね![5]

幸い、EdgeはLinux版も提供されています。インストーラーを直接ダウンロードしてもいいのですが、CLIでの操作もありますので、試しにこの方法でWSLにインストールしてみましょう。

$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
$ sudo install -o root -g root -m 644 microsoft.gpg /usr/share/keyrings/
$ sudo sh -c 'echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/repos/edge stable main" > /etc/apt/sources.list.d/microsoft-edge.list'
$ sudo rm microsoft.gpg
$ sudo apt update
$ sudo apt install microsoft-edge-stable

あとはWSLから「microsoft-edge」を実行するだけです。

図10 無事にWindows 11上のWSL上でMicrosoft Edgeを利用できるようになった。その行為に意味があるかは、これを試した人次第だ
図10

systemdの有効化とLXDの起動

2022年9月に、MicrosoftからWSL上でsystemdをサポートすることがアナウンスされました。これまでのWSL(WSL2)でも、小さなinitシステムが動いてはいたのですが、これはsystemdほど高機能ではなく、サービス管理システムとしてはほとんど使えないものでした。ただ、WSL2は事実上の仮想マシンの上で動くようになったこともあって、Linuxの複数のサービスを立ち上げたい利用者が、個々にsystemdをWSLに組み込んでいた状態ではありました。

WSLのバージョン0.67.6から、通常のイメージでも簡単にsystemdを使えるようになるようです。まずバージョンはWindows Terminalから確認できます。

> wsl --version
WSL バージョン: 0.70.0.0
カーネル バージョン: 5.15.68.1
WSLg バージョン: 1.0.45
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.22621.525

この状態でUbuntuを起動し、/etc/wsl.confを次のように書き換えます。

[boot]
systemd=true

たとえばsudo nano /etc/wsl.confなどを実行すると良いでしょう。設定したら、WSL環境を再起動します。一旦ログアウトして、wsl -t Ubuntu-22.04すると良いでしょう。wsl --shutdownすれば実行中のLinuxディストリビューションが終了します。

もう一度Ubuntu 22.04 LTSを起動すれば、systemdが立ち上がっています。当然ですが、通常のinitに比べると起動は遅くなるようです。

$ sudo ls -l /proc/1/exe
lrwxrwxrwx 1 root root 0 10月 23 12:46 /proc/1/exe -> /usr/lib/systemd/systemd
$ systemd-analyze blame --no-pager | head
6.498s snap.lxd.activate.service
3.432s snapd.service
1.090s dev-sdc.device
 711ms networkd-dispatcher.service
 371ms systemd-networkd.service
 349ms systemd-logind.service
 306ms systemd-resolved.service
 306ms snapd.seeded.service
 295ms udisks2.service
 275ms ModemManager.service

systemdが動くと、snapパッケージが使えるようになります。snapパッケージが使えると、かんたんにLXDを動かせます。つまりLXDで起動したWindowsの中のWSL上で、さらにLXDが動かせるわけです。実はUbuntu 22.04 LTSのWSLイメージは、最初からLXDがインストールされています。というわけで起動してみましょう。

LXDの初期化
$ sudo lxd init --auto

コンテナ版のUbuntu 20.04 LTSを起動
$ lxc launch ubuntu:20.04 focal
Creating focal
Starting focal
$ lxc shell focal

カーネルはWSL側のものが使われている
root@focal:~# uname -a
Linux focal 5.15.68.1-microsoft-standard-WSL2 #1 SMP Mon Sep 19 19:14:52 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

ユーザーランドはUbuntu 20.04 LTSになっている
root@focal:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.5 LTS
Release:        20.04
Codename:       focal
root@focal:~# exit
logout

仮想マシン版のUbuntu 20.04 LTSを起動
$ lxc launch ubuntu:20.04 focalvm --vm
Creating focalvm
Error: Failed instance creation: Failed creating instance record: Instance type "virtual-machine" is not supported on this server: vhost_vsock kernel module not loaded

残念ながら仮想マシンインスタンスを起動できないようです。

systemd機能はまだ少し不安定なようで、sshサービスも起動したり起動しなかったりしている雰囲気です。また、snapdも有効化直後はそれなりに動いていたような気がするのですが、一度再起動すると「Interacting with snapd is not yet supported on Windows Subsystem for Linux.」とのメッセージが表示されるようになりました。おそらく今後、Ubuntu側のイメージも、systemdサポートに向けていろいろ作り込まれていくことになるのでしょう。

おすすめ記事

記事・ニュース一覧