発端について
私は、大学の研究室にて数台のベアメタルサーバーを利用してKubernetesクラスタを構築しています。
元々、Ubuntuを入れて問題なく使っていましたが、VMを複数台作成したくなったためProxmoxを入れて運用することにしました。
初めは問題なく稼働してくれていましたが、ある日突然、何もしていないのにも関わらずとあるマシンにsshできなくなりました。
マシンに対してpingしようにも、Destination Host Unreachable と言われ疎通ができません。
家からリモートでサーバーに接続していましたが、どうしようもないので研究室に行き直接サーバーの様子をみることにしました。
とりあえず接続不良を疑い、LANケーブルを挿し直したりしました。その結果挿し直した直後は一時的に疎通できるようになったものの、暫く経つとまた同様の問題が発生するようになりました。
そのため、しっかりと調査する事にしました。
使用しているソフトウェア・ハードウェア
ソフトウェア
Proxmox VE 9.1.0
Kernel: 6.17.2-1-pve
ハードウェア
NICチップ: Intel Corporation Ethernet Connection I217-LM [8086:153a]
ドライバ: e1000e
原因の切り分け
とりあえず、L1・L2・L3のどのレイヤで問題が発生しているのかを切り分けるところから始めました。
設定は何も変更していないのでL1またはL2と思い調査を始めました。
以下の結果から、default routeである同一LAN内の 192.168.80.1 に対するL2通信が失敗していることを確認しました。
root@pve:~# ip neigh
192.168.80.1 dev vmbr0 lladdr ac:44:f2:xx:xx:xx FAILED
ハードウェアの故障の可能性がないかを探るため、問題の発生したサーバーでNICの状態を確認してみました。
root@pve:~# ethtool -S nic0
NIC statistics:
rx_crc_errors: 0
rx_packets: 3138030
rx_missed_errors: 289184
rx_crc_errors が0であることからL1の問題ではないだろうと判断し、サーバーの設定に問題があるのではないかと考えました。
また、rx_missed_errors の数が増えていることを確認しました。問題が発生しなかったサーバーではこの値が0であったため、この数が増えていることとサーバーに疎通できなくなったことが関係していると考えました。
rx_missed_errorsは、NICがパケットを受信したが、OSに渡すことができず捨ててしまった回数 であるとのことだったので、LANケーブルやスイッチ等の物理的な問題ではなさそうです。
そして、NICにはパケットが到達しているもののOSに渡すことができていないという事実から、それらの橋渡しを行うNICドライバーに異常が発生しているのではと考えました。
エラーログの確認
上記の流れをもとに、NICドライバーのカーネルログを確認してみました。
root@pve:~# dmesg | grep e1000e
[343968.145158] e1000e 0000:00:19.0 nic0: Detected Hardware Unit Hang:
[343970.129160] e1000e 0000:00:19.0 nic0: Detected Hardware Unit Hang:
[345051.086864] e1000e 0000:00:19.0 nic0: Detected Hardware Unit Hang:
[345053.134924] e1000e 0000:00:19.0 nic0: Detected Hardware Unit Hang:
[345055.118873] e1000e 0000:00:19.0 nic0: Detected Hardware Unit Hang:
[345057.102802] e1000e 0000:00:19.0 nic0: Detected Hardware Unit Hang:
[345059.150874] e1000e 0000:00:19.0 nic0: Detected Hardware Unit Hang:
[345060.669603] e1000e 0000:00:19.0 nic0: NIC Link is Down
[345063.872709] e1000e 0000:00:19.0 nic0: NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx
[345092.446546] e1000e 0000:00:19.0 nic0: NIC Link is Down
[345095.634617] e1000e 0000:00:19.0 nic0: NIC Link is Up 1000 Mbps Full Duplex, Flow Control: Rx/Tx
その結果、Detected Hardware Unit Hang という怪しげなログを確認することができました。
問題の対応
議論されているスレッドの発見
エラーログで検索を行った結果、同じ問題が発生している議論のスレッドを発見しました。同様の問題が発生しているユーザが多くいることがわかり安心しました。
スレッドを読むとどうやらIntel製NIC(e1000e)とProxmoxの相性が悪いようで、サーバーの設定をいくつか変更すると状況が改善したと報告するユーザがいたため、私も同様の対応を行う事にしました。
ethtool -K eth0 tx off rx off
Disabling TCP checksum offloading worked for me
対応
結果として、NICのオフロード機能 (GRO/GSO/チェックサムオフロード) の無効化を行いました。
従来はデータの分割処理をNIC側にオフロードすることでCPU負荷を抑えることができるためデフォルトで有効化されているようですが、このせいで通信が不安定になっていたため、無効化しパケットの分割処理をOS側に委譲するようにしました。
ethtool -K nic0 gro off gso off tx off rx off
/etc/network/interfaces を編集し、再起動時に消えないように設定の永続化を行いました。
auto nic0
iface nic0 inet manual
post-up ethtool -K nic0 gro off gso off tx off rx off
この設定を反映した結果、暫く疎通の不具合は発生していないので、とりあえず問題は解消したものと考えています。
まとめ・感想
かなり厄介なエラーでしたが、原因の切り分けを行っていき当たりをつけていく作業は意外と面白いと感じる場面もありました。
原因を見つけるのが厄介な問題かつ多くの人が遭遇する事象かと思われるので、本記事がどなたかの参考になると幸いです。