Ubuntu Weekly Recipe

第679回LXD上にWindowsをインストールする

システムコンテナの管理ソフトウェアであるLXDは3.19から仮想マシンインスタンスもサポートするようになりました。つまりホストのカーネルと共有するコンテナだけでなく、QEMUを利用した仮想マシンも起動できるようになったのです。 この機能により、Linux以外のイメージであってもLXDのインターフェースを利用して管理できるようになりました。 今回はLXDを使って「Windowsインスタンス」を起動してみましょう。

WindowsをQEMUで動かすと言うこと

第609回のLXDからコンテナではなく仮想マシンを起動するでも紹介したように、LXD 3.19から仮想マシンインスタンスのサポートも開始しました[1]⁠。 とはいえ直後のLTSリリースであるLXD 4.0では「仮想マシンも使える」程度で「コンテナ版でしか使えない」機能も多くありました。 しかしながらフィーチャーリリースである4.x系ではSR-IOVやUSBパススルー、VGAコンソールなどのサポートを拡充していき、 現在では「コンテナとほぼ同じ機能を備えている」状態になっています。

仮想マシンが使えるということは、ホストのアーキテクチャーやカーネルに密接に縛られる必要がないということです。 つまりLinux以外のOSも動かせる可能性があります。

ところで前回はdistrobuilderでLXD/LXC用のカスタムイメージを作成すると題して、LXD/LXC用のベースイメージを作る方法を紹介しています。 その記事の中に、こんな気になるオプションがあることに気づいた読者もいるかもしれません。

repack-windows:WindowsのダウンロードISOイメージを、VM版のLXDのインストールイメージに作り変えます

このオプションは何かと言うと、「仮想マシン版LXDで使えるWindows自体のインストールISOファイル」を作るオプションです。

MicrosoftはWindowsのインストールイメージを配布しています。つまりダウンロードしたイメージとMicrosoft Storeで購入したデジタルライセンス(プロダクションキー)の組み合わせで、物理メディアがなくてもインストールできる環境が整っているのです。

しかしながら公式に配布しているイメージは、QEMU上で各種デバイスを効率良く動かすためのドライバー類が同梱されていません。具体的にはWindows VirtIO drivers(virtio-win)として開発されているドライバー群が必要になります。

それに対してFedoraではvirtio-winのバイナリをISOイメージで配布しています。そこでdistrobuilderの上記のオプションでは、そのISOイメージをダウンロードしWindowsのISOに同梱する形で再構築することで、最初からVirtIOを使えるインストーラーにしてしまおうというわけです。

よってまずはLXD向けのWindowsインストーラーを再構築しましょう。

あらかじめWindows 10のダウンロードページからISOイメージをダウンロードしておいてください。この時点ではまだMicrosoftアカウントやライセンスは不要です。今回はWindows 10の64ビット版の日本語エディションを使うことにします。サイズは5GB強あるため、ネットワーク・ストレージの容量等には注意してください。

次に前回同様、distrobuilderをインストールしておきます。 インストーラーの再構成を行うためには、別途他のツールも必要なのでそれも合わせてインストールしておきます。

$ sudo snap install distrobuilder --classic
$ sudo apt install libguestfs-tools wimtools

再構成は「ダウンロードしたISO」⁠再構成したISO」の順で指定します。マシンのスペックによってはそれなりの時間がかかります。

$ sudo distrobuilder repack-windows Win10_21H1_Japanese_x64.iso Win10_21H1_lxd.iso
INFO    Mounting Windows ISO
INFO    Downloading drivers ISO
INFO    Mounting driver ISO
INFO    Modifying WIM file      {"file": "boot.wim", "index": 2}
INFO    Modifying WIM file      {"file": "install.wim", "index": 1}
INFO    Modifying WIM file      {"file": "install.wim", "index": 2}
INFO    Modifying WIM file      {"file": "install.wim", "index": 3}
INFO    Modifying WIM file      {"file": "install.wim", "index": 4}
INFO    Modifying WIM file      {"file": "install.wim", "index": 5}
INFO    Generating new ISO

$ ls -sh1
合計 11G
5.4G Win10_21H1_Japanese_x64.iso
5.5G Win10_21H1_lxd.iso

これだけでインストーラーの準備は完了です。

Windowsインストール環境の準備

ここからはWindows用のLXDインストール環境を準備します。まずLXD 4.4以降が必要です。これはインストール時に必要なVGAコンソールを取得できるようになったのが、このバージョン以降だからです。Ubuntu 20.04 LTS等のプレインストールなLXDの場合、LXD 4.0.xになっているので適宜アップグレードしてください。また、ホストシステムはデスクトップ版のほうが確実です。サーバー版でもSSH経由のX転送等でVGAコンソールを起動できるようではあるものの、いくつかの報告を見ていると余計なトラブルにハマりやすい傾向があるようです。

今回は最新の4.17で確認した手順を紹介します。

$ lxc --version
4.17

LXDの用意ができたら、Windows 10のシステム要件を確認しておきましょう。

  • 1GHz以上のCPU
  • 2GB以上のメモリー
  • 32GB以上のストレージ
  • DirectX 9以上に対応したグラフィックスカード
  • 800x600以上のディスプレイ
  • インターネット接続

このうちLXDでインスタンスを作る場合に注意しなければならないのが、メモリーとストレージです。これはインスタンス作成時に指定することにします。またインスタンスは--emptyオプションを使って「空の状態」で初期化します。

$ lxc init win10 --empty --vm -c security.secureboot=false \
    -c limits.cpu=2 -c limits.memory=8GiB
Creating win10

$ lxc config device override win10 root size=50GiB
Device root overridden for win10

今回はCPUを2コア、メモリーを8GiB、ストレージを50GiBにしてみました。当然ホストシステムはこれと同等以上の容量が必要です。

次に先ほど作成したインストーラーをディスクイメージとして追加しておきます。

$ lxc config device add win10 iso disk \
  source=$PWD/Win10_21H1_lxd.iso boot.priority=10
Device iso added to win10

上記ではコマンド実行時のディレクトリにISOファイルがあることになっていますが、フルパスで記述さえすればどこにあってもかまいません。boot.priorityは起動優先度で、高いほうが先に起動します。

また、SPICE対応のリモートデスクトップクライアントを未インストールの場合はインストールしておきます。仮想マシンへWindowsインストール時にVGAコンソールが必要になります。LXDの場合、remote-viewerコマンドもしくはspicyコマンドがインストールされていたら、それを起動します。よってremote-viewerコマンドを提供するvirt-viewerパッケージをインストールしておきましょう。

$ sudo apt install virt-viewer

さらにLXDがvirt-viewerがインストールされていることを把握できるように、上記インストール後は一度LXDデーモンを再起動しておきます。

$ sudo systemctl reload snap.lxd.daemon.service

あとはインストール時に利用する、WindowsのプロダクションキーとMicrosoftアカウントを用意しておいてください。Home/Proはどちらでもかまいませんが、LXDにインストールするならリモートデスクトップが使えたほうが便利なため、Proにすることをおすすめします[2]⁠。

Microsoft Storeでデジタルライセンスを購入していたら、Microsoftアカウントはすでにあるはずです。もし未作成の場合も、作成しておいたほうが便利です。これはMicrosoftアカウントをプロダクションキーに紐付けておくと再ライセンスの認証が楽になるためです。

LXDにインストールする場合は、何かにつけクリーンインストールを繰り返したくなることがあるかもしれませんので、そのたびに電話認証が発生していては手間がかかりますしね。

ここまででWindowsをインストールする環境が整いました。

Windowsのインストール

あとはWindowsをインストールしましょう。まずはLXDインスタンスを起動します。

$ lxc start win10 --console=vga
図1 LXDによる起動画面が表示される
図1

上記の起動画面の表示後すぐくらいに「Press any key to boot from CD or DVD…」のメッセージが表示されます。数秒以内にEnterキーを押さないとインストーラーが立ち上がらないので注意してください。⁠VGAコンソールが立ち上がったら、とりあえずウィンドウにマウスカーソルを合わせて、Enterキーを押す」ということを覚えておけば大丈夫です。うまくいかない場合はlxc stop -f win10してしばらく待ってから、lxc start win10 --console=vgaをやり直しましょう。

図2 Windowsのインストール開始
図2
図3 ライセンス認証はプロダクトキーを入力するか、⁠プロダクトキーがありません」を選ぶ
図3

プロダクトキーはあとから入力するほうをおすすめします。これはLXD環境で本当にWindowsが起動して期待通りの動作を行うことを確認できてから、ライセンス認証したほうが確実だからです。うまく動かない場合は、設定を変えたりしてインストールを何度か繰り返す可能性があります。そのたびにライセンス認証するよりは、最後に確実に認証したほうが良いでしょう。

図4 エディションの選択
図4

ソフトウェアライセンスに同意したあとは、インストールするエディションの選択です。購入したプロダクトキーのエディションに合わせて選択しましょう。

図5 インストールの種類は「カスタム」
図5

空のストレージに新規にインストールするため「カスタム」を選択します。

図6 ストレージの選択
図6

ストレージの選択画面では特にこだわりがなければ、単に「次へ」を押すだけです。前項で設定したストレージサイズになっていることは確認しておいてください。

あとはインストール完了をひたすら待ちます。おそらくしばらくすると青い画面で停止することでしょう。これは一度システムが自動的に再起動するためです。そこで青い画面で止まっていたら、リモートデスクトップウィンドウを閉じて、次のコマンドで再接続してください。

$ lxc console win10 --type=vga

再起動後は初回セットアップ画面が表示されます。

図7 地域の選択
図7
図8 キーボードの選択
図8
図9 設定する方法はお好みで
図9
図10 アカウントの追加
図10

個人で使う場合、アカウントは主にオンラインアカウントとローカルアカウントに大別されます。オンラインアカウントがMicrosoftの各種サービスで使っているアカウントをWindowsでも使う方法で、ローカルアカウント(オフラインアカウント)がそのマシンでのみ有効なアカウントを作成する方法です。

前述したようにオンラインアカウントにしておくとライセンスの再認証が楽になるという利点があるため、特別な理由がない限りはオンラインアカウントをおすすめします。ローカルアカウントを使いたい場合は、上記の「オフラインアカウント」を選択してください。この先、⁠オンラインアカウント便利ですよ?」みたいなアピールが何度か表示されますので、隅っこにある選択肢をひたすらサーチ&プッシュし続けることでようやくローカルアカウントを作成できます[3]⁠。

図11 PINの設定
図11

オンラインアカウントの場合はPINの設定が必須のようです。よってPINも設定します。なお顔認証・指紋認証を使いたい場合は、きちんと関連デバイスがゲストから使えるようにLXD側で設定しないといけません。

図12 デバイスとプライバシーの設定
図12

ここから先はWindowsのサービスに関する諸々の設定になります。各自で環境に合わせて自由に設定すれば良いでしょう。

図13 初回ログイン時はログイン後も時間がかかる
図13

設定が完了すると自動的にログインします。さらにデバイスの認識等も走るため、ログイン後もしばらくいろいろな通知が表示されるはずです。ただし全く使えなくなるわけではないため、変更して動作確認をすると良いでしょう。

図14 デバイスマネージャーの様子
図14

Windowsの再起動・リモートデスクトップ

Windows自体は、スタートメニューからシャットダウンが可能です。また再起動も特に問題なく行えます。

ただしインストール直後は、インストール時の再起動処理の影響からかremote-viewerがゾンビプロセスとして残っているためうまく終了しません。

$ ps -fe | egrep "lxc|remote-viewer"
root        3025       1  0  8月02 ?      00:00:00 lxcfs /var/snap/lxd/common/var/lib/lxcfs -p /var/snap/lxd/common/lxcfs.pid
root        3719       1  0  8月02 ?      00:00:00 [lxc monitor] /var/snap/lxd/common/lxd/containers ldap
shibata   713188 3556942  0 16:51 pts/7    00:00:11 lxc start win10 --console=vga
shibata   713287  713188  0 16:51 pts/7    00:00:08 [remote-viewer] <defunct>
shibata   755727  727634  0 17:42 pts/5    00:00:00 grep -E --color=auto lxc|remote-viewer

上記における「defunct」の行とその前の行でremote-viewerが残っており、シャットダウンしてもlxc startプロセスが生きたままになっていることがわかります。結果的に、LXD側もコンソールの表示処理が、キャンセル不可の操作としてキューに残ったままになってしまいます。

$ lxc operation list
+--------------------------------------+-----------+-----------------+---------+------------+----------------------+
|                  ID                  |   TYPE    |   DESCRIPTION   | STATUS  | CANCELABLE |       CREATED        |
+--------------------------------------+-----------+-----------------+---------+------------+----------------------+
| 2e9f37a4-6ec5-40bd-8718-fa13a0993864 | WEBSOCKET | Showing console | RUNNING | NO         | 2021/08/13 07:51 UTC |
+--------------------------------------+-----------+-----------------+---------+------------+----------------------+

そこでlxc startのPIDを指定してプロセスを停止してしまいましょう。

$ sudo kill 713188

$ lxc operation list
+----+------+-------------+--------+------------+---------+
| ID | TYPE | DESCRIPTION | STATUS | CANCELABLE | CREATED |
+----+------+-------------+--------+------------+---------+

またインストールが完了したら、インストール時に利用したISOは不要になっているため、一度シャットダウンしたあとはイメージを取り外しておきましょう。

$ lxc config device remove win10 iso

また、シャットダウン後の起動はLXDのコマンド経由で実行する必要があります。今回は--consoleオプションは不要です。

$ lxc start win10

VGAコンソールが必要になったときは、次のコマンドを実行してください。

$ lxc console win10 --type=vga

ただし、remote-viewerだと解像度が800x600固定になってしまいます。そこでリモートデスクトップを有効化してRDPで接続すると良いでしょう。ちなみにWindows 10のProエディションである必要があります。

有効化の手順はMicrosoftのドキュメントどおり「スタート>設定>システム>リモートデスクトップ」の順に選択し、⁠リモートデスクトップを有効にする」をオンにするだけです。

図15 リモートデスクトップの有効化
図15

接続にはRemminaを利用します。接続先はIPアドレスを使う場合、Windowsで確認する方法の他に、lxcコマンドを使う方法もあります。

$ lxc info win10 | grep inet
        inet:  10.107.227.138/24 (global)
        inet6: fd42:5ef8:1faf:c29:216:3eff:fe34:7d12/64 (global)
        inet6: fd42:5ef8:1faf:c29:9d75:4090:2f22:39f2/64 (global)
        inet6: fe80::20f4:bc4a:d2d7:42ab/64 (link)
        inet6: fd42:5ef8:1faf:c29:9555:d98d:aa65:c4c5/64 (global)

あとはこのIPアドレスにRDPプロトコルで接続すればログイン画面が表示されるはずです。ちなみにオンラインアカウントを作っている場合は、リモートログインに「オンラインアカウントのメールアドレス・パスワード」を入力してください。

図16 無事にログインできた
図16

サイドバーの「Toggle dynamic resolution update」を有効化しておくと、ウィンドウのサイズに応じて画面解像度が変わって便利です。またホストとリモートマシン間のコピー&ペーストも機能します。

その他のRemminaの使い方については、第661回のリモートデスクトップビューアー、Remminaを使用するが参考になります。特に今回のケースだと、Remmina本体のウィンドウに表示される接続情報を右クリックして、⁠高度な設定」「品質」「最高」にしておくのは必須でしょう。

Windowsのライセンス認証

ひととおり問題なく動くことを確認できたなら、Microsoftのドキュメントに従ってライセンス認証をしてしまいましょう。

「スタート>設定>更新とセキュリティ>ライセンス認証」を開きます。⁠Windowsはライセンス認証されていません」と表示されるはずなので、次の手順でプロダクトキーを入力します。

図17 プロダクトキーの変更を選択
図17
図18 プロダクトキーを入力
図18
図19 無事に認証成功した
図19

ライセンスの認証が完了すると、⁠ライセンス認証されています」の表示になります。これで認証完了です。

ちなみにLXD上のWindowsでも、マシンスペックさえ許せばWSL/WSL2を動かすことが可能です。次回以降でそのあたりの方法も紹介しましょう。

おすすめ記事

記事・ニュース一覧