はじめに
Dockerのコンテナなどを用いてProxyサーバを立てることがありますが、そこで生成されるaccess.log
はそのままではログサーバに送ることが出来ません。この記事ではこの課題に対する1つの解決方法を提示します。
解決方法
内容は以下の通りです。
- ログ保管場所を永続化させるようにした Proxyサーバコンテナの作成する。
- ホスト側のrsyslogdの設定で上記の
access.log
をリモートのsyslogサーバに転送する。
Proxyサーバコンテナの構築
ここではProxyサーバはSquidで構築します。コンテナ内の/var/log/squid
をホスト側の/home/user/containers/proxy/logs/
にバインドします。Dockerfile
とdocker-compose.yml
は以下の通りです。ディレクトリの位置は各自の都合で変更してください。
/home/user/containers/proxy/Dockerfile
FROM ubuntu:latest
# Installing squid
RUN apt update && \
apt install -y squid
# Squid settings
RUN sed -ri 's/^#http_access allow localnet/http_access allow localnet/' /etc/squid/squid.conf && \
sed -ri 's/#cache_dir/cache_dir/' /etc/squid/squid.conf && \
sed -ri 's/^cache_dir/#cache_dir/' /etc/squid/squid.conf && \
echo 'cache_dir ufs /var/spool/squid 100 16 256' >> /etc/squid/squid.conf
# Initialize Squid cache directory
RUN squid -z
EXPOSE 3128/tcp
CMD [ "squid", "-N" ]
/home/user/containers/proxy/docker-compose.yml
version: '3'
services:
squid:
build: .
ports:
- "3128:3128"
volumes:
- ./logs:/var/log/squid
- ./cache:/var/spool/squid
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.***.***:514"
tag: proxy
restart: always
コンテナ内のSquidはDockerのログドライバを利用してくれないのですが、Dockerコンテナ自身のエラーを集約するためにdocker-compose.yml
の中にsyslogサーバへの転送を記述しています。IPアドレスを各自の環境に合わせて修正してください。
次に必要なディレクトリを作成します。
$ cd /home/user/containers/proxy
$ mkdir cache logs
$ sudo usermod -aG user proxy
$ sudo usermod -aG syslog proxy
$ sudo chown proxy.proxy cache logs
$ sudo chmod 775 cache logs
3行目のuser
は管理者がユーザ権限でログを調査したい場合などのためにあった方が良い設定です。user
は各自のユーザ名に置き換えてください。
設定が出来たらコンテナを起動させます。
$ docker compose up -d
rsyslog設定ファイルの変更
コンテナ内のログをログサーバに転送したいという要求は他のコンテナでも起こるかもしれませんので、コンテナごとに設定ファイルを分けます。以下のファイルを/etc/rsyslog.d/
に追加します。
/etc/rsyslog.d/30-proxy_container.conf
module(load="imfile")
input(type="imfile"
file="/home/user/containers/proxy/logs/access.log"
tag="proxy"
facility="local0"
severity="notice")
:syslogtag, isequal, "proxy" @@192.168.***.***:514
この設定のポイントはimfile
のモジュールを使ってファイルを監視するところで、ファイルの更新があるとその更新分をrsyslogdで処理することになります。監視するファイルとtag
を書き換えた設定ファイルを増やすことで他のコンテナのログ転送もすることが出来ます。
最後の行のIPアドレスはリモートのログサーバのIPアドレスとします。たいていの場合は、docker-compose.yml
に記述したログサーバのIPアドレスと同じになるでしょう。
設定が出来たらrsyslogdを再起動します。
$ sudo service rsyslog restart
$ sudo service rsyslog status
● rsyslog.service - System Logging Service
Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2023-09-08 08:06:09 UTC; 31s ago
(以下略)
ステータス確認でエラーが起きている場合は設定ファイルに誤りがある場合や、ログファイルアクセスのためのパーミッションが足りない場合があります。エラーメッセージを読んで確認してください。
動作確認
ウェブブラウザなどでProxyサーバの設定をして適当なページをアクセスしてください。ログサーバにaccess.log
の内容が転送されていれば成功です。
その他
はまりポイント
私の場合は/home/user/containers/proxy
以下にコンテナ関連ファイルを置きましたが、最初は以下のエラーが発生しました。
imfile: on startup file '/home/user/containers/proxy/log/access.log' does not exist
but is configured in static file monitor - this may indicate a misconfiguration.
これは、/home/user
のパーミッションが700
だったためでしたので、sudo chmod 755 ~
などとしてアクセス許可をしました。解決方法は他にもありますので、皆さんの都合の良い方法を適用していただければと思います。
残作業
-
ホスト上のログファイルの取り扱い
/var/log/squid
を永続化したのは良いのですが、このままではホストのストレージが溢れてしまいます。logrotate
の設定などが必要です。リモートのログサーバへの転送が確実に行われていることを確認出来たら、ここでのログ保存は数時間程度分だけでも良いかもしれません。 -
転送用syslogサーバのコンテナ化
今回はコンテナホスト側でsyslogサーバを動かしていたのでそのまま使いましたが、軽量ホストを使う場合は
rsyslogd
もコンテナ化することになるでしょう。また、上記ログ管理のためにlogrotate
のコンテナも作ることになります。機能ごとにrsyslogd
コンテナやlogrotate
コンテナを立てるか、ホスト上にある全てのコンテナのログを管理するためのrsyslogd
コンテナ、logrotate
コンテナを立てるかは思案のしどころです。
考察
この作業をするために検討していたことを記しておきます。
-
コンテナ上にsquidとrsyslogdを同居させる
この記事など、いくつかの事例がありますが、どれも2つの機能を実行させるために
init
やstartup.sh
などでコンテナの最後のコマンドを実行する必要があります。ダメというわけではありませんが、以下の事を考慮して見送りました。- シンプルでなく、メンテナンス上の問題を抱える可能性がある。
-
squid
からrsyslogd
にログを送る際にjournald
などを使う場合はさらに設定が複雑になる(のかな?)。
もっと良い方法がありましたら教えてください。
-
Dockerのログドライバ
sshサーバコンテナを作った時は
sshd_config
に特別な設定をしなくてもDockerのログドライバでリモートログサーバにログを転送できました。Squidではsquid.conf
にaccess.log syslog:local0.info combined
を追加してみても、Dockerのログドライバからリモートログサーバに転送してくれませんでした。何か勘違いがあったら教えてください。
以上です。