GNU/Linux >> Linux の 問題 >  >> Linux

初期ramdisk(initrd)でのLinuxネットワーク構成を楽しみにしています

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)からメタデータをフェッチして、ネットワークを自動的に構成します。


Linux
  1. Linuxカーネルの継続的インテグレーションテスト

  2. ネームゲーム:Linuxでのネットワークインターフェイスの命名

  3. Linux – Linuxネットワークの名前空間間でトラフィックを転送する方法は?

  1. Linuxカーネルをftraceで分析する

  2. Linuxカーネル:イノベーショントップ5

  3. Linux カーネル タイマーの変更

  1. Linuxカーネルテストのライフサイクル

  2. Linuxmtrコマンドの使用方法

  3. Linux –カーネルメーリングリストに参加していますか?