Linux の基礎知識

【Linuxの基礎知識】再起動時に入れ替わるデバイス名「sdX」を固定したい

本業に忙殺され長らく(2年ほど)本ブログの更新をサボってしいました。
その間にも彼此、コメントでの質問がたまっていましたので、少しずつ回答記事を作成していこうかと思っています。かなり急いでコメントされた方もいるみたいですが、誠に恐縮ですが今更の回答になってしまうことをお許しください。

さて、lvm関連での質問で、OSを再起動するたびにデバイスマップ名がコロコロ変更されてしまう件に関して回答いたします。実際に口頭でやり取りしたわけではないので、あくまでも憶測になりますが、テキスト文章から察するに回答としては、「initramfs」ファイルの再作成が必要となります。詳しくは後述します。恐らく、ディスクの容量が足りずに後から外部ストレージ側のLUNを追加されていませんでしょうか?

再起動後にデバイスマップが変わる原因

Linux OSで外部ストレージからLUN(Logical Unit Number)を追加し、再起動後にデバイスマップが変わる原因は、主に以下の要因によるものです。

デバイスマップが変わる原因

過去の経験から、再起動時にデバイス名が入れ替わる代表的な(ケース)原因をいくつか挙げてみます。(どれも実際に筆者が過去にぶち当たった障害です。)

恐らく下記ケースの中にある「ストレージ構成の変更」が原因と思われます。

ケースの具体例

  • カーネル関連の変更
    ・新しいカーネルをインストールした場合

     カーネルをアップデートすると、対応する新しいinitramfsが必要です。
    ・カーネルモジュールの変更
     カーネルモジュール(例: ファイルシステムなど)を追加・削除・更新した。
  • ストレージ構成の変更
    ・ディスクやパーティションの追加・変更

     ブートプロセスに影響するディスク、パーティションを変更した。
    ・マルチパス(multipath)の設定変更
     SAN(ストレージエリアネットワーク)環境でmultipath.confを編集した。
  • ブート構成の変更
    ・「/etc/fstab」の変更
     UUIDやLABELを利用してファイルシステムを指定し直した。

    ・LVM(論理ボリューム管理)の変更
     ルートファイルシステムがLVM上にあるLVMの構成を変更した。

    ・ファイルシステムの変更
     新しいファイルシステム(例: XFS, ZFSなど)をルートパーティションに使用した。
  • 特殊なケース
    ・カーネルパラメータの変更
     ブートローダー(GRUBなど)でカーネルパラメータを変更した。

    ・システムの復旧作業
     initramfsが破損している場合や、システムが正常に起動しない。

通常外部ディスクのLUN領域は、余裕を見てサイズを切り出し、未使用領域は後の拡張分として切り出しておくのが一般的です。ただし、昨今は予算の関係から必要と思われるサイズギリギリでLUNを切り出し、不足分はその都度追加する切り張りプロジェクトが増えている気がします。
上記の理由などからOS起動段階で読み込まれるイメージファイル内のデバイス構成情報と起動後にMODPROBEによって認識されるデバイス構成情報に差が発生しているのではないかと思われます。

LinuxOSがデバイスを認識するプロセス

特に上記の「1. カーネル関連の変更」「カーネルモジュールの変更」にフォーカスします。これは主に外部ディスクの容量が足りずに後から外部ストレージ側のLUN(スライス)を追加した場合によく起こる障害です。(実際これ系の質問が一番届いていました。)

OSが外部デバイスを認識する順序は下記のとおりです。

簡単な流れ

  • 電源を投入する
  • BIOSを起動、デバイス認識・初期化
  • ブートデバイスから(HDD)MBRをロード
  • ブートローダーを起動
  • ブートローダが「カーネル」イメージをロード
    ここで小さなLinuxが起動します。「Linuxのブートストラップで読み込まれるイメージ」後述参照
  • カーネルを起動
  • カーネルが「systemd(旧/sbin/init)」を実行する

外部デバイス認識順序の「ブートローダが「カーネル」イメージをロード」の時、内部ではカーネルがイメージファイルを読み込み、小さなLINUXを展開します。(「initramfs」とは、この時カーネルから読み込まれるイメージファイルの正体です。)

展開された小さなLINUXが起動してカーネルが起動した後、「systemd(旧/sbin/init)」が実行され、正式なLINUXシステムが起動します。狭義の"Linux"とは、このカーネル部分のみを指しています。一連の処理を終えて、いよいよLinuxが立ち上がります。

なぜこのような煩わしい仕組みが採用されているかは、昨今のOSシステムの肥大化に伴い、システム起動までに必要な時間が長くなる傾向にあります。そこで予め小さなLINUXを内部で立ち上げ、システム起動までの時間を短く見せかける必要があるためです。

正式なLINUXが起動後、「MODPROBE」モジュールが実行され始めて最新のデバイス情報が認識されます。「initramfs:イメージファイル」の中身は、初期構築時に作成され自動で更新することはありません。その後、新たなデバイスの追加が発生した場合は「initramfs」を最新の情報を反映させるため再作成する必要があるのです。

Linuxのブートストラップで読み込まれるイメージ

initramfsは、Linuxシステムが起動する際に非常に重要な役割を果たし、カーネルがハードウェアを認識し、必要なドライバやツールを提供するために使用されます。ブートプロセスの初期段階でシステムが正しく動作するために欠かせない部分です。

  1. カーネル起動

    Linuxカーネルがシステムのブートプロセスを開始します。

  2. initramfs実行

    小さなLinux環境がカーネルによって立ち上がります。この環境は、構築時の必要なドライバやツール情報を含んでおり、各種デバイスとの接続を行います。

  3. ドライバ提供

    initramfsは、ハードウェアデバイスを操作するためのドライバを提供します。これにより、システムは周辺機器と通信できるようになります。

  4. ファイルシステムの準備

    必要なファイルシステムがマウントされ、システムが正常に動作するための準備が整います。

  5. システム初期化

    システムの初期化が行われ、必要なサービスやプロセスが起動されます。

  6. ルートファイルシステム切り替え(正規Linux)

    最後に、initramfsから正規のLinuxルートファイルシステムに切り替えられ、完全なLinux環境が立ち上がります。

initramfsとは

initramfsはLinuxシステムの起動において不可欠な役割を果たしており、ハードウェアとの接続やファイルシステムの準備を行うことで、スムーズなブートプロセスを実現しています。

1. initramfsとは何か?

  • 初期RAMファイルシステムinitramfs)は、Linuxカーネルが起動する際に、システムが必要とする初期的なドライバやツールを含む、一時的なファイルシステムです。通常、initramfsは圧縮されたアーカイブ形式(例:initramfs.img)として提供され、システムメモリ(RAM)に展開されます。

2. 役割と目的

  • カーネルのサポート: initramfsは、カーネルがディスクを正しく認識するために必要なドライバを提供します。これにより、カーネルがブート時にハードウェアやファイルシステムにアクセスできるようになります。
  • ファイルシステムの準備:
    ルートファイルシステム(通常はHDDやSSDにある)をマウントするための準備をします。これが完了すると、initramfsは通常のファイルシステムに切り替わります。
  • システムの初期化:
    initramfsは、カーネルが起動する前に必要なツール(たとえば、ディスクのマウント、LVMやRAIDの設定など)を実行します。

3. initramfsが使用される場面

  • 新しいハードウェアのサポート:
    特定のハードウェアを認識するためのドライバを提供する。
  • 暗号化されたディスク:
    例えば、LUKS(Linux Unified Key Setup)で暗号化されたディスクを復号化する際に使用されます。
  • 特殊なストレージ構成:
    RAIDやLVM、ネットワークブートなど、複雑なストレージ設定を行う際にも使用されます。

4. 起動プロセスとの関係

  1. カーネル起動:
    カーネルがロードされ、initramfsがメモリに展開されます。
  2. 2.initramfsの実行:
    必要なドライバや設定を実行し、最終的にルートファイルシステムをマウントします。
  3. 3.ルートファイルシステムへの切り替え:
    initramfsが終了し、実際のルートファイルシステムが使用されるようになります。

5. initramfsとinitrdの違い

  • initramfsinitrd(Initial RAM Disk)は似たような役割を持ちますが、initramfsはより新しい技術で、initrdよりも柔軟で効率的に動作します。

initramfsの再作成手順

initramfsの再作成は、ストレージデバイス関連の初期化プロセスに関わる重要な変更を適用するために必要な場合があります。設定後に予期しない動作を防ぐため、変更内容を正確に理解し、適切に再作成するようにしてください。

step
1
現在のinitramfsの確認

現在の「initramfs」を確認します。「initramfs」は「/boot/」は以下に作成されています。

ls -l /boot/initramfs-$(uname -r).img

cp -ip initramfs-$(uname -r).img initramfs-$(uname -r).img_$(date +%Y%m%d)

思わぬ事故を防ぐために必要に応じてバックアップを取得してから実行してください。
 「initramfs」の上書き再作成は怒られてしまうため、一旦現在の「initramfs」ファイルを削除してから再作成コマンドを実行します。

step
2
再作成コマンドの実行

Linuxでは、各カーネルバージョンに対応したinitramfsイメージが/bootディレクトリに保存されています。

末尾に$(uname -r)が付いている理由は、現在使用しているカーネルバージョンを動的に取得し、適切なバージョンに対応するinitramfsを再作成するためです。

  • RHEL/CentOS系

dracut -f /boot/initramfs-$(uname -r).img $(uname -r)

特に問題がなければ、イメージファイルの作成ご、プロンプトが帰ってきます。
すでに同じカーネルバージョンが存在する状態でオーバーライド(上書き)しようとすると怒られます。

  • Debian/Ubuntu系

update-initramfs -u -k $(uname -r)

step
3
変更を確認

コマンド実行後、作成された「initramfs」のカーネルがマシンのカーネルと一致していることを確認します。

ls -l /boot/initramfs-$(uname -r).img

step
4
再起動

カーネルの更新が必要なため、必ずOSの再起動を行なう必要があります。

reboot

実行する場合は、必ずバックアップファイルを作成してからコマンドを実行してください。

ココに注意

  • dracutupdate-initramfsでエラーが発生した場合、設定ファイル(例:/etc/fstab, multipath.conf, udevルール)を再確認してください。
  • /etc/fstabに誤った設定がある場合、ブートプロセスが停止する可能性があるため、特に注意が必要です。

initramfsの中身について

lsinitrdコマンドを実行すると、kernelディレクトリ内のファイル一覧が表示されます。Dracutツールを使って作成されたinitrd(またはinitramfs)の場合、次にモジュールが表示され、その後でinitrdに含まれているファイルがリストされます。もしモジュールの後に表示されるファイル名が不要な場合、「-m」(または--mod)オプションを指定することで、それを省略できます。

initramfsに組み込まれたモジュール一覧を表示

例えば外部ストレージからLUNを「Multipath」モジュールを使ってOSへ接続している場合、上記の「dracut modules:」一覧配下に「Multipath」が出力表示されます。

initramfsにあるファイルの内容を表示

上記はイメージファイル中の「/etc/conf.d/systemd.conf」を覗いています。

念押しでもう一度伝えます。
LinuxOSを起動する際に外部デバイス認識順序の「ブートローダが「カーネル」イメージをロード」をロードします。内部ではカーネルがイメージファイルを読み込み、小さなLINUXを展開します。(「initramfs」とは、この時カーネルから読み込まれるイメージファイルの正体です。)展開された小さなLINUXが起動してカーネルが起動した後、「systemd(旧/sbin/init)」が実行され、正式なLINUXシステムが起動します。

上記の例は、最初に展開される小さなLinuxの中身です。ここで言う小さなLinuxと、この後、起動される正式なLINUXシステムのデバイス情報間の誤差が原因でデバイス名が変わってしまうのです。

よく読まれている記事

1

Shellとは? Shellとは、人間の理解できる言葉を機会へ伝えるプログラムです。 Linux環境でコマンドプロンプト画面を開いているとき、常にShellは起動している状態です。 「Shell」とは ...

2

Linuxは主にサーバー用として利用されるOSです。大規模な基幹システムの開発者、ロボットや家電開発等の組み込み系エンジニア、ネットワーク機器やデータベースに携わるインフラエンジニアは触れることが多い ...

3

プログラミング言語を習得しようと思った時、必ずと言っていいほど候補として挙げられるのが「Java」というプログラミング言語です。 「Java」は、現在日本で最も使われている言語であり、非常に人気のある ...

4

この記事は、Linuxについて勉強している初心者の方向けに「Shellスクリプト」について解説します。最後まで読んで頂けましたら、Shellスクリプトはどのような役割を担っているのか?を理解出来るよう ...

-Linux の基礎知識