FluentdのDaemonSetで、Kubernetes NodeのログをAmazon S3に集約する

AWS

1. やりたいこと

Nishipy
KubernetesをのWorker Nodeのログを、FluentdによりS3に転送してみます。Fluentdは、KubernetesのDaemonsetとしてデプロイします。構成としては、こんな感じです。

2. 予備知識

KubernetesのWorker Nodeのログを、FluentdによりS3に転送するにあたり、予備知識について少しまとめます。

Fluentd

ググってみると、オープンソースのデータ収集ソフトウェアと書かれています。「データを収集して転送する」というようなことが実現できるようです。
特に、各サーバのアプリケーションログやコンテナログを収集して転送し、ログの保存や解析を担うサーバに集約するような使い方が多いようです。

また、多くのプラグインが用意されており、データ転送先の選択肢が豊富です。

  • Amazon S3
  • Google Cloud Storage(GCS)
  • Elasticsearch
  • CloudWatch Logs
  • Stackdriver Logging など

Kubernetes

オープンソースのコンテナオーケストレーションシステムであるKubernetesは、ここ数年よく耳にするようになりました。私も近頃、仕事で使う機会が増えてきたため勉強しているところです。ちなみに2018年は、Kubernetesのスキルがある人が、米国の転職市場でもっとも有利だったらしい。この流れは、日本にも来るのでしょうか。来てほしい。

Just a moment...

日本語の本だと、これがすごく良いです。いつもお世話になっています。

KubernetesのWorkerノードや、その上で動くコンテナログを収集する際は、FluentdのDaemonsetを使うことが推奨されているようですので、今回実装してみます。
ログ収集に関しても、↑の本の16章に記載があり、FluentdからStackdriver Loggingにログを転送する例が解説されています。
同じことをしても面白くないので、この記事ではFluentdからAWSのS3にログを転送する方法を検討します。

3. 下準備

Kubernetes環境

S3を使うということで、私はEKSでKubernetesをデプロイしました。このあたりを参考にして、用意してください。

EKS Workshop | EKS Workshop
Amazon Web Services workshop for Elastic Kubernetes Service

S3バケット

ログを転送するS3バケットも、あらかじめ用意してください。また、バケットポリシーも適切に設定しておいてください。
S3プラグインのGithubに載っている情報を元に、設定すれば、おそらく問題ないと思います。

GitHub - fluent/fluent-plugin-s3: Amazon S3 input and output plugin for Fluentd
Amazon S3 input and output plugin for Fluentd. Contribute to fluent/fluent-plugin-s3 development by creating an account on GitHub.

例えば、こんなポリシーとか。

試したいだけなら、バケットを公開するのもありかもしれません。

アクセスキー

バケットに転送するために、アクセスキーも用意しておきます。こちら、ご参考。

IAM ユーザーのアクセスキーの管理 - AWS Identity and Access Management
AWS へのプログラムによる呼び出しのアクセスキー (認証情報) を作成、変更、表示、または更新します。

Dockerイメージ

fluentd公式のDockerイメージに、S3プラグインをインストールします。今回は、予めDockerイメージとしてビルドしていますが、Kubernetesのマニフェストでやってもいいと思います。

fluent-plugin-s3をインストール済みのDockerイメージは、Dockerhubに公開しています。

Docker

4. やってみる

これだけ下準備ができれば、残りはkubernetesのマニフェストファイルを書くだけです。


ConfigMap

まずは、fluentdの設定ファイルfluent.confを、KubernetesのConfigMapとして定義します。今回は/var/log/messagesを、fluentdによりtailして、S3に転送します。<match td.messages>...</match>内の、aws_key_ids3_bucketなどの値は、下準備で用意したものに置き換えてください。

ちなみに<match td.messages>...</match>pathは、Worker Nodeのホスト名によりスライスされるように設定しています。Worker Nodeのホスト名は、後述のDaemonsetのマニフェストファイルで、環境変数NODE_NAMEに渡します。

DaemonSet

次に、DaemonSetの定義を行います。下準備に記載したDockerイメージをpullして、設定していきます。

マニフェストファイルの適用

マニフェストファイルを、kubectl applyで適用します。うまくいかない時は、kubectl log [Pod Name]でデバッグしましょう。

S3バケットを見てみる

最後にAWSコンソールで、S3バケットを見てみます。しばらくすると、S3にログが転送されてくるのがわかります。<match td.messages>...</match>pathで設定したように、各Worker Nodeのホスト名が含まれた形でスライスできています。

できた!


5. 最後に

DaemonSetを初めて知った時は、「これいつ使うん?」と思っていました。あの頃の自分をしばきたい。Fluentdと組み合わせると、すごく便利そうですね。今回はログの保管を目的としてS3を使いましたが、Elasticsearch+Kibanaに転送して、ログの可視化を行うのも面白そうです。
Kubernetes楽しいので、いろいろやってみて、また記事にします。最後まで読んでいただきありがとうございます。

以上.

コメント