Server Build Exercises on AWS (Amazon Web Services) 2022 edition

コンテナのログ管理

アプリケーションの動作状況を確認するにはログを見る必要がありますが、 コンテナは一つの閉じた世界を作ってしまうため、 コンテナの中で動かしているアプリケーションのログはコンテナの中に閉じ込められています。 そして、 コンテナの中で行われた変更点はを停止すれば消えてしまうのでログも消えてしまいます。

そのため、コンテナの外へログを転送する工夫が必要です。 転送するためには、 アプリケーション側の設定変更が必要で、 場合によってはやソースコードの修正が必要なこともありえます。

もっとも楽な手段としては、 アプリケーションからのログをすべて STDOUT と STDERR に書き込むように設定し、 docker runのオプションにある-log-driverで転送方法を指定する方法があります。 ちなみに-log-driverオプションで指定可能なパラメータは json-file syslog journald gelf fluentd awslogs splunk etwlogs gcplogs noneです。

syslog

Unix では伝統的に syslog という仕組みを使っています。一番簡単な方法がこれです

docker run --log-driver=syslog [その他のオプション] コンテナ名

と起動すればログは syslog に転送されます。

Unix でも OS ごとに少しずつ異なるので注意が必要ですが、 たいてい、 ログは /var/log/messages ファイルか /var/log/syslog ファイルに書きこまれるので、 このファイルをみて動作を確認します

ちなみに、新たに追記されたログがターミナルに次々と表示されてくるように、 -F オプションをつけて tail コマンドを使うテクニックが便利です(定番です)

sudo tail -F /var/log/messages 

出力例: 1行目は nginx のログ、2行目は www.go が mysql にアクセスできなかったというエラー

Dec 11 11:27:36 ip-172-31-87-16 d6a00c26379b[2969]: 118.19.153.189 - - [11/Dec/2021:11:27:36 +0000] "POST /search HTTP/1.1" 200 27 "http://3.83.39.191/shop.html" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36" "-"
Dec 11 11:47:43 ip-172-31-87-16 24b1585faf62[2969]: 2021/12/11 20:47:43 dial tcp 172.30.0.2:3306: connect: connection refused

エラーの探し方

Unix コマンドは一行単位を前提とした設計なので、これに合わせて、 syslog に書かれるログは一つのログが一行です。

エラーの場合 error や fatal といった単語が使われるので、 だいたいそれを便りに検索して人間が読んで分析するという対応を長年しています (ここで使うのが grep コマンド)。

ログ収集システムの運用

ログで一番問題になる点はフォーマットがバラバラなことでしょう。 いわゆる非構造化データの代表です

問題はログのフォーマットで、 日付やsyslogのタグなどのあと(右側)に、 アプリケーションから送られてくる文字列そのものが記録されます。 この文字列はアプリケーションごとに異なり本当に千差万別です。

かつては syslog で、すべての情報を syslog サーバに集結させるというのが定番でした。 syslog のログをためこむ仕組みを作るのは簡単なのですが、 運用はいまいちで、あくまでも非常時にエラーを探せる最低ラインの仕組みです。 そこからエラーを分析するには人間が目で見て分析するという熟練の技が必要でした。 つまり検索や可視化は、あんまり考えてないんですね

そこで、 最近の定番は syslog サーバではなく、 アプリケーションから fluentd というサーバへ fluentd のプロトコルでデータを送り、 fluentd がログのフォーマットを統一します

アプリケーション --> fluentd --> elasticsearch -> kibana もしくは grafana

トレジャーデータ社の fluentd は、 そのため(ログの収集とフォーマット標準化)のソフトウエアです。 それを elasticsearch という検索エンジンにデータを集め、 それを kibana や grafana といったソフトウエアで可視化するという仕組みを作ります。

ちなみに elasticsearch ではなく Apache Spark に集める構成もあります

fluentd -> kafka  <-> spark <-> mysql
embulk  -> hadoop <-> spark

Apache kafka は流量調整のためにはさむキューイング(queing)のソフトウエアです

fluentd の部分には、いくつかの選択肢があります。

  • ストーム処理はfluented (ruby と C, トレジャーデータ社)
  • バッチはembulk (ruby と C, トレジャーデータ社)
  • 組み込み機器向けの fluent-bit (C言語, トレジャーデータ社)
  • logstashというelasticsearchを作っている会社が出していたオープンソースもの、 最近あまり聞かないのはコンテナに向いてないからみたい?

fluentd は ruby なので、 ログのためだけに大きなソフトウエアだよなぁ〜とか、そのへんがいまいちだったのですが、 いまはC言語で小さくて高速な fluent-bit があるので、これを使うのがいいと考えています。 fluent-bit は Go言語プラグインもあるので最悪 Go言語でカスタマイズできるはずです (<- ruby さわりたくないと言っている? そうで〜す)。

Last updated on 11 Dec 2021
Published on 11 Dec 2021
Copyright (C) 2021-2022 Ken'ichi Fukamachi, All rights reserved. CC BY-NC-SA 4.0
We appreciate AWS Academy Japan for the offer of the learning environment.

Powered by Hugo. Theme by TechDoc. Designed by Thingsym.