それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Linuxのマルチブートを作りたい。目的と手法

動機と目的

リモートから、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ブートの作成例)

DebianUbuntuの場合はGRUBを使っている。ただし、UbuntuGrubメニューを隠蔽しているので、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ステップを試すことにした。

レベル1 インストーラーによる、デュアルブートの構築

簡単に言えば、CD-ROMでOS別にインストールを行う。2回インストをする方法だ。

レベル2 dd/dump/rsyncデュアルブート作成

インストール済みディスクのOSをddでコピーして grub再構築を試す。

rsync/ddでOS複製してデュアルブートを試す。

レベル3 UEFIGRUBメニューを試す。

EFIパーティションを持ったPCをつくり、EFIからGRUBを起動し、Grubメニューからマルチブートする

レベル4 EFIデュアルブート

EFIパーティションに複数のOSを登録に行き、efibootmgrから起動OSを切り替える。

GRUBメニューでデュアルブートの例

こんな感じに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を選択して起動します。

殆どの場合そのまま起動しますが、WindowsLinuxもOS選択機能があります。Linuxの場合はOS起動前にGRUBを起動して、カーネル起動のオプションを変更します。デュアルブートは古くからGRUBメニューでやるんでした。普段意識しないのですっかり忘れてました。UbuntuではGRUBメニューすら非表示のため存在すら忘れかけていました。

デュアルブート作成の目標地点

既存のOSがインストール済みのPCに、追加でOSをインストールすることを想定しています。

インストール時にブートを書き換えられたら困るのでマニュアルでOSをコピーし、ブート選択を修正する。これが目標です。

登場したコマンド

解説なく、コマンドが登場しまくるので、ここにまとめておきます、

GRUBの再インストール

GRUBをHDDのパーティションに書き込みます。

sudo grub-install 

未指定の場合は起動しているHDDです。

MBR/GPT(MGR互換)へのGRUB再インストール

sudo grub-insall /dev/vda

EFIへのGRUB登録

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 

ディスクを接続してChrootしてGRUB修正

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が一番確実でした。LinuxLinuxのマルチブートをしておくと緊急メンテナンスがリモートで完結するし管理手法で新しいことを覚えなくていい。新しいことに興味がわかない年寄りには便利だ。

始めからDockerや仮想マシンでいいのだろうけど、その仮想マシンが載っかってるOS自体を更新するのがめんどくさかった。AWSなら常に最新のものをサクッと使えるけど、自宅に放置したPCでそれをやってると数年後にOS自体を更新するのがめんどくさかった。デュアルブートで解決できるんじゃないかなと。

関連記事

参考資料