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
のみ指定したとすると、以下のように動作します。
-
BUNDLE_PATHは/etc/td-agent/vendor/bundle
-
BUNDLE_PATHが存在しないので/etc/td-agentをパーミッションチェックの起点とする
-
/etc/td-agent/build_info/* と /etc/td-agent/* がtd-agentユーザーで書き込み可能かどうかチェックする
-
↑で書き込み不可なファイルやディレクトリが一つでもあれば、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'
設定例
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のプラグインを管理することができます。