最近のデバッグ事例は、Kubernetesにおける微妙だが影響の大きいメモリ問題を浮き彫りにしています。Linuxカーネルのページキャッシュが、アプリケーションの実際のヒープやオフヒープメモリをはるかに超えてコンテナのメモリ使用量を膨らませることがあります。このケースでは、Spring Boot Podが4GB以上のメモリを消費していた一方で、JVMヒープとオフヒープの合計は約1GBでした。調査の結果、active_file(ページキャッシュ)がマウントされたホストディレクトリ(/logs)に保存された3GBのログファイルをキャッシュしていることが判明しました。これは既知の動作です。コンテナがホストディレクトリをマウントすると、カーネルはファイルデータをページキャッシュにキャッシュし、それがコンテナのメモリcgroup制限にカウントされます。修正方法としては、メモリcgroup設定でページキャッシュを制限する、ログにtmpfsマウントを使用する、またはログローテーションと圧縮を構成してキャッシュデータサイズを削減するなどがあります。この事例は、DevOpsおよびSREチームが本番環境でボリュームマウントを使用する際に、アプリケーションメモリだけでなくカーネルレベルのキャッシュも監視する必要があることを示す貴重な教訓です。
Spring Boot Podのメモリ使用量がヒープ+オフヒープ(1GB)を大幅に超え4GB以上になっていた原因は、マウントされたホストディレクトリのログファイルをLinuxカーネルのページキャッシュ(active_file)がキャッシュしていたためです。これはK8s環境でよく見落とされる問題です。