動機と目的
リモートから、ext4 のrepair や lvm のりサイズをやりたい。
デュアルブートにしておいて、いつでもFSCKをかけられるようにしておきたい。
そのため、GRUBメニューで起動するOSを切り替えたい。
いちいち、USB起動のディスクを差し込みに行くのがめんどくさいうえ、物理的に接触が必要で遠隔から操作できないのが不便極まりないのである。
リモートFSCKの実現手法
デュアルブート環境と、シリアルコンソール環境を併用し実現する。HDD内部を、複数のパーティションに分割し、OSを複数入れておく。GRUBは一つインストールする。GRUBメニューから起動OSを選ぶ。GRUB操作はシリアルコンソール経由で行う。シリアルコンソールはRaspiなどを使ってSSH経由でアクセスするようにしておく。
次のような接続を実現する。
作業マシンー<SSH>ー>Raspiー<シリアル>ー>PC(Debian,ubuntu )
このとき、PCをデュアルブートにしてGRUBメニューから切り替えて起動すれば、リモートからfsck や lvresizeのようなルートパーティションを操作するコマンドが使えるはずである。
デュアルブートでなく、緊急メンテナンスのroot を使えばいいかもしれない。resizeだったりパーティション切り直しだったり、リードオンリーだと不自由だった。リモートで完全に自由にサワれる環境が欲しかった。この実現にはデュアルブートが確実ではないかと考えた。そこでまずは、デュアルブートを作ることにした。
HDMIキャプチャでリモートKVMでもいいかとおもったけど維持管理がめんどくさそうだった。
BIOSをリモートから触れるIPMIとかでもいいかもしれないが、通常のPCが対応してるはずもなく。
手元にあるものを組み合わせたらデュアルブートが安上がりっぽい。容量8GBほど確保すればいいだけし。
事前調査
デュアルブートを環境の作成方法を確認する。
linux の ブートは、/boot
に書かれる。/boot
は別パーティションに出来る。別パーティションにすることで、OSに依存を切り離せる。マルチブートが可能になる。
また、EFIがある場合はEFIパーティションを使うとEFIでOS依存をを切り離してマルチブートが可能になる。( EFIブートの作成例)
Debian・Ubuntuの場合はGRUBを使っている。ただし、UbuntuはGrubメニューを隠蔽しているので、Ubuntuでマルチブートをする場合は、GRUBを変更してメニューを表示する必要がある。(設定例)。
ディスクの構成
今回、作成するディスクの構成は次のような感じにする。
takuya@ubuntu:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 20G 0 disk
├─vda1 252:1 0 1M 0 part
├─vda2 252:2 0 998M 0 part
├─vda3 252:3 0 1G 0 part /boot
└─vda4 252:4 0 18G 0 part
├─vg0-u04root 253:0 0 3G 0 lvm /
└─vg0-d05root 253:1 0 3G 0 lvm
ポイントは、/boot
が1つ、/
が2つ。という点である。デュアルブートなので、一つのboot
を複数のOSがシェアする形式にする。
さらに、UEFIをつかった構築についても考えていきたい。
デュアルブートを作成し、組み合わせを考慮し作成手段を、いくつかのレベルに分割して考えることにした。
いかの4ステップを試すことにした。
簡単に言えば、CD-ROMでOS別にインストールを行う。2回インストをする方法だ。
インストール済みディスクのOSをddでコピーして grub再構築を試す。
rsync/ddでOS複製してデュアルブートを試す。
EFIパーティションを持ったPCをつくり、EFIからGRUBを起動し、Grubメニューからマルチブートする
EFIパーティションに複数のOSを登録に行き、efibootmgrから起動OSを切り替える。
こんな感じにGRUBメニューでデュアルブートができることを目指します。
実験環境
実験環境でベアメタルな実PCを使うと時間も手間ももったいないので、KVM/QEMUで仮想マシンを作って実験することにした。
kvm/qemu をそのまま使うと大変なので、libvirtd と virt-manager も用意した。
実際の構築
Linuxのマルチブートの作業ログ一覧
OSブートにはMBR/GPT(MBR互換)とEFIパーティションの2つのブートシーケンスがあります。
MBR時代は、ブートパーティションをHDDに書いていました。grub-installコマンドをするとMBRを書き換えます。
EFIパーティションは、ブートをHDD内部のEFIパーティション(FAT)に書き込みに行き、UEFI側でブートOSを選択して起動します。
殆どの場合そのまま起動しますが、WindowsもLinuxもOS選択機能があります。Linuxの場合はOS起動前にGRUBを起動して、カーネル起動のオプションを変更します。デュアルブートは古くからGRUBメニューでやるんでした。普段意識しないのですっかり忘れてました。UbuntuではGRUBメニューすら非表示のため存在すら忘れかけていました。
既存のOSがインストール済みのPCに、追加でOSをインストールすることを想定しています。
インストール時にブートを書き換えられたら困るのでマニュアルでOSをコピーし、ブート選択を修正する。これが目標です。
登場したコマンド
解説なく、コマンドが登場しまくるので、ここにまとめておきます、
GRUBをHDDのパーティションに書き込みます。
sudo grub-install
未指定の場合は起動しているHDDです。
MBR/GPT(MGR互換)へのGRUB再インストール
sudo grub-insall /dev/vda
sudo grub-install --target=x86_64-efi
virsh でインストール・起動・停止・削除
仮想マシンをインストール・停止・削除する方法を覚えておくと作業が早い。
virsh でUbuntuインストール
virt-install\
--connect=qemu:///system \
--ram 8192 --virt-type kvm --vcpus 8 --name $NAME --os-type linux \
--graphics none \
--disk path=$DISK \
--location /var/lib/libvirt/images/ubuntu-20.04.3-live-server-amd64.iso,kernel=casper/hwe-vmlinuz,initrd=casper/hwe-initrd \
--os-variant ubuntu20.04 \
--extra-args "console=tty0 console=ttyS0,115200n8" \
virt-install で仮想マシンのインストールができます。インストール時にCDーROMを指定しなくてもURL指定でインストールOSを指定できます。
ただし、フルパッケージCDーROMを使うほうが速いです。ローカルコピーで済むのでインストールが速いです。本当に速いです。
ネットワークから取得する場合はプロキシサーバーを挟んでロスを軽減するといいです。
速いネットワークを自宅に引き込んでいたとしても相手先サーバーの混雑があります。ローカル取得のほうがやっぱり速いんで。
停止
virsh shutdown $NAME # シャットダウン命令送信
virsh destroy $NAME # 強制停止
削除
virsh undefine $NAME
virsh undefine $NAME --nvram ## efi のとき
qemu-img でスナップショットを取る
virsh (libvirt)のスナップショットはメモリ管理がメインだと思う。今回のように、ディスク・パーティションをガンガン触るときにvirsh スナップショットは向いてない。
qemeu-img でディスク自体をスナップショットを取った方がいい
qemeu-img でスナップショット一覧
qemu-img snapshot -l name.qcow2
qemeu-img でスナップショットを作成
qemu-img snapshot -c pointA name.qcow2
qemu-img snapshot -c pointB name.qcow2
qemeu-img でスナップショットへ戻す
qemu-img snapshot -a pointA name.qcow2
仮想マシンにディスクを接続・切断
sudo virsh attach-disk path/to/img myVM01 vdX
sudo virsh detach-disk myVM01 vdX
ただし、qcow2を接続するときは次のようにする。
sudo virsh attach-disk \
--domain $NAME \
--source path/to/$DISL\
--driver qemu\
--subdriver qcow2\
--targetbus virtio\
vdb
OSのインストールを少しでも早く
試行錯誤とインストールを少しでも早くするために、キャッシュを使えばいい。ダウンロードしたISOイメージも速いです。とにかくインストールを少しでも早くすると作業能率があがり気軽に試せます。
APT-PROXYを用意しておく
http://172.17.0.1:3142
efibootmgr でEFIを管理する
EFIの起動順番を変える。
sudo efibootmgr -o 0004,0001
EFI起動メニューから指定番号を無効にする
sudo efibootmgr -A -b 0002
EFI起動メニューから指定番号を有効化
sudo efibootmgr -a -b 0002
GRUBミスったり飛ばしたら、慌てずにディスクのマウント状況を確認して、GRUBを再インストール・メニュー再構築しましょう。
chroot 後は仮想マシンのように扱える
sudo su
mount /dev/mapper/vg-root /mnt
cd /mnt
mount -t proc proc proc/
mount -t sysfs sys sys/
mount -o bind /dev dev/
mount -t devpts pts dev/pts/
chroot /mnt
Chrootの環境下でGRUB修正
root@chroot ~ : grub-install /dev/vga
root@chroot ~ : update-grub /dev/vga
sgdisk でディスク構成を作る
OSのインストール時に、インストール画面でディスクのフォーマット・パーティション作成をやっているとキリがないです。
初期化
sudo -E sgdisk -og $vda # 初期化
状態表示
sudo -E sgdisk -p $vda
パーティション作成
sudo -E sgdisk \
-n 1:2048:4095 -c 1:"BIOS Boot" -t 1:ef02 \
-n "2::+1G" -c 2:"GRUB" -t 2:8300 \
-n "3::+1G" -c 3:"swap" -t 3:8200 \
-n 4:0:$(sudo -E sgdisk -E $vda ) -c 4:"LVM" -t 4:8e00 \
$vda;
表示。
sudo -E sgdisk -p $vda
gdisk コマンドで事前作成できるとは言え、Gdiskでディスクを毎回作っているとめんどくさいです、コピペで作業効率を改善します。そのためにsgdiskを活用します。
Linuxのマルチブートの作業ログ一覧
やってみて。
いまどきデュアルブートなんてと思ってました。ESXiあるしProxmoxもある。IPMIもある、Raspberryで自作リモートKVMもできる。とおもってた。
でもやってみたら、枯れた技術のシリアルコンソールとSSHが一番確実でした。LinuxでLinuxのマルチブートをしておくと緊急メンテナンスがリモートで完結するし管理手法で新しいことを覚えなくていい。新しいことに興味がわかない年寄りには便利だ。
始めからDockerや仮想マシンでいいのだろうけど、その仮想マシンが載っかってるOS自体を更新するのがめんどくさかった。AWSなら常に最新のものをサクッと使えるけど、自宅に放置したPCでそれをやってると数年後にOS自体を更新するのがめんどくさかった。デュアルブートで解決できるんじゃないかなと。
関連記事
参考資料