Arch Linux on Distrod on WSL2にいろいろと限界を感じ始めたので、Hyper-V 上にArch Linux 環境を作ることにしました。
手順をメモします。
Hyper-V とかLinux とかよく分かっていないので、雰囲気でやっていきます。
Hyper-V - ArchWiki の手順に従いながら進めていく。
仮想ネットワークの設定
今回は内部スイッチを利用する。
Windows 10 Fall Creators Update (バージョン 1803) 以降では、仮想マシン に NAT スイッチ (Default Switch) が組み込まれており、特段の設定なしでインターネットに接続できます。
とのことなので、特別な設定は不要のようだ。
Hyper-V マネージャー
まず、Hyper-V マネージャーの右サイドバーの「新規」→「仮想マシン 」を選択。
出てきたダイアログに値を入力しながら進めていく。
名前と場所の指定
名前と場所は適当に指定する。
今回は名前を "thyme"、場所を D ドライブ配下にした。
世代の指定
UEFI ベースのファームウェア を使うため、「第2世代」を選択。
メモリの割り当て
起動メモリはひとまず1024MBを指定。
「動的メモリ」を有効にして、必要に応じて追加のメモリが割り当てられるようにする (便利!)。
ネットワークの構成
前述の通り内部スイッチを利用するため「Default Switch」を選択。
仮想ハードディスクの接続
仮想ハードディスクを新たに作成して接続します。
ディスクは容量可変で後からサイズ変更可能なため、容量はデフォルトの127GBのままとした。
インストールオプション
Arch Linux JP Project - ダウンロード よりダウンロードしたISOイメージを指定。
仮想マシン の新規作成ウィザードの完了
最後に内容を確認して、「完了」を押すと、仮想マシン が作成され仮想マシン マネージャーの画面に戻る。
続けて、仮想マシン を設定していく。
Hyper-V マネージャー
仮想マシン マネージャーで作成した仮想マシン を選択すると右サイドバーに表示される「設定」をクリックする。
仮想マシン 設定 → ハードウェア → セキュリティ
「ハードウェア」→「セキュリティ」を選択する。
Arch Wiki の注意書きに従い、セキュアブートを無効化する。
仮想マシン 設定 → ハードウェア → メモリ
「ハードウェア」→「メモリ」を選択する。
動的メモリの最大割り当て量 (最大RAM) が1048576MB (1TB!) というとんでもない値になっている。
仮想マシン が暴走した場合などに問題が起きるかもしれないため、マシンの搭載メモリ量の50%ほどを指定しておく。
今回は32768(32GB)を指定した。
※後ほどrustupでRustをインストールしようとしたところメモリ不足で失敗すたため、RAMと最小RAMを2048MBに変更した。
仮想マシン 設定 → ハードウェア → プロセッサ
「ハードウェア」→「プロセッサ」を選択する。
「仮想プロセッサの数」が1になっているので、適切な値に設定する。
仮想マシン で重い処理をする場合、搭載されているプロセッサコアの半分を割り当てると良いでしょう。
とのこと。ここで言うプロセッサコア数は論理プロセッサ数のことだと思われるが、今回はホストマシンの物理プロセッサ数の半分の8を設定した。
仮想マシン 設定 → 管理 → チェックポイント
「自動チェックポイントを使用する」はオフにした。
その他の設定はデフォルトのままにした。
VM の運用方法に合わせて「自動開始アクション」や「自動停止アクション」の設定をすると良いだろう。
設定完了したら、「OK」をクリックする。
仮想マシン マネージャーの右サイドバーの「接続」をクリックして、仮想マシン 接続を表示する。
仮想マシン 接続
「起動」を押すと仮想マシン が起動される。
GNU GRUB
少し待つとGRUB の画面が表示される。
"Arch Linux install medium (x86 _64, UEFI )" を選択し、先に進む。
何もキーを押さずに放置していれば、自動で選択されるようだ。
archisoコンソール
少し待つとコンソールが表示される。
インターネット接続できるか、以下コマンドで確認する。
# ping archlinux.org
Arch Linux のインストールの準備
インストールガイド - ArchWiki に従って作業を進める。
コンソールのキーボードレイアウトの設定
US配列のキーボードを利用しているため、省略。
起動モードの確認
UEFI モードで起動しているか確認する。
以下コマンドでディレクト リの内容が表示されれば、UEFI で起動していると確認できるそうだ。
# ls /sys/firmware/efi/efivars
インターネットへの接続
以下コマンドでネットワークインタフェースが認識・有効化されていることを確認する。
# ip link
ip link の結果
認識されているようだ。
システムクロックの更新
NTPを有効化してシステムクロックを正しくする。
# timedatectl set-ntp true
# timedatectl status
timedatectl の結果
正しい時刻になっていればOK。
ディスクに割り当てられたブロックデバイス を確認する。
# fdisk -l
fdisk -l の結果
/dev/sda が割り当てられたようだ。
このデバイス 上にパーティション を作成する。
今回はルートディレクト リのパーティション と、UEFI で起動するためのEFI システムパーティション の2つを作成する。
UEFI を使うのでパーティション テーブルはGPTを使用する。
まずgdiskコマンドを起動する。
# gdisk /dev/sda
gdisk 起動時の画面
gdisk を起動するとパーティション テーブルのスキャン結果の後にプロンプトが表示され、コマンド入力を求められる。
gdisk コマンド一覧
? を入力すると、利用可能なコマンドの一覧が表示される。
まず、EFI システムパーティション を設定する。
EFI システムパーティション の設定
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
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
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 マネージャー
まず、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
以降、随時追加予定