ククログ

株式会社クリアコード > ククログ > td-agent3でGemfileベースのプラグイン管理

td-agent3でGemfileベースのプラグイン管理

Fluentdのプラグイン管理はGemfileベースでやると、きちんとバージョンを管理できるのでよいです。 ドキュメントでもGemfileベースのプラグイン管理について書かれています。 しかし、記事執筆時点ではtd-agentでどのようにするのかは、書かれていませんでした。

td-agent3からsystemdに対応しているので、特に断りがない場合はsystemdについて書いています。 また、パッケージはいくつか種類がありますが主にdebパッージについて書きます。rpmの場合でも、serviceファイルなどの内容は同じなので、そのまま使える知識です。

使用するソフトウェアで特にバージョンを気にするものは以下の通りです。

  • td-agent 3.1.1

  • bundler 1.16.0

bundle install中にsudoを実行される

Fluentdは--gemfileオプションを指定すると、起動時に指定されたGemfileを使ってbundle installを実行します。 このとき、bundlerがある条件下でsudoを実行しようとしますが、td-agentを使用している場合、td-agentユーザーはsudoを使用できるようになっていないのでエラーになってしまいます。 なお、Fluentdは--gemfileオプションのみを指定すると、そのGemfileと同じディレクトリのvendor/bundleというディレクトリをBUNDLE_PATHとして使用します。

--gemfile /etc/td-agent/Gemfileのみ指定したとすると、以下のように動作します。

  1. BUNDLE_PATHは/etc/td-agent/vendor/bundle

  2. BUNDLE_PATHが存在しないので/etc/td-agentをパーミッションチェックの起点とする

  3. /etc/td-agent/build_info/* と /etc/td-agent/* がtd-agentユーザーで書き込み可能かどうかチェックする

  4. ↑で書き込み不可なファイルやディレクトリが一つでもあれば、sudoが必要と判定する

今の場合、td-agentをインストールした後、すぐにGemfileを置いてtd-agentを再起動したとすると以下のファイルやディレクトリのパーミションをチェックします。

  • /etc/td-agent

  • /etc/td-agent/td-agent.conf

  • /etc/td-agent/plugin

そのパーミッションは以下の通りで、pluginディレクトリとtd-agent.confはtd-agentユーザーから書き込みできません。

$ ls -laR /etc/td-agent/
/etc/td-agent/:
total 16
drwxr-xr-x  3 td-agent td-agent 4096 Mar  1 08:44 .
drwxr-xr-x 57 root     root     4096 Mar  5 06:14 ..
drwxr-xr-x  2 root     root     4096 Mar  1 08:43 plugin
-rw-r--r--  1 root     root     2381 Mar  1 08:44 td-agent.conf

よって、bundlerはsudoが必要だと判定してしまいます。

どのようにすればよいかは後述します。

td-agentユーザーのホームディレクトリが存在しない

これはdebパッケージ限定の問題ですが、masterでは修正済みです。 ホームディレクトリが存在しない場合、/tmp/bundler/home/vagrantのようなディレクトリをかわりに使用するため、マシンを再起動するとbundlerのキャッシュが消えます。 また、起動するたびにログにメッセージが残るのも本来着目すべきログを見つけづらくなります。

td-agent 3.1.1のメンテナスクリプトでは、以下のようにホームディレクトリ(/home/td-agent)を作成していませんでした。

adduser --group --system --no-create-home td-agent

ホームディレクトリを /var/lib/td-agent に変更して作成します。 /var/lib/td-agentにしたのはRPMに合わせるためです。また、システムユーザーは/var/lib以下にホームディレクトリを持つことが多いためです。

$ sudo usermod -d /var/lib/td-agent td-agent
$ sudo mkdir -p /var/lib/td-agent
$ sudo chown -R td-agent:td-agent /var/lib/td-agent

systemdのドロップインファイルについて

td-agentはsystemdに対応しているので、systemdの場合はtd-agentのオプションをカスタマイズするのに/etc/default/td-agent1や/etc/sysconfig/td-agent2は使いません。

ドロップインファイルというものを使用します。

$ sudo systemctl edit td-agent.service

を実行するとエディターが起動するので、内容を書いて保存すると/etc/systemd/system/td-agent.service.d/override.confというファイルを作成することができます。

td-agent 3.1.1 の場合は以下のようにすると、td-agentのオプションを変更することができます。

[Service]
Environment='TD_AGENT_OPTIONS=--gemfile=/etc/td-agent/Gemfile'
ExecStart=
ExecStart=/opt/td-agent/embedded/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid $TD_AGENT_OPTIONS

masterではExecStartに$TD_AGENT_OPTIONSが追加されているので以下のようにEnvironmentだけ指定すれば十分です。

[Service]
Environment='TD_AGENT_OPTIONS=--gemfile=/etc/td-agent/Gemfile'

参考: systemd - ArchWiki

設定例

td-agent 3.1.1

td-agent 3.1.1では次のようにします。

debの場合、td-agentユーザーのホームディレクトリを作成してください。

$ sudo usermod -d /var/lib/td-agent td-agent
$ sudo mkdir -p /var/lib/td-agent
$ sudo chown -R td-agent:td-agent /var/lib/td-agent

bundlerがsudoを必要としないドロップインファイルは以下の通りです。--gem-fileオプションでGemfileを指定し、--gempathオプションでtd-agentユーザーが書き込むことができるパスを指定します。

[Service]
Environment='TD_AGENT_OPTIONS=--gemfile=/etc/td-agent/Gemfile  --gempath=/var/lib/td-agent/vendor/bundle'
ExecStart=
ExecStart=/opt/td-agent/embedded/bin/fluentd --log /var/log/td-agent/td-agent.log --daemon /var/run/td-agent/td-agent.pid $TD_AGENT_OPTIONS

td-agent の次のリリースでは

bundlerがsudoを必要としないドロップインファイルは以下の通りです。

td-agentユーザーのホームディレクトリはパッケージによって作成済みなので、ドロップインファイルで環境変数を指定すればよいだけです。 環境変数の内容はtd-agent 3.1.1と同じです。

[Service]
Environment='TD_AGENT_OPTIONS=--gemfile=/etc/td-agent/Gemfile  --gempath=/var/lib/td-agent/vendor/bundle'

トレードオフ

Gemfileでプラグインを管理する場合、td-agent起動時にbundle installを実行するため、td-agentにバンドルされているgemであってもgemパッケージをダウンロードします。 Gemfileでプラグインのバージョンを固定できるというメリットとのトレードオフです。

まとめ

td-agent3でGemfileを使ってFluentdのプラグインを管理する方法を紹介しました。 きちんと設定すればtd-agentユーザーにsudoできる権限を与えずにGemfileを使ってFluentdのプラグインを管理することができます。

  1. debの場合

  2. rpmの場合