CentOS Stream 9 における Rsyslog での集中ログ管理:ログを一元化して運用を「楽」にする

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

数十ものログファイルから「針を探す」ような絶望感

インフラエンジニアや運用担当の皆さんなら、システムが正常に動いていたのに突然「ダウンした」という経験が必ずあるはずです。最も厄介なのは、その原因が分からないことです。そんな時、まず最初に行うのは原因特定のためにログを漁ることでしょう。

管理しているサーバーが1〜2台であれば、各サーバーにSSHでログインして tail -f /var/log/messages を実行するだけで数分で済みます。しかし、マイクロサービスが稼働する数十、数百台の仮想マシンがある場合を想像してみてください。この手作業はまさに悪夢です。ターミナルウィンドウを行ったり来たりするだけで、何時間も費やすことになります。

以前、午前2時にWebサーバー群で502エラーが多発した時のことを覚えています。眠い目をこすりながら5つのターミナルタブを開き、どのサーバーがアップストリームエラーを出しているか1台ずつ確認しました。あの時のストレスは相当なものでした。さらに悪いことに、サーバーがハードウェア故障で突然停止した場合、証拠となるログもサーバーと共に消えてしまいます。その時、私は「集中ログ管理(Centralized Logging)はオプションではなく、必須だ」と痛感しました。

なぜログは分散し、管理が難しくなるのか?

デフォルトでは、CentOS Stream 9などのLinuxディストリビューションはログをローカルストレージに保存します。SSH、メール、カーネルなどのあらゆるサービスは、/var/log/ 内の個別のファイルに書き込まれます。この手法には3つの致命的な弱点があります。

  • データがバラバラ: システム全体の「全体像」を把握するために、5〜10箇所の異なるソースから情報を繋ぎ合わせる必要があります。
  • セキュリティリスク: ハッカーがルート権限を奪取した場合、証跡を消すためにログファイルを削除することがよくあります。ログがローカルにしかない場合、調査能力を完全に失うことになります。
  • システム停止の危険: ログが大量に出力されると、/var パーティションが一杯になる可能性があります。これにより、ストレージ空き容量がなくなり、他のサービスが停止してしまいます。

一般的なソリューションの紹介

現在、この問題を解決するための強力なツールが数多く存在します:

  1. ELK Stack (Elasticsearch, Logstash, Kibana): 検索能力とグラフ表示においてトップクラスです。しかし、ELKは非常にリソースを消費します。基本的なELKクラスターを起動するだけで、最低でも4〜8GBのRAMが必要です。
  2. Graylog: ELKよりも管理しやすいですが、安定稼働には依然として強力なインフラが必要です。
  3. Loki + Grafana: 非常に軽量で、Docker/Kubernetes環境に適していますが、新しいクエリ言語であるLogQLを学習する必要があります。

Rsyslog:軽量・安定・標準搭載の「間違いない」選択肢

中規模のシステムや、安定性と軽量さを優先する場合、Rsyslog こそが最適解です。このツールは消費RAMが50MB未満でありながら、非常に強力です。CentOS Stream 9、AlmaLinux、Rocky LinuxなどのほとんどのRHELベースのディストリビューションに標準でインストールされています。

CentOS 8がEOL(サポート終了)になった際、私は急いでサーバー群をCentOS Stream 9に移行しました。その時最初に行ったのは、Rsyslogによるログ管理クラスターの再構築でした。何年もメンテナンスなしで極めて安定して動作し続けています。

ステップ1:ログサーバーの設定(ログ受信側)

1台のサーバーをセントラルサーバーとして指定します。設定はすべて /etc/rsyslog.conf ファイルにあります。

使い慣れたエディタでファイルを開きます:

sudo vi /etc/rsyslog.conf

以下の行を探してコメントアウトを解除し、RsyslogがUDPとTCPの両方で514ポートを開くようにします:

# UDP用
module(load="imudp")
input(type="imudp" port="514")

# TCP用
module(load="imtcp")
input(type="imtcp" port="514")

クライアントマシンのログがサーバー自体のログと混ざらないように、テンプレートを使用して自動的に分類します。ファイルの末尾に以下のコードを追加します:

$template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log"
*.* ?RemoteLogs
& ~

この設定により、ログはホスト名とアプリケーション名に基づいてディレクトリに自動的に振り分けられます。ファイルを保存し、サービスを再起動します:

sudo systemctl restart rsyslog
sudo systemctl enable rsyslog

ステップ2:CentOS Stream 9でのファイアウォール開放

ファイアウォールで514ポートを開放するのを忘れないでください。そうしないと、クライアントからのログ送信がブロックされてしまいます。

sudo firewall-cmd --permanent --add-port=514/udp
sudo firewall-cmd --permanent --add-port=514/tcp
sudo firewall-cmd --reload

ステップ3:ログクライアントの設定(ログ送信側)

次に、監視対象のサーバーに移動します。同様に /etc/rsyslog.conf ファイルを開きます:

sudo vi /etc/rsyslog.conf

末尾に以下の行を追加します(IPアドレスは自分のログサーバーのアドレスに置き換えてください):

# UDP経由で送信(高速だがパケットロスの可能性あり)
*.* @192.168.1.10:514

# TCP経由で送信(低速だが信頼性が高い)
*.* @@192.168.1.10:514

変更を適用するために、クライアント側でRsyslogを再起動します:

sudo systemctl restart rsyslog

ステップ4:結果の確認

ログサーバー側で、/var/log/remote/ ディレクトリを確認します:

ls -R /var/log/remote/

すぐにテストするために、クライアントマシンからメッセージを送信してみましょう:

logger "itfromzeroの集中ログ管理テスト!"

ログサーバーに戻ると、そのクライアントのログファイルにこの行が表示されているはずです。あらゆる場所からログが1か所に集まってくる様子を見るのは、システム全体を完全に掌握しているような、非常に爽快な気分です。

実体験から得た「鉄則」と注意点

本番環境(プロダクション)に導入する際は、以下の3点に注意してください:

  1. 容量管理: ログが集約されると、容量は非常に早く膨らみます。すぐに logrotate を設定し、古いログを定期的に圧縮・削除(例:30日間保持)するようにしてください。
  2. 通信のセキュリティ: Rsyslogはデフォルトでデータをプレーンテキストとして送信します。インターネット経由で送信する場合は、機密情報の盗聴を防ぐためにTLS/SSLの設定が必須です。
  3. SELinux: CentOS Stream 9はSELinuxの設定が厳格です。デフォルト以外のポート(514以外)を使用する場合は、semanage port コマンドでポートのラベルを更新することを忘れないでください。

集中ログ管理の設定は難しくありませんが、それによって得られるメリットは計り知れません。何か問題が発生した際、すべての証拠が1か所に揃っており、すぐに対処できると分かっていることは、エンジニアにとって大きな心の平安に繋がります。ネットワーク経由で送信されるログの完全性を保証するために、通信のセキュリティ対策も併せて検討することをお勧めします。

Share: