現代のロギングにおけるリソースコスト
多数のLinuxサーバーでログを管理する場合、難しい選択を迫られることがよくあります。信頼性は高いものの、現代的な構造化バイナリデータの扱いに苦労する従来のRsyslogを使い続けるか、あるいはELKスタック(Elasticsearch、Logstash、Kibana)やLokiを導入するかです。これらのツールは強力な分析機能を提供しますが、CPUとメモリを大量に消費することで知られています。
筆者は最近、2GB RAMのVPSインスタンス群を管理している際にこの壁に突き当たりました。課題は単にログを収集することではなく、Javaベースのインデックスエンジンのためにシステムのメモリの30%を犠牲にすることなく収集することでした。Ubuntu 22.04のプロダクションサーバーにおいて、このネイティブなsystemdのアプローチはメモリ使用量を50MB未満に抑えました。 一般的なElasticsearchノードが必要とする2GB以上のメモリと比較すれば、そのメリットは明らかです。
多くの場合、フラストレーションの原因は、ツールと実際のインフラ規模のミスマッチにあります。5台から50台程度のサーバーを管理しているのであれば、本格的なデータウェアハウスは必要ないでしょう。ネットワーク全体で何が起きているかを確認するために、一箇所から journalctl を実行できれば十分なはずです。これこそが、systemd-journal-remote が解決するために設計された問題です。
ロギング手法の比較
なぜ systemd-journal-remote が小規模な環境に適しているのかを理解するために、大手ツールとのデータ処理の違いを見てみましょう。
Rsyslog vs. systemd-journal-remote
Rsyslogは主にテキストベースです。systemd-journaldがRsyslogにログを送信する際、古いsyslog形式に合わせるために豊富なメタデータが削ぎ落とされることがよくあります。その結果、イベントの構造化されたコンテキストが失われてしまいます。対照的に、systemd-journal-remote はログをネイティブのバイナリ形式で転送します。これにより、_PID、_BOOT_ID、_TRANSPORT、およびカスタムアプリケーションのメタデータを含むすべてのフィールドが保持されます。
ELK/Loki vs. systemd-journal-remote
ELKは洗練されたGUIと複雑なクエリ機能を提供します。しかし、そのパワーには「Java税」が伴います。つまり、相応のリソースを備えた専用サーバーが必要になります。systemd-journal-remote は、すでに使い慣れたツールを使用します。ファイルシステムをストレージエンジンとして使用するため、別途データベースを用意する必要はありません。これは、バイナリのジャーナルエントリを地点Aから地点Bへ移動させるシンプルな仕組みです。
強みと制限事項
メリット
- 学習コストが最小限:
journalctlを使えれば、すでに使いこなせているも同然です。 - 高い効率性: C言語で書かれ、initシステムに統合されているため、リソース消費は極めてわずかです。
- 完全なコンテキスト: ソースサーバーのすべてのメタデータが、デバッグ用にそのまま保持されます。
- デフォルトでセキュア: サードパーティ製プラグインなしでHTTPSや相互TLS(mTLS)をサポートしています。
デメリット
- ビジュアルダッシュボードがない: 円グラフなどは表示されません。これはCLIファーストのツールです。
- 基本的なログ保持管理: systemdの設定や手動のcronジョブを使用してディスク容量を管理する必要があります。
- スケールの限界: 数十台のサーバーには最適ですが、数千ノード規模で必要とされるElasticsearchのような水平スケーリング機能はありません。
推奨されるアーキテクチャ
このセットアップでは、1台のサーバーをコレクター(Collector)、他をノード(Node)として指定します。「プッシュ」モデルを採用し、各ノード は systemd-journal-upload サービスを実行して、暗号化された接続を介してコレクターにログを送信します。
コレクターの /var/log/journal/remote に専用のパーティションまたはボリュームをマウントすることをお勧めします。これにより、サービス障害などでノードがログを大量に送り始めた場合でも、ルートファイルシステムがいっぱいになるのを防ぐことができます。
導入ガイド
1. コンポーネントのインストール
コレクターとノードの両方に systemd-journal-remote パッケージが必要です。DebianやUbuntuシステムでは、以下のコマンドでインストールします。
sudo apt update
sudo apt install systemd-journal-remote -y
RHEL、AlmaLinux、Fedoraユーザーの場合:
sudo dnf install systemd-journal-remote
2. コレクターの設定
コレクターが着信接続をリッスンするように設定する必要があります。デフォルトではポート19532を使用します。設定ファイルを開き、ログの保存方法を定義します。
sudo nano /etc/systemd/journal-remote.conf
[Remote] セクションを以下のように設定します:
[Remote]
Seal=false
SplitMode=host
注:SplitMode=host は非常に重要です。これにより、リモートサーバーごとに個別のジャーナルファイルが作成され、ホスト名によるログのフィルタリングが大幅に高速化されます。
次に、ソケットとサービスを有効化します:
# リスナーソケットを有効化
sudo systemctl enable --now systemd-journal-remote.socket
# 管理サービスを開始
sudo systemctl enable --now systemd-journal-remote.service
3. ノードの設定
監視対象のすべてのサーバーで、アップローダーがコレクターのIPアドレスを指すように設定する必要があります。アップロード設定を編集します:
sudo nano /etc/systemd/journal-upload.conf
URLをコレクターのアドレスに合わせて更新します:
[Upload]
URL=http://10.0.0.50:19532
アップローダーを起動してデータの送信を開始します:
sudo systemctl enable --now systemd-journal-upload
4. セキュリティ:TLSによる要塞化
公開ネットワーク上で平文のHTTP経由でログを送信するのは危険です。常にTLS証明書の使用をお勧めします。コレクターの journal-remote.conf を更新し、各キーを指定します:
[Remote]
ServerKeyFile=/etc/ssl/private/journal.key
ServerCertificateFile=/etc/ssl/certs/journal.crt
TrustedCertificateFile=/etc/ssl/certs/ca.crt
各ノードでは、journal-upload.conf のURLを https:// に変更し、対応するクライアント証明書を提供します。
一元管理されたログのクエリ
ここからがこのセットアップの本領発揮です。ログが届き始めると、/var/log/journal/remote/ に保存されます。これらのファイルを展開したり cat したりする必要はありません。ただ journalctl を使うだけです。
特定のリモートホストのログを確認する場合:
journalctl --directory /var/log/journal/remote/ --file remote-host-10.0.0.101.journal
クラスタ全体のすべての着信ログをリアルタイムで監視する場合:
journalctl --directory /var/log/journal/remote/ -f
-o json フラグを使用すれば、ログを jq にパイプで渡すことができます。これにより、ウェブブラウザを開くことなく、特定のエラーを簡単にフィルタリングできます。
終わりに
数百のマイクロサービスを管理している場合は、ELKやLokiを使い続けてください。しかし、パフォーマンスを優先する特定のLinuxサーバー群を運用している場合は、systemd-journal-remote がより賢い選択肢となります。システムリソースを尊重し、既存のsystemdエコシステムを活用できます。このツールのおかげで、筆者の多段階にわたるSSHトラブルシューティングの手順は、たった一つの高速なローカルコマンドに変わりました。

