Linuxのブートプロセスの全貌を解明:電源投入からログインまで

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

恐怖のブラックスクリーン:なぜブートプロセスが重要なのか

黒い画面で点滅するカーソルをじっと見つめ、データが消えてしまったのではないかと不安になった経験は誰にでもあるはずです。電源ボタンを押し、ファンが回り始めたのに、その後に何も起きない。あるいは、<a href="https://itnotes.dev/ja/grub%e3%81%ae%e4%bf%ae%e5%be%a9%ef%bc%9alive-usb%e3%82%92%e4%bd%bf%e7%94%a8%e3%81%97%e3%81%a6linux%e3%82%b7%e3%82%b9%e3%83%86%e3%83%a0%e3%82%92%e5%be%a9%e6%97%a7%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81/">grub rescue></a> という謎のプロンプトがあなたを嘲笑っているかもしれません。私がLinuxサーバーの管理を始めたばかりの頃、こうした瞬間は純粋なパニックでした。まるで中身の見えないブラックボックスを棒で突きながら、奇跡を祈っているような気分でした。

Linuxのブートシーケンスを理解することは、単なる学術的な知識ではありません。それは究極のトラブルシューティングの武器になります。これまでに様々なクライアントのために15以上の本番環境のLinuxインスタンスを管理してきましたが、ブート失敗の90%は、プロセスの「引き継ぎポイント」を知っていれば予測可能なものです。ハードウェアがどの時点でソフトウェアに処理を渡すのかを正確に把握していれば、問題の原因がCMOS電池の寿命なのか、ブートローダーの破損なのか、あるいはsystemdサービスの停止なのかをピンポイントで特定できます。

ブートシーケンスを、失敗の許されないリレー競争と考えてみてください。4人の走者がバトンを完璧に渡さなければなりません。一人が転んだだけでもレースは止まり、システムは起動しなくなります。

リレー競争:4つのステージをマッピングする

ブートプロセスは「インストール」するものではありません。ハードウェアとOSにあらかじめ組み込まれています。しかし、問題が発生した際にナビゲートするためのメンタルマップが必要です。プロセスは厳格な階層に従います。ステージ1が失敗すれば、ステージ2に信号が送られることはありません。

ステージ1:ハードウェアとファームウェア (BIOS/UEFI)

マザーボードに電気が流れた瞬間、ファームウェアが主導権を握ります。2010年以前の古いハードウェアでは、これはBIOSでした。現代のシステムはUEFI(Unified Extensible Firmware Interface)を使用しています。これは実質的に、それ自体が小さなオペレーティングシステムのようなものです。

  • POST (Power-On Self-Test): ファームウェアがクイックインベントリを実行します。32GBのRAMが正しく装着されているか、CPUが反応しているかを確認します。短いビープ音が3回鳴り、画面が暗いままなら、リレーはまだ始まってもいません。
  • 引き継ぎ場所の特定: BIOSはディスクの最先頭にあるわずか512バイトのブートセクタ (MBR) を探していました。UEFIはより洗練されており、EFIシステムパーティション (ESP)(通常はFAT32パーティション)を検索し、/EFI/ubuntu/grubx64.efi のような特定の .efi ファイルを実行します。

ステージ2:ブートローダー (GRUB2)

ファームウェアは賢いですが、Linuxの動かし方までは知りません。ファームウェアが知っているのは、ブートローダーを見つける方法だけです。ほとんどのディストリビューションは GRUB2 を採用しています。その主な役割は、メニューを表示してカーネルをメモリにロードすることです。

メニューが表示されたなら、ファームウェアの処理は成功しています。しかし、grub>grub rescue> プロンプトに放り出された場合は、GRUBが自身のコードは見つけたものの、設定ファイルやカーネルを含むパーティションが見つからないことを意味します。

ステージ3:カーネルとInitramfs

ここからが実際のLinux OSの寿命の始まりです。GRUBは2つの重要なファイルをRAMに読み込みます。カーネル (vmlinuz)Initramfs (Initial RAM Filesystem) です。

カーネルはシステムの心臓部ですが、古典的な「鶏が先か卵が先か」の問題に直面します。ハードドライブ(特にNVMeや暗号化ボリューム)を読み取るにはドライバが必要ですが、そのドライバ自体がそのハードドライブに保存されているからです。Initramfs がこの問題を解決します。これは、カーネルが本物のルートパーティション (/) をマウントするために必要な最小限のドライバを含む、一時的な小さなルートファイルシステムです。本物のディスクがマウントされると、カーネルはそこへ「ピボット」し、一時的なRAMディスクを消去します。

ステージ4:Initシステム (systemd)

本物のルートファイルシステムが稼働すると、カーネルは史上最初のプロセスである PID 1 を開始します。Ubuntu、Debian、RHELなどの現代的なディストリビューションでは、これが systemd です。これはネットワークスタック、SSHサーバー、そして最後にログインプロンプトを起動するグランドオーケストレーターです。

設定:介入する方法

効果的なデバッグには、このリレー競争に介入する方法を知っておく必要があります。GRUBメニューがその主要な介入ポイントです。

その場でGRUBを編集する

起動中にシステムがハングした場合、カーネルパラメータを調整することで問題を回避できることがよくあります。GRUBメニューが表示されたら、e キーを押して編集します。linux で始まる行を探します。

linux /boot/vmlinuz-6.5.0-generic root=UUID=a1b2c3d4... ro quiet splash

何が失敗しているのかを正確に確認するには、quietsplash を削除してください。これにより、綺麗なロゴを表示する代わりに、テキストがスクロール表示されるようになります。システムからロックアウトされた場合、末尾に init=/bin/bash を追加すると、セキュリティサービスやパスワードが読み込まれる前に、直接ルートシェルに入ることができます。

永続的な修正

/boot/grub/grub.cfg を直接編集するのは避けてください。カーネルが更新されるたびに上書きされてしまいます。代わりに /etc/default/grub を編集します。例えば、常に詳細なログを表示させるには、デフォルトの行を以下のように変更します。

# /etc/default/grub を編集
GRUB_CMDLINE_LINUX_DEFAULT="nosplash debug"

# 変更を適用
sudo update-grub # Ubuntu/Debianの場合
sudo grub2-mkconfig -o /boot/grub2/grub.cfg # RHEL/Fedoraの場合

ターゲットの切り替え

systemdは、古いランレベルの代わりに「ターゲット」を使用します。GUIがクラッシュしてログインできない場合、リソースを節約したりドライバを修正したりするために、テキストモードのみで起動を強制することができます。

# コマンドラインのみで起動(RAMを約500MB以上節約)
sudo systemctl set-default multi-user.target

# 標準のデスクトップインターフェースに戻す
sudo systemctl set-default graphical.target

検証:なぜ起動が遅いのか?

ログイン画面に到達できれば勝利ですが、パフォーマンスも重要です。サーバーの起動に3分かかるなら、ボトルネックが存在します。

「犯人」探し

私はデプロイするすべてのサーバーを監査するために systemd-analyze を使用しています。これはカーネル内とユーザー空間で費やされた時間の概要を教えてくれます。

systemd-analyze

起動を遅らせている犯人を特定するには、以下を実行します。

systemd-analyze blame

これにより、開始時間順にサービスがリストされます。以前、設定ミスのNFSマウントがタイムアウトを引き起こし、再起動のたびに正確に90秒追加されていたのを発見したことがあります。<a href="https://itnotes.dev/ja/%e3%83%8d%e3%83%83%e3%83%88%e3%83%af%e3%83%bc%e3%82%af%e5%85%b1%e6%9c%89%e3%81%ab-fstab-%e3%82%92%e4%bd%bf%e3%81%86%e3%81%ae%e3%81%af%e3%82%84%e3%82%81%e3%82%88%e3%81%86%ef%bc%9alinux-%e3%81%ab/">/etc/fstab</a> を素早く修正することで、起動時間を15秒未満に短縮できました。

ログの深掘り

ハードウェアデバイスが表示されない場合は、dmesg が最適です。カーネルの生バッファを表示します。サービスの失敗については、<a href="https://itnotes.dev/ja/%e9%9d%99%e7%9a%84%e3%81%aa%e3%83%86%e3%82%ad%e3%82%b9%e3%83%88%e3%81%aegrep%e3%81%af%e3%82%82%e3%81%86%e3%82%84%e3%82%81%e3%82%88%e3%81%86%ef%bc%9ajournalctl%e3%81%ab%e3%82%88%e3%82%8b%e3%83%a2/">journalctl</a> が標準です。

# 今回のブートセッションのすべてのエラーを表示
journalctl -b -p err

これらのステージをマスターすることで、私のLinuxへの向き合い方は変わりました。推測する代わりに、バトンがどこで落ちたかを探すようになったのです。GRUBメニューが出ない?EFIパーティションを確認しましょう。カーネルパニック?initramfsを再構築しましょう。ログインプロンプトが出ない?systemdユニットを確認しましょう。プロセスを分解して理解すれば、「ブラックボックス」は論理的で解決可能な一連の流れに変わります。

Share: