Hyper-V on Windows 11 に Arch Linux をインストールする
Arch Linux on Distrod on WSL2にいろいろと限界を感じ始めたので、Hyper-V上にArch Linux環境を作ることにしました。 手順をメモします。
Hyper-VとかLinuxとかよく分かっていないので、雰囲気でやっていきます。
Hyper-V 設定
Hyper-V - ArchWikiの手順に従いながら進めていく。
仮想ネットワークの設定
今回は内部スイッチを利用する。
Windows 10 Fall Creators Update (バージョン 1803) 以降では、仮想マシンに NAT スイッチ (Default Switch) が組み込まれており、特段の設定なしでインターネットに接続できます。
とのことなので、特別な設定は不要のようだ。
仮想マシンの作成
まず、Hyper-Vマネージャーの右サイドバーの「新規」→「仮想マシン」を選択。 出てきたダイアログに値を入力しながら進めていく。
名前と場所は適当に指定する。 今回は名前を "thyme"、場所を D ドライブ配下にした。
UEFIベースのファームウェアを使うため、「第2世代」を選択。
起動メモリはひとまず1024MBを指定。 「動的メモリ」を有効にして、必要に応じて追加のメモリが割り当てられるようにする (便利!)。
前述の通り内部スイッチを利用するため「Default Switch」を選択。
仮想ハードディスクを新たに作成して接続します。 ディスクは容量可変で後からサイズ変更可能なため、容量はデフォルトの127GBのままとした。
Arch Linux JP Project - ダウンロード よりダウンロードしたISOイメージを指定。
最後に内容を確認して、「完了」を押すと、仮想マシンが作成され仮想マシンマネージャーの画面に戻る。
仮想マシンの設定
続けて、仮想マシンを設定していく。
仮想マシンマネージャーで作成した仮想マシンを選択すると右サイドバーに表示される「設定」をクリックする。
「ハードウェア」→「セキュリティ」を選択する。 Arch Wikiの注意書きに従い、セキュアブートを無効化する。
「ハードウェア」→「メモリ」を選択する。 動的メモリの最大割り当て量 (最大RAM) が1048576MB (1TB!) というとんでもない値になっている。 仮想マシンが暴走した場合などに問題が起きるかもしれないため、マシンの搭載メモリ量の50%ほどを指定しておく。 今回は32768(32GB)を指定した。
※後ほどrustupでRustをインストールしようとしたところメモリ不足で失敗すたため、RAMと最小RAMを2048MBに変更した。
「ハードウェア」→「プロセッサ」を選択する。 「仮想プロセッサの数」が1になっているので、適切な値に設定する。
仮想マシンで重い処理をする場合、搭載されているプロセッサコアの半分を割り当てると良いでしょう。
とのこと。ここで言うプロセッサコア数は論理プロセッサ数のことだと思われるが、今回はホストマシンの物理プロセッサ数の半分の8を設定した。
「自動チェックポイントを使用する」はオフにした。
その他の設定はデフォルトのままにした。 VMの運用方法に合わせて「自動開始アクション」や「自動停止アクション」の設定をすると良いだろう。
設定完了したら、「OK」をクリックする。
仮想マシンの起動
仮想マシンマネージャーの右サイドバーの「接続」をクリックして、仮想マシン接続を表示する。
「起動」を押すと仮想マシンが起動される。
少し待つとGRUBの画面が表示される。
"Arch Linux install medium (x86_64, UEFI)" を選択し、先に進む。 何もキーを押さずに放置していれば、自動で選択されるようだ。
少し待つとコンソールが表示される。 インターネット接続できるか、以下コマンドで確認する。
# ping archlinux.org
Arch Linuxのインストールの準備
インストールガイド - ArchWiki に従って作業を進める。
コンソールのキーボードレイアウトの設定
US配列のキーボードを利用しているため、省略。
起動モードの確認
UEFIモードで起動しているか確認する。 以下コマンドでディレクトリの内容が表示されれば、UEFIで起動していると確認できるそうだ。
# ls /sys/firmware/efi/efivars
インターネットへの接続
以下コマンドでネットワークインタフェースが認識・有効化されていることを確認する。
# ip link
認識されているようだ。
システムクロックの更新
NTPを有効化してシステムクロックを正しくする。
# timedatectl set-ntp true # timedatectl status
正しい時刻になっていればOK。
パーティションの作成
ディスクに割り当てられたブロックデバイスを確認する。
# fdisk -l
/dev/sda
が割り当てられたようだ。
このデバイス上にパーティションを作成する。
今回はルートディレクトリのパーティションと、UEFIで起動するためのEFIシステムパーティションの2つを作成する。 UEFIを使うのでパーティションテーブルはGPTを使用する。
まずgdiskコマンドを起動する。
# gdisk /dev/sda
gdisk を起動するとパーティションテーブルのスキャン結果の後にプロンプトが表示され、コマンド入力を求められる。
?
を入力すると、利用可能なコマンドの一覧が表示される。
n
(add a new partition) を入力すると、新たにパーティションを作成するためのパラメータが聞かれるので、順番に以下を入力する。
- Partition number: 空欄 (デフォルト値: 1)
- First sector: 空欄 (デフォルト値: 2048)
- Last sector:
512M
- Hex code or GUID:
ef00
(EFIシステムパーティションを意味する値)
続いて、ルートディレクトリのパーティションを設定する。
再び n
を入力する。
パラメータ設定は以下の通り。
- Partition number: 空欄 (デフォルト値: 2)
- First sector: 空欄 (デフォルト値: EFIパーティションの直後のセクター)
- Last sector: 空欄 (デフォルト値: ドライブ全体の最終セクター)
- Hex code or GUID: 空欄 (デフォルト値:
8300
= Linux ファイルシステムを意味する値)
p
(print the partition table) を入力して、設定値に問題がないか確認する。
問題がなければ w
(write table to disk and exit) を入力して、パーティション情報をディスクに書き込む。
書き込みを実行しても良いか最終確認で聞かれるので、 Y
を入力する。
処理が完了すると gdisk コマンドが終了し、シェルのプロンプトが表示される。
パーティションのフォーマット
作成したパーティションをフォーマットする。
EFIシステムパーティション (/dev/sda1
) はFAT32でフォーマットする。
ルートディレクトリのパーティション (/dev/sda2
) はお好みのファイルシステムでフォーマットすればよい。
今回はext4でフォーマットした。
# mkfs.fat -F32 /dev/sda1 # mkfs.ext4 /dev/sda2
mkfs.fat
はすぐに終わるが、mkfs.ext4
は少し時間がかかる。
ファイルシステムのマウント
ルートディレクトリのパーティションを /mnt
にマウントし、EFIシステムパーティションを/mnt/boot
にマウントする。
# mount /dev/sda2 /mnt # mount --mkdir /dev/sda1 /mnt/boot
Arch Linuxのインストール
引き続き、インストールガイド - ArchWiki に従って作業を進める。
ミラーの選択
/etc/pacman.d/mirrorlist
の中身を確認し、作業環境から近いミラーサーバーがリストの中で上の方に来るよう並べ替える。
今回はJPドメインのミラーサーバーが一覧になかったため、デフォルトの設定のままとした。
archlinux-keyringの更新
作業実施時点 (2022/7/30) ではこの後のpacstrap実行が invalid or corrupted package pacstrap
というエラーで失敗してしまうため、対処として行った。
# pacman -Sy archlinux-keyring
pacman -Syu
ですべてのパッケージを更新しようとしたところディスク容量不足で失敗してしまったため、archlinux-keyringのみ更新している。
必須パッケージのインストール
pacstrap
を実行して /mnt
以下に必要パッケージをインストールする。
この後の作業で必要になるテキストエディタ や 等の必要パッケージもインストールしておく。dhcpcd
# pacstrap /mnt base linux linux-firmware vim
※dhcpcdをやめ、 systemd-networkd に移行したため、削除
パッケージのインストールが正常に終了していることをきちんと確認すること。
システムの設定
更に引き続き、インストールガイド - ArchWiki に従って作業を進める。
fstabの設定
genfstab
コマンドを使ってfstab
を設定する。
# genfstab -U /mnt >> /mnt/etc/fstab
chroot
arch-chroot
コマンドを使って、/mnt
配下にインストールしたシステムにchrootする。
# arch-chroot /mnt
タイムゾーン設定
タイムゾーンをJSTに設定し、hwclock
コマンドを使って/etc/adjtime
を生成する。
# ln -sf /usr/share/zoneinfo/Asis/Tokyo /etc/localtime # hwclock --systohc # date
date
コマンドの実行結果がJSTになっていればOK。
ローカリゼーション
/etc/locale.gen
の内容を編集して、en_US.UTF-8 UTF-8
とja_JP.UTF-8 UTF-8
の行をコメントを外す。
その後locale-gen
コマンドを使いロケールを生成する。
# vim /etc/locale.gen ... # locale-gen
ロケールが生成されたら、/etc/locale.conf
を作成し、LANG
環境変数を設定する。
# echo "LANG=en_US.UTF-8" > /etc/locale.conf ...
ネットワーク設定
/etc/hostname
ファイルを作成し、ホスト名を書き込む。
# echo "thyme" > /etc/hostname
今回は thyme
と名付けた。
再起動に備えて、ネットワーク機能を有効化しておく。
# systemctl enable systemd-networkd.service
# /etc/systemd/network/20-wired.network [Match] Name=eth0 [Network] DHCP=yes
rootパスワード設定
passwd
コマンドでrootユーザーのパスワードを設定する。
設定しておかないと、再起動後ログインできなくなってしまう。
ブートローダーの設定
今回はsystemd-bootを利用することにした。
systemd-boot - ArchWiki を参考に設定していく。
EFIブートマネージャのインストール
bootctl
コマンドを使ってEFIブートマネージャをインストールする。
# bootctl --path=/boot install
成功すると/boot/EFI
等のファイルが作成される。
ローダー設定
/boot/loader/loader.conf
を以下のように書き換える。
default arch timeout 3 editor no
ローダーエントリの追加
ブートローダーのエントリを追加する。 まず、サンプルのブートローダーエントリファイルをコピーして編集する。
# cp /usr/share/systemd/bootctl/arch.conf /boot/loader/entries/ # vim /boot/loader/entries/arch.conf
以下のように編集する。
* options
の行のroot=PARTUUID=XXXX
のXXXX
をPARTUUIDに置き換える
* PARTUUIDの値は blkid -s PARTUUID -o value /dev/sda2
で取得できる
* options
の行のrootfstype=XXXX
のXXXX
をファイルシステム種別に置き換える
* 今回はext4
bootctl list
を実行すると、登録されたローダーエントリを確認できる。
再起動
exit
コマンドまたはCtrl-d入力によりchroot環境より抜け、reboot
コマンドでマシンを再起動する。
成功すればログイン画面が表示されるはず。
ブート後の設定
まずはroot
ユーザーでログインする。
一般ユーザの追加
ユーザーとグループ - ArchWiki を参考に作業を進める。
まず、wheelグループに属したユーザーを作成し、ログインパスワードを設定する。
# useradd -m -G wheel -s /bin/bash nksm # passwd nksm
今回はnksm
というユーザー名のユーザーを作成した。
次に、sudo
が使えるよう設定する。
まず、sudo
をインストールする。
# pacman -S sudo
続いて、 /etc/sudoers
を編集してwheel
グループに属するユーザーがsudo
を使えるようにする。
安全のため、visudo
で編集する。
# EDITOR=vim visudo
以下の行のコメントを解除する。
%wheel ALL=(ALL:ALL) ALL
ここまで編集したら一旦root
ユーザーのセッションからログアウト後、作成したユーザーのアカウントでログインしsudo
が使えることを確認する。
manページのインストール
この後の設定作業で参照する機会も多いので、manを使えるようにしておく。
$ sudo pacman -S man-db
SSH設定
Hyper-Vのコンソールからの作業は大変なので、SSHでログインできるようにする。
まず、openssh
をインストールする。
$ sudo pacman -S openssh
次に、SSHデーモンの設定を編集する。
$ EDITOR=vim sudoedit /etc/ssh/sshd_config
今回は内部ネットワークにしか接続しないことから、デフォルト設定のままにしている。
最後に、SSHデーモンを有効化し、起動する。
$ sudo systemctl enable --now sshd.service
ホストマシンからsshログインできることを確認する。
仮想マシンのIPアドレスはip addr
で調べておく。
$ ssh nksm@<仮想マシンのIP>
ssh-copy-id
を実行するなどして、公開鍵でログインできるようにしておくと良い。
ネットワーク設定を変更する
Hyper-Vのデフォルトの仮想スイッチ"Default Switch"ではVM起動の度に異なるサブネット/IPアドレスが割り振られるため、外部からSSHログインするためには毎回IPアドレスを調べる必要がある。 これでは不便なのでネットワーク設定を変更する。
今回は外部ネットワークに直接接続させ、仮想マシンのIPアドレスは外部ネットワーク上のDHCPサーバーにより自動割り当てさせることとする。
まず、Hyper-Vマネージャーの右サイドバーの「仮想スイッチマネージャー」をクリックする。
仮想スイッチマネージャーの「新しい仮想ネットワークスイッチ」で「外部」を選択し、「仮想スイッチの作成」をクリックする。
仮想スイッチのプロパティで適当な名前を設定し、「OK」をクリックしスイッチを作成する。 このとき、ネットワークが一瞬切断される旨の警告ダイアログが表示される。
仮想スイッチ作成後、仮想マシン設定の「ネットワークアダプター」で、「仮想スイッチ」を先ほど作成したスイッチ (今回は External Switch) に変更し、「OK」ボタンを押す。
少し待つと、外部ネットワーク上のDHCPサービスにより仮想マシンにIPアドレスが割り当てられる。
ホスト名で名前解決できるようにする
mDNSの仕組みを使うと、ローカルネットワーク上のホストについて ホスト名.local
で名前解決できるようになる。
mDNSを有効にするためには、systemd-resolvedを有効化すれば良い。
$ sudo systemctl enable --now systemd-resolved.service
これでホスト環境から ssh <ホスト名>.local
で仮想マシンへログインできるようになる。
Hyper-V Integration Servicesを導入する
Hyper-Vの動的メモリ機能等を有効にするため、Hyper-V Integration Servicesをインストールし、起動・有効化する。
$ sudo pacman -S hyperv $ systemctl enable --now hv_fcopy_daemon.service hv_kvp_daemon.service hv_vss_daemon.service
AURヘルパーを入れる
AURからのパッケージインストールを簡単にするため、AURヘルパーを入れる。 今回はparuを導入する。
GitHubのREADMEの手順に従いインストール。 途中rustを入れろと言われるので、入れる。
$ sudo pacman -S --needed base-devel $ sudo pacman -S git $ git clone https://aur.archlinux.org/paru.git $ cd paru $ makepkg -si
paruの新バージョンがリリースされた時に自動アップデートできるよう、AURからparu-bin
をインストールし、paru
を上書きする。
$ paru -S paru-bin
systemd-boot更新時にbootctl updateを自動実行する
systemd-bootが更新された場合、EFIブートマネージャを更新できる。
更新のためには bootctl update
を実行する必要がある。
作業を自動化するためにAURよりpacmanのhookをインストールする。
$ paru -S systemd-boot-pacman-hook
NTPの有効化
timedatectlで有効化する
$ sudo timedatectl set-ntp true $ timedatectl Local time: Sat 2022-07-30 19:13:32 JST Universal time: Sat 2022-07-30 10:13:32 UTC RTC time: Sat 2022-07-30 10:13:32 Time zone: Asia/Tokyo (JST, +0900) System clock synchronized: yes NTP service: active RTC in local TZ: no
NTP serviceがactiveになった。
swap の有効化
ひとまず4GBのswapfileを用意する。
スワップ - ArchWikiを参考に設定する。
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 status=progress $ sudo chmod 600 /swapfile $ sudo mkswap -U clear /swapfile Setting up swapspace version 1, size = 4 GiB (4294963200 bytes) no label, UUID=00000000-0000-0000-0000-000000000000 $ sudo swapon /swapfile
自動的にswapfileが有効化されるよう、/etc/fstab
に以下を追加する。
/swapfile none swap defaults 0 0
以降、随時追加予定