RHEL 互換ディストリビューションを使用しており、オンボードの Realtek NIC がカーネル内の r8169 ドライバでうまく動作しない場合(リンクの切断、異常なスループット、不安定な自動ネゴシエーションなど)、Realtek のツリー外の r8168 ドライバに切り替えることで、実用的な解決策となる可能性があります。
この投稿では、クリーンで再現性のある方法について説明します。r8168 を DKMS 経由でインストールすることで、カーネルが更新されるたびに自動的に再構築されるようにします。
前提: Realtek の公式ダウンロードページから r8168 Linux ドライバの tarball をダウンロードします。 https://www.realtek.com/Download/List?cate_id=584
DKMS を使用する理由
RHEL 互換ディストリビューションでは、カーネルの更新は通常であり、頻繁に行われる運用イベントです。DKMS を使用せずにツリー外のドライバをインストールした場合、カーネルの更新後、手動で再構築/再インストールする必要があることがよくあります。
DKMS は、起動するカーネルに合わせてドライバモジュールをローカルで再構築することで、この問題を解決し、モジュールをカーネルのライフサイクル変更に合わせて維持します。
始める前に(重要な運用上の注意点)
NIC ドライバを切り替えると、一時的にネットワークが切断される可能性があります。
リモートサーバーで SSH を使用して作業している場合は、アウトオブバンドコンソールアクセス(IPMI/iDRAC/iLO/KVM)があるか、少なくとも代替手段を用意しておく必要があります。メンテナンスの時間を計画してください。
ステップ 0: NIC と現在のドライバを特定する
まず、NIC が存在し、r8169 が現在使用されていることを確認します。
uname -r
lspci -nnk | grep -A3 -i ethernet
Kernel driver in use: r8169 と表示された場合は、この変更を行うのに適しています。
ステップ 1: EPEL を有効にし、カーネルビルドリポジトリが利用可能であることを確認する
通常、次のものが必要です。
- EPEL(
dkms用) - 実行中のカーネルに対応する カーネルヘッダー/devel を提供するパッケージへのアクセス
EPEL と必要な基本リポジトリを有効にします。
sudo dnf install -y dnf-plugins-core
# EPEL の前提条件は、RHEL の主要バージョンによってわずかに異なります。
RHEL_MAJOR="$(rpm -E %rhel)"
if [ "$RHEL_MAJOR" -eq 9 ]; then
sudo dnf config-manager --set-enabled crb
elif [ "$RHEL_MAJOR" -eq 8 ]; then
sudo dnf config-manager --set-enabled powertools
fi
# EPEL
sudo dnf install -y epel-release
注: カーネルヘッダー/devel の取得方法は、使用しているカーネルストリーム(ベンダーカーネル、代替カーネルリポジトリなど)によって異なります。重要な要件は、ヘッダー/devel は起動するカーネルと一致している必要があるということです。
ステップ 2: ビルドツール、DKMS、および一致するカーネルヘッダー/devel をインストールする
DKMS には、動作するツールチェーンと、実行中のカーネルに対応するカーネルビルド環境が必要です。
sudo dnf install -y gcc make elfutils-libelf-devel tar bzip2
sudo dnf install -y dkms
次に、実行中のカーネルと一致するカーネルヘッダー/devel をインストールします。
sudo dnf install -y "kernel-devel-$(uname -r)" "kernel-headers-$(uname -r)" || \
sudo dnf install -y kernel-devel kernel-headers
簡単な整合性チェック
最近新しいカーネルをインストールしたが、再起動していない場合、uname -r には古いカーネルが表示されることがあります。その場合は、次の手順を実行します。
- 目的のカーネルに再起動する
uname -rを再実行するkernel-develがそのバージョンと一致することを確認する
これにより、一般的な DKMS エラー「カーネルヘッダーが見つからない」を回避できます。
ステップ 3: Realtek から r8168 をダウンロードして抽出する
Realtek のページから、r8168 Linux ドライバの tarball をダウンロードします。ファイル名は通常、次のようになります。
r8168-8.xx.xx.tar.bz2(バージョンは異なる)
ダウンロードディレクトリから:
ls -1 r8168-*.tar.bz2
tar -xvf r8168-*.tar.bz2
ls -1 | grep -E '^r8168-[0-9]+\.[0-9]+\.[0-9]+$'
抽出されたディレクトリ名とバージョンをキャプチャします。
R8168_DIR="$(ls -d r8168-* | head -n 1)"
R8168_VER="${R8168_DIR#r8168-}"
echo "使用するバージョン: ${R8168_VER}"
ステップ 4: ソースを /usr/src に配置する(DKMS に適したレイアウト)
DKMS は、/usr/src/<name>-<version> の下のモジュールソースを想定しています。
sudo rm -rf "/usr/src/r8168-${R8168_VER}"
sudo cp -a "${R8168_DIR}" "/usr/src/r8168-${R8168_VER}"
ステップ 5: dkms.conf を作成する
次の場所に DKMS 構成ファイルを作成します。
/usr/src/r8168-<version>/dkms.conf
この例では、Realtek tarball が src/ ディレクトリからモジュールをビルドすると想定しています。
sudo tee "/usr/src/r8168-${R8168_VER}/dkms.conf" >/dev/null <<EOF
PACKAGE_NAME="r8168"
PACKAGE_VERSION="${R8168_VER}"
BUILT_MODULE_NAME[0]="r8168"
BUILT_MODULE_LOCATION[0]="src/"
DEST_MODULE_LOCATION[0]="/kernel/drivers/net/ethernet/realtek"
AUTOINSTALL="yes"
MAKE[0]="make -C src KERNELDIR=/lib/modules/\${kernelver}/build modules"
EOF
Realtek パッケージで異なる Makefile インターフェイスを使用している場合は、MAKE[0] を調整します。ヒントは Makefile 自体の中にあります。
sed -n '1,120p' "/usr/src/r8168-${R8168_VER}/src/Makefile"
ステップ 6: DKMS モジュールを登録、ビルド、およびインストールする
次に、モジュールを DKMS に追加し、現在のカーネル用にビルドしてインストールします。
KVER="$(uname -r)"
sudo dkms add -m r8168 -v "${R8168_VER}"
sudo dkms build -m r8168 -v "${R8168_VER}" -k "${KVER}"
sudo dkms install -m r8168 -v "${R8168_VER}" -k "${KVER}"
dkms status
ビルドが失敗した場合
DKMS ログは通常、非常に明確です。make.log を確認します。
sudo find "/var/lib/dkms/r8168/${R8168_VER}" -name make.log -print -exec tail -n 120 {} \;
ほとんどの失敗は、次のような原因によるものです。
kernel-devel/kernel-headersがないkernel-develがuname -rと一致しないdkms.confと Makefile が一致しない
ステップ 7: r8169 をブラックリストに登録して競合を回避する
r8168 と r8169 は、同じハードウェアをめぐって競合する可能性があります。標準的なアプローチは、r8169 をブラックリストに登録することです。
echo 'blacklist r8169' | sudo tee /etc/modprobe.d/blacklist-r8169.conf
initramfs を再構築します(ブラックリストが起動の早い段階で尊重されるように推奨されます)。
sudo dracut -f "/boot/initramfs-$(uname -r).img" "$(uname -r)"
再起動します。
sudo reboot
ステップ 8: 再起動後の検証
システムが起動したら:
lsmod | egrep 'r8168|r8169'
lspci -nnk | grep -A3 -i ethernet
ethtool -i <YOUR_INTERFACE_NAME>
次のことを確認する必要があります。
r8168がロードされているr8169がロードされていないethtool -iにdriver: r8168と表示される
ステップ 9: カーネルの更新による安定性の維持
AUTOINSTALL="yes" を設定したため、DKMS は、一致する kernel-devel が存在する場合、新しいカーネルをインストールしたときにモジュールを自動的に再構築するように設計されています。
必要に応じて、特定のカーネルバージョンに対して手動で強制的に再構築できます。
sudo dkms autoinstall -k <new-kernel-version>
共通の落とし穴とトラブルシューティングのヒント
ヘッダー/devel の不一致
「カーネルヘッダーが見つからない」や build/ ディレクトリがないなどのエラーが表示された場合は、次のことを確認してください。
uname -rがインストールされているkernel-develパッケージのバージョンと一致している
セキュアブート
セキュアブートが有効になっている場合、署名されていないサードパーティのモジュールはロードに失敗する可能性があります。一般的な解決策は次のとおりです。
- セキュアブートを無効にするか、
- モジュールに署名し、キー(MOK)を登録する
誤ったドライバパッケージ
Realtek は、いくつかの類似のドライバ(r8125、r8126 など)を提供しています。r8168 ドライバを正しいカテゴリページからダウンロードしていることを確認してください。
結論
DKMS は、RHEL 互換ディストリビューションで Realtek の r8168 ドライバを実行するための最もクリーンな方法です。カーネルの更新ごとに手動で再構築する必要なく、ドライバをカーネルの更新に合わせて維持します。