先日 DockerにおけるロギングのSidecarアプローチ | shinodogg.com というエントリで、LogglyでDockerのログを一元管理する方法をご紹介しましたが、今日はCloudWatch LogsでDocker(Amazon ECSのタスク)のログを一元管理する方法を考えていきたいと思います。
awslogsログドライバーをGetting Startedしてみる
Using the awslogs Log Driverに沿って進めていくため、WordPressやMySQLのDocker imageを使ってEC2上にECSでタスク(EC2上に稼働するコンテナ)定義しながら構築を進めていく形になります。
awslogsをEC2インスタンスにインストール
Using CloudWatch Logs with Container Instancesに沿ってCloudWatch Logsのエージェントであるawslogsをコンテナを稼働させるEC2インスタンスにインストールしていきます。
$ which awslogs /usr/bin/which: no awslogs in (/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin) $ sudo yum install -y awslogs 読み込んだプラグイン:priorities, update-motd, upgrade-helper amzn-main/latest | 2.1 kB 00:00 amzn-updates/latest | 2.3 kB 00:00 依存性の解決をしています 〜略〜 python27-ply.noarch 0:3.4-3.12.amzn1 python27-pyasn1.noarch 0:0.1.7-2.9.amzn1 python27-rsa.noarch 0:3.4.1-1.8.amzn1 完了しました!
awslogsの設定ファイルは /etc/awslogs/awslogs.conf に配置してあって、中身を開くとサービスの起動の仕方とかが書いてあります。
# ------------------------------------------ # CLOUDWATCH LOGS AGENT CONFIGURATION FILE # ------------------------------------------ # # --- DESCRIPTION --- # This file is used by the CloudWatch Logs Agent to specify what log data to send to the service and how. # You can modify this file at any time to add, remove or change configuration. # # NOTE: A running agent must be stopped and restarted for configuration changes to take effect. # # --- CLOUDWATCH LOGS DOCUMENTATION --- # https://aws.amazon.com/documentation/cloudwatch/ # # --- CLOUDWATCH LOGS CONSOLE --- # https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logs: # # --- AGENT COMMANDS --- # To check or change the running status of the CloudWatch Logs Agent, use the following: # # To check running status: service awslogs status # To stop the agent: service awslogs stop # To start the agent: service awslogs start # To start the agent on server startup: chkconfig awslogs on # # --- AGENT LOG OUTPUT --- # You can find logs for the agent in /var/log/awslogs.log
今回はサンプルに沿って↓のように書き換えます。
[general] state_file = /var/lib/awslogs/agent-state [/var/log/dmesg] file = /var/log/dmesg log_group_name = /var/log/dmesg log_stream_name = test/725126da-6e5b-453a-96b0-bc6fe0b6c34c [/var/log/messages] file = /var/log/messages log_group_name = /var/log/messages log_stream_name = test/725126da-6e5b-453a-96b0-bc6fe0b6c34c datetime_format = %b %d %H:%M:%S [/var/log/docker] file = /var/log/docker log_group_name = /var/log/docker log_stream_name = test/725126da-6e5b-453a-96b0-bc6fe0b6c34c datetime_format = %Y-%m-%dT%H:%M:%S.%f [/var/log/ecs/ecs-init.log] file = /var/log/ecs/ecs-init.log.* log_group_name = /var/log/ecs/ecs-init.log log_stream_name = test/725126da-6e5b-453a-96b0-bc6fe0b6c34c datetime_format = %Y-%m-%dT%H:%M:%SZ [/var/log/ecs/ecs-agent.log] file = /var/log/ecs/ecs-agent.log.* log_group_name = /var/log/ecs/ecs-agent.log log_stream_name = test/725126da-6e5b-453a-96b0-bc6fe0b6c34c datetime_format = %Y-%m-%dT%H:%M:%SZ [/var/log/ecs/audit.log] file = /var/log/ecs/audit.log.* log_group_name = /var/log/ecs/audit.log log_stream_name = test/725126da-6e5b-453a-96b0-bc6fe0b6c34c datetime_format = %Y-%m-%dT%H:%M:%SZ
デフォルトではCloudWatch Logsはus-east-1にデータを送信するようになっているので、/etc/awslogs/awscli.conf のリージョンを変更します。
[plugins] cwlogs = cwlogs [default] region = ap-northeast-1
それでは awslogs を起動します。ついでに自動起動するように仕込んでおきます。
$ sudo service awslogs start Starting awslogs: [ OK ] $ sudo chkconfig awslogs on
でもって、CloudWatch Logsではそれっぽく見えてます。
//embedr.flickr.com/assets/client-code.js
でもって、毎回こういうことやるの面倒なので、cloud-initとかでよしなに〜っていうのは今回は割愛させていただいて…。あと、IAMロールでlogs:CreateLogStreamとかlogs:PutLogEventsの権限が必要よん、、とか。
ECSのTaskからCloudWatch Logsにデータを送信
ロググループの作成
例えばWordPressなヤツであれば、WordPressコンテナ用のロググループと、MySQLコンテナ用のロググループを作ります。
$ aws logs create-log-group --log-group-name awslogs-wordpress --region ap-northeast-1 $ aws logs create-log-group --log-group-name awslogs-mysql --region ap-northeast-1
ECS Taskの定義&実行
サンプルをまんまで↓ECSのコンソールのタスク定義から突っ込んで登録した後、
{ "containerDefinitions": [ { "name": "wordpress", "links": [ "mysql" ], "image": "wordpress", "essential": true, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "awslogs-wordpress", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "awslogs-example" } }, "memory": 500, "cpu": 10 }, { "environment": [ { "name": "MYSQL_ROOT_PASSWORD", "value": "password" } ], "name": "mysql", "image": "mysql", "cpu": 10, "memory": 500, "essential": true, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "awslogs-mysql", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "awslogs-example" } } } ], "family": "awslogs-example" }
コンテナインスタンスでタスクを実行します。
//embedr.flickr.com/assets/client-code.js
CloudWatch Logsでログの確認
WordPressにアクセスしてみます。
//embedr.flickr.com/assets/client-code.js
CloudWatch Logs上で狙ったようにWordPressのログが出ていて、
//embedr.flickr.com/assets/client-code.js
MySQLの方もそれっぽいログが出ていました。
//embedr.flickr.com/assets/client-code.js
追加でログを取りたくなったら、、
例えばアクセスログだけでなく、PHPのデバッグログを見たい!という場合があるかもしれません。その場合、1つのコンテナ上で複数ファイルを上記の仕掛けでやりくりすることは出来ないので、EC2インスタンスのボリュームをマウントしてそこに書き込みを行い、それをCloudWatch Logsに流すコンテナを立ち上げることにします。
ECSのタスク定義に以下のように追加します。WordPressのDockerコンテナの /var/www/html を、コンテナインスタンス(EC2)の wpdata というディレクトリにマウントして、そこに書き込むことができる、という設定です。
"mountPoints": [ { "sourceVolume": "wpdata", "containerPath": "/var/www/html", "readOnly": false } ]
コンテナインスタンス上の wpdata は今回は適当にホームディレクトリな設定にしました…
//embedr.flickr.com/assets/client-code.js
ということで、/var/www/html にある wp-config.php で デバッグログ設定を以下のように有効にします。
define('WP_DEBUG', true); define('WP_DEBUG_DISPLAY', false); define('WP_DEBUG_LOG', true);
そうすることで、 wp-content ディレクトリの中に以下のような debug.log というファイルが出来ます。(ログの出力先のパスを変えなさいよっていう話もあるのですが、、)
今回はこのファイルをtailしてCloudWatch Logsに転送してみたいと思います。
[08-Feb-2017 08:25:38 UTC] WordPress database error Table 'wordpress.wp_users' doesn't exist for query SELECT * FROM wp_users WHERE user_login = 'hoge' made by require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), WP->init, wp_get_current_user, _wp_get_current_user, apply_filters('determine_current_user'), WP_Hook->apply_filters, call_user_func_array, wp_validate_logged_in_cookie, wp_validate_auth_cookie, get_user_by, WP_User::get_data_by
DebugログをCloudWatch Logsに転送するコンテナを立てる
今回はログtailして出力するDocker imageとしてfluent/fluentd(https://hub.docker.com/r/fluent/fluentd/)を使ってみたいと思います。
タスク定義にfluentd用のコンテナの設定を以下のように追加します。
イメージは fluent/fluentd。
//embedr.flickr.com/assets/client-code.js
fluentdの設定ファイルは、試しに立ち上げて docker exec -it {CONTAINER ID} /bin/sh で中入ってみたら↓こんな感じだったので、
$ ps -ef PID USER TIME COMMAND 1 fluent 0:00 {fluentd} /usr/bin/ruby /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins 6 fluent 0:00 {fluentd} /usr/bin/ruby /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins 18 fluent 0:00 /bin/sh 25 fluent 0:00 ps -ef
コンテナインスタンス(ECSのタスクが稼働するEC2インスタンス)の適当なところに fluent.conf を置いて読み取り専用で /fluentd/etc にマウントして、
ついでに debug.log も読み込めるように、wpdata(上記のWordPressのコンテナが吐き出したdebug.logは /var/www/html/wp-content に出力される)も /home/fluent に読み取り専用でマウントしておきます。
//embedr.flickr.com/assets/client-code.js
超絶雑で大変申し訳ございませんがコンテナインスタンス(EC2)と各タスク(Dockerコンテナ)は↓こんな構成。笑
//embedr.flickr.com/assets/client-code.js
ログ出力に関しては、awslogs-php というグループを後で作ることにして、こちらも今までと同様にawslogsを使ってCloudWatch Logsに連携するように設定します。これによって標準出力に吐き出すだけでログが転送されます。
ということでfluent.confの中身は↓こんな感じ。debug.logをtailして標準出力に吐き出すだけ。
<source> @type tail path /home/fluent/wp-content/debug.log format none tag php @id input </source> <match **> @type stdout @id output </match>
※ CloudWatch Logsまでデータが行くと、その先にAmazon Elasticsearch Serviceに簡単に突っ込めたり、AWS Lambdaでホゲホゲしたりとか、色々便利なのですが、その辺の話はまた別途…
CloudWatch Logsにロググループを追加してDebugログを出力する
CloudWatch LogsのロググループはPHP用に以下のものを用意します。 $ aws logs create-log-group --log-group-name awslogs-php --region ap-northeast-1
例えばですが、、WordPressの 外観 メニューから選べる Twenty Seventeen: テーマヘッダー (header.php) の中に
↓こんなコードを一行追加してみます。
error_log("hoge log");
ECSタスクを実行後にCloudWatch Logsを見ると↓こんな風に仕込んだデバッグログが見えます。
//embedr.flickr.com/assets/client-code.js
最後に
今回『アプリケーションが稼働するコンテナ→データボリューム→ログをtailして吐き出すコンテナ→CloudWatch Logs』といったような流れをawslogsを使ってやってみました。この仕掛けを使いながら DockerにおけるロギングのSidecarアプローチ | shinodogg.com で紹介したようなsidecarやsidekicksと呼ばれるようなやり方を実現できると、コンテナ化しても安心してログ管理が出来るのではないかと思います。
文藝春秋
売り上げランキング: 43,902
コメント