initrd (初期ramdisk)は、Linuxシステムでの起動プロセス中にロードされる小さなファイルシステムです。 initrdが担当する可能性のあるタスクの1つは、ネットワーク構成です。
この記事では、起動プロセスの早い段階でネットワーク構成が必要になる場合、その実装方法、およびRed Hat EnterpriseLinux8.3によってもたらされる改善について説明します。
initrdの必要性
マシンの電源ボタンを押すと、ブートプロセスは、ブートローダーをロードするハードウェア依存のメカニズムで開始されます。 。ブートローダーソフトウェアは、ディスク上のカーネルを見つけて起動します。次に、カーネルはルートファイルシステムをマウントし、init
を実行します プロセス。
このプロセスは単純に聞こえますが、一部のLinuxシステムで実際に発生する可能性があります。ただし、最新のLinuxディストリビューションは、この手順では不十分な一連のユースケースをサポートする必要があります。
まず、ルートファイルシステムは、特定のドライバーを必要とするデバイス上にある可能性があります。ファイルシステムをマウントする前に、実行中のカーネルに適切なカーネルモジュールを挿入する必要があります。場合によっては、ルートファイルシステムが暗号化されたパーティション上にあるため、パスフレーズをユーザーに要求してカーネルにフィードするユーザースペースヘルパーが必要です。または、ルートファイルシステムをNFSまたはiSCSIを介してネットワーク経由で共有することもできます。その場合、ルートファイルシステムをマウントするには、最初にネットワークインターフェイスにIPアドレスとルートを構成する必要があります。
[次のこともお勧めします:Linuxネットワーク:netstatの13回の使用]
これらの問題を克服するために、ブートローダーは、実際のルートファイルシステムを見つけてマウントするためのスクリプトとツールを含む小さなファイルシステムイメージ(initrd)をカーネルに渡すことができます。これが完了すると、initrdは実際のルートに切り替わり、通常どおり起動が続行されます。
ドラカットインフラストラクチャ
FedoraとRHELでは、initrdは dracutを介して構築されます。 。ホームページから、dracutは「イベント駆動型initramfsインフラストラクチャです。dracut(ツール)は、インストールされたシステムからツールとファイルをコピーし、通常/usr/lib/dracut/modules.d
。"
用語に関する注意: initrdという名前の場合があります およびinitramfs 互換的に使用されます。実際には、イメージを構築するさまざまな方法を指します。 initrdは、カーネルによってマウントされる実際のファイルシステム(たとえば、ext2)を含むイメージです。 initramfsは、tmpfsとして解凍されるディレクトリツリーを含むcpioアーカイブです。現在、initrdイメージは廃止され、initramfsスキームが採用されています。ただし、initrd名は、一時ファイルシステムを含むブートプロセスを示すために引き続き使用されます。
カーネルコマンドライン
前に述べたNFSルートシナリオをもう一度見てみましょう。 NFS経由で起動する1つの可能な方法は、root=dhcp
を含むカーネルコマンドラインを使用することです。 引数。
カーネルコマンドラインは、ブートローダーからカーネルに渡されるオプションのリストであり、カーネルとアプリケーションにアクセスできます。 GRUBを使用している場合は、 eを押すことで変更できます。 ブートエントリをキー入力し、 linuxで始まる行を編集します 。
initramfs内のdracutコードは、カーネルコマンドラインを解析し、コマンドラインにroot=dhcp
が含まれている場合、すべてのインターフェイスでDHCPを開始します。 。 DHCPリースを取得した後、dracutは受信したパラメーター(IPアドレスとルート)を使用してインターフェースを構成します。また、リースからルートパスDHCPオプションの値を抽出します。このオプションは、NFSサーバーのアドレスとパス(たとえば、192.168.50.1:/nfs/client
など)を伝達します。 )。次に、Dracutはこの場所にNFS共有をマウントし、ブートを続行します。
アドレスとNFSルートパスを提供するDHCPサーバーがない場合は、コマンドラインで値を明示的に構成できます。
root=nfs:192.168.50.1:/nfs/client ip=192.168.50.101:::24::ens2:none
ここで、最初の引数はNFSサーバーのアドレスを指定し、2番目の引数は ens2を構成します 静的IPアドレスとのインターフェース。
インターフェイスのネットワーク構成を指定する構文は2つあります。
ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]]
ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}[:[<mtu>][:<macaddr>]]
1つ目は自動構成(DHCPまたはIPv6 SLAAC)に使用でき、2つ目は静的構成または自動と静的の組み合わせに使用できます。ここにいくつかの例があります:
ip=enp1s0:dhcp
ip=192.168.10.30::192.168.10.1:24::enp1s0:none
ip=[2001:0db8::02]::[2001:0db8::01]:64::enp1s0:none
ip=
を渡す場合は注意してください オプションですが、dracutはルートファイルシステムをマウントするためにネットワークを必要としません。このオプションは無視されます。ネットワークルートなしでネットワーク構成を強制するには、rd.neednet=1
を追加します コマンドラインに移動します。
自動設定方法の中には、 ibft もあることに気付いたと思いますが、 。 iBFTはiSCSIBootFirmware Tableの略で、iSCSIデバイスに関するパラメーターをファームウェアからオペレーティングシステムに渡すメカニズムです。 iSCSI(Internet Small Computer Systems Interface)は、ネットワークストレージデバイスにアクセスするためのプロトコルです。 iBFTとiSCSIの説明は、この記事の範囲外です。重要なのは、ip=ibft
を渡すことです。 カーネルに対して、ネットワーク構成はファームウェアから取得されます。
Dracutは、カスタムルートの追加、マシン名とDNSサーバーの指定、ボンド、ブリッジ、VLANの作成などもサポートしています。詳細については、dracut.cmdlineのマニュアルページを参照してください。
ネットワークモジュール
initramfsに含まれているdracutフレームワークは、モジュラーアーキテクチャーを備えています。これは一連のモジュールで構成され、各モジュールには特定の機能を提供するためのスクリプトとバイナリが含まれています。コマンドdracut --list-modules
を使用して、initramfsに含めることができるモジュールを確認できます。 。
現在、ネットワークを構成するモジュールは2つあります。network-legacy
およびnetwork-manager
。なぜ異なるモジュールが同じ機能を提供するのか不思議に思うかもしれません。
network-legacy
古いもので、iproute2
などのユーティリティを呼び出すシェルスクリプトを使用します 、dhclient
、およびarping
インターフェイスを構成します。実際のルートに切り替えた後、別のネットワーク構成サービスが実行されます。このサービスは、network-legacy
が何であるかを認識していません 実行するモジュールと各インターフェイスの現在の状態。これにより、ルートスイッチの境界を越えて状態を維持する際に問題が発生する可能性があります。
保持される状態の顕著な例は、DHCPリースです。起動中にインターフェイスのアドレスが変更されると、NFS共有への接続が切断され、起動に失敗します。
シームレスな移行を保証するには、2つの環境間で状態を渡すメカニズムが必要です。ただし、異なる構成モデルを持つサービス間で状態を渡すことは問題になる可能性があります。
network-manager
dracutモジュールは、この状況を改善するために作成されました。モジュールはinitrdでNetworkManagerを実行して、カーネルコマンドラインから生成された接続プロファイルを設定します。完了すると、NetworkManagerはその状態をシリアル化し、後で実際のルートのNetworkManagerインスタンスによって読み取られます。
Fedora 31は、network-manager
に切り替えた最初のディストリビューションでした。 デフォルトではinitrdにあります。 RHEL 8.2では、network-legacy
は引き続きデフォルトですが、network-manager
利用可能です。 RHEL 8.3では、dracutはnetwork-manager
を使用します デフォルトで。
別のネットワークモジュールを有効にする
2つのモジュールはほぼ互換性があるはずですが、動作にはいくつかの違いがあります。それらのいくつかは、nm-initrd-generator
に文書化されています マニュアルページ。一般に、network-manager
を使用することをお勧めします NetworkManagerが有効になっている場合のモジュール。
特定のネットワークモジュールを使用してinitrdを再構築するには、次のいずれかのコマンドを使用します。
# dracut --add network-legacy --force --verbose
# dracut --add network-manager --force --verbose
この変更は、次にinitrdが再構築されたときに元に戻されるため、次の方法で変更を永続的にすることができます。
# echo 'add_dracutmodules+=" network-manager "' > /etc/dracut.conf.d/network-module.conf
# dracut --regenerate-all --force --verbose
--regenerate-all
オプションは、システムで見つかったカーネルバージョンのすべてのinitramfsイメージも再構築します。
network-managerdracutモジュール
すべてのdracutモジュールと同様に、network-manager
モジュールは、起動中のさまざまな時間に呼び出されるステージに分割されます(詳細については、dracut.modulesのマニュアルページを参照してください)。
最初の段階では、/usr/libexec/nm-initrd-generator
を呼び出して、カーネルコマンドラインを解析します。 /run/NetworkManager/system-connections
に接続プロファイルのリストを作成します 。モジュールの2番目の部分は、udevが落ち着いた後、つまり、ユーザースペースがシステムで見つかったデバイス(ネットワークインターフェイスを含む)のカーネルイベントの処理を終了した後に実行されます。
NMが実際のルート環境で開始されると、NMはD-Busに登録され、ネットワークを構成し、イベントまたはD-Bus要求に応答するためにアクティブなままになります。 initrdでは、NetworkManagerはconfigure-and-quit=initrd
で実行されます モード。これはD-Busに登録されず(少なくとも現時点ではinitrdで使用できないため)、 startup-completeに達した後に終了します。 イベント。
スタートアップ完了 イベントは、接続プロファイルが一致するすべてのデバイスが正常にアクティブ化を試みたかどうかに関係なくトリガーされます。すべてのインターフェースが構成されると、NMは終了し、dracutフックを呼び出して、ネットワークが使用可能であることを他のモジュールに通知します。
/run/NetworkManager
に注意してください 生成された接続プロファイルとその他のランタイム状態を含むディレクトリが実際のルートにコピーされるため、そこで実行されている新しいNetworkManagerプロセスは正確に何をすべきかを認識します。
トラブルシューティング
dracutでネットワークの問題が発生した場合、このセクションには問題を調査するためのいくつかの提案が含まれています。
最初に行うことは、 rd.debugを追加することです カーネルコマンドラインに移動し、dracutでのデバッグログを有効にします。ログは/run/initramfs/rdsosreport.txt
に保存されます ジャーナルでも入手できます。
システムが起動しない場合は、initrd環境内にシェルを取得して、動作しない理由を手動で確認すると便利です。このために、 rd.breakがあります コマンドライン引数。 initrdがジョブを終了し、実際のルートファイルシステムのinitプロセスを制御しようとしているときに、引数がシェルを生成することに注意してください。ドラカットの別の段階(たとえば、コマンドライン解析後)で停止するには、次の引数を使用します。
rd.break={cmdline|pre-udev|pre-trigger|initqueue|pre-mount|mount|pre-pivot|cleanup}
initrdイメージには、最小限のバイナリセットが含まれています。 dracutシェルで特定のツールが必要な場合は、不足しているものを追加してイメージを再構築できます。たとえば、 pingを追加するには およびtcpdump バイナリ(すべての依存ライブラリを含む)、実行:
# dracut -f --install "ping tcpdump"
次に、オプションで、それらが正常に含まれていることを確認します。
# lsinitrd | grep "ping\|tcpdump"
Arguments: -f --install 'ping tcpdump'
-rwxr-xr-x 1 root root 82960 May 18 10:26 usr/bin/ping
lrwxrwxrwx 1 root root 11 May 29 20:35 usr/sbin/ping -> ../bin/ping
-rwxr-xr-x 1 root root 1065224 May 29 20:35 usr/sbin/tcpdump
ジェネレーター
NetworkManagerの設定に精通している場合は、特定のカーネルコマンドラインがNetworkManager接続プロファイルにどのように変換されるかを知りたい場合があります。これは、マシンを起動しなくても、構成メカニズムをよりよく理解し、コマンドラインで構文エラーを見つけるのに役立ちます。
ジェネレーターは/usr/libexec/nm-initrd-generator
にインストールされます 二重ダッシュの後にカーネル引数のリストを指定して呼び出す必要があります。 --stdout
オプションは、生成された接続を標準出力に出力します。サンプルのコマンドラインを使用してジェネレーターを呼び出してみましょう:
$ /usr/libexec/nm-initrd-generator --stdout -- \
ip=enp1s0:dhcp:00:99:88:77:66:55 rd.peerdns=0
802-3-ethernet.cloned-mac-address: '99:88:77:66:55' is not a valid MAC
address
この例では、 enp1s0 の後にMTUのフィールドがないため、ジェネレーターがエラーを報告します。 。エラーが修正されると、解析は成功し、ツールは生成された接続プロファイルを出力します。
$ /usr/libexec/nm-initrd-generator --stdout -- \
ip=enp1s0:dhcp::00:99:88:77:66:55 rd.peerdns=0
*** Connection 'enp1s0' ***
[connection]
id=enp1s0
uuid=e1fac965-4319-4354-8ed2-39f7f6931966
type=ethernet
interface-name=enp1s0
multi-connect=1
permissions=
[ethernet]
cloned-mac-address=00:99:88:77:66:55
mac-address-blacklist=
[ipv4]
dns-search=
ignore-auto-dns=true
may-fail=false
method=auto
[ipv6]
addr-gen-mode=eui64
dns-search=
ignore-auto-dns=true
method=auto
[proxy]
rd.peerdns =0に注意してください 引数はignore-auto-dns=trueに変換されます プロパティ。これにより、NetworkManagerはDHCP経由で受信したDNSサーバーを無視します。 NetworkManagerのプロパティの説明は、nm-settingsのマニュアルページにあります。
[ネットワークが制御不能になっていますか? Red Hatの無料の本、みんなのためのネットワーク自動化をチェックしてください。 ]
結論
NetworkManager dracutモジュールはFedoraでデフォルトで有効になっており、RHELでもまもなく有効になります。これにより、initrdのネットワークと実際のルートファイルシステムで実行されているNetworkManagerの統合が向上します。
現在の実装はうまく機能していますが、改善の可能性についていくつかのアイデアがあります。 1つは、configure-and-quit=initrd
を放棄することです。 モードを設定し、systemdサービスによって開始されるデーモンとしてNetworkManagerを実行します。このようにして、NetworkManagerは実際のルートで実行される場合と同じ方法で実行され、維持およびテストされるコードが削減されます。
configure-and-quit=initrd
を完全に削除するには モードの場合、NetworkManagerはinitrdのD-Busにも登録できる必要があります。現在、イメージは最小限である必要があるため、dracutにはD-Busデーモンを提供するモジュールがありません。ただし、いくつかの新機能を実装する必要があるため、これを含める提案はすでにあります。
initrdでD-Busを実行すると、NetworkManagerの強力なAPIを他のツールで使用して、ネットワークの状態を照会および変更し、さまざまなアプリケーションのロックを解除できます。それらの1つは、nm-cloud-setup
を実行することです。 initrdで。 NetworkManager-cloud-setup
で出荷されるサービス Fedoraパッケージは、クラウドプロバイダーのインフラストラクチャ(EC2、Azure、GCP)からメタデータをフェッチして、ネットワークを自動的に構成します。