LoginSignup
3
4

More than 5 years have passed since last update.

KubernetesのPodのログをすべてsyslogに送り付ける

Posted at

Elasticsearchがいくら盛り上がったところで既存の監視システムとの兼ね合いでアプリのログはsyslogに来ないと困っちゃうという事は良くある話でして。
filebeat使えれば良かったんですが、あれでsyslogに出力するのが結構難儀。
基本的には、Kubernetes上で動作するPodのコンテナ出力ログは、kubeletが「/var/log/containers/」ディレクトリ下に「pod名namespace名コンテナ名っぽい何か.log」のファイル名でリンクを張ってくれるので、それをtail -Fしてloggerコマンドでsyslogに送り付ければ良い。

/root/logsys
#! /bin/bash
MYNAME=logsys
LOGDIR=/var/log/containers
ACTIVE=/dev/shm/$MYNAME

mkdir -p $ACTIVE

watch () {
  logger -t $MYNAME -- $MYNAME::start watching $l
  echo $BASHPID > $ACTIVE/$1
#  tail -F -c +0 $LOGDIR/$1 | while read m; do
  tail -F $LOGDIR/$1 | while read m; do
    logger -t $MYNAME -- $1::$m
  done
  rm $ACTIVE/$1
}

ls $LOGDIR | while read l; do
  if [ ! -e $ACTIVE/$l ]; then
    watch $l &
  fi
done

上記はスクリプトを実行した後に出力されたログをsyslogに転送しますが、tailに-c +0オプションが付いたほうの行に変えればスクリプト実行時点で存在するログもすべてsyslogに送ります。まあ、気を付けて使用ください。
chmod +x /root/logsys してですね、新しいPodが作成された時も勝手にsyslogにも出力してくれるよう、それを crontab -e で1分に1回実行するように仕込みます。

crontab
* * * * * /root/logsys

停止したい場合は、crontab -eで上記行をコメントアウトして定期実行を止めたのち、以下のコマンドを実行してスクリプトのtailプロセスを全部止めます。

for i in $(ls /dev/shm/logsys); do kill $(ps --ppid $(cat /dev/shm/logsys/$i) -o pid=); done

場合によっては大量のログが出力されることになるので、「ls $LOGDIR | while read l; do」の直後ぐらいに、ファイル名からnamespace名等でsyslog転送するログをフィルタする処理を追加したほうが良いでしょう。ちなみにwhile文でそのループの処理を途中でスキップするにはcontinueを使います。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4