自転車操業になりつつある「初老丸の独り Advent calendar 2015」の十七日目の記事です。
追記(2016/01/20)
ECS 上の Docker コンテナから CloudWatch Logs を利用する場合には以下の点に注意が必要です。
- Task Definition での定義はサポートしていない
docker run
時のオプションで指定することで利用は可能
コメントにて id:NewGyu さんよりご指摘頂きました。id:NewGyu さん、コメント有難うございました。
現時点ではTask Definitionにawslogsを指定すると「awslogsなぞ知らん」と言われてしまい使えないようです。 ただ、ECSAgentにそれっぽいプルリクが来ているので近日使えるようになりそうな気配です。 https://github.com/aws/amazon-ecs-agent/pull/251
上記の通り、ECS Agent に Logging Driver として CloudWatch Logs を利用出来るようにするプルリクがあるようです(Stream 名(デフォルトは Container ID))について検討が必要な点があるようです)ので、近いうちに Task Definition で指定が可能になると思います。
tl;dr
Amazon ECS で個人的な疑問を紐解いていきたい。
今日の疑問
疑問
- Docker の Logging Driver で CloudWatch Logs が使えるとのことですが、ECS でも使えますでしょか
答え
- 少々お待ち下さい、ECS から直接利用するにはもう少し時間がかかりそうです(2016/01/20)
安心してください、もちろん使えますよ
以下のようにドキュメントにも記載されいる。
ポイントとしては Credentials だと思う。(後ほど)
ちなみに Logging Driver とは
個人的な認識だがコンテナのログを以下のようなミドルウェアに出力することができるようになるオプション。
- json-file
- syslog
- journald
- gelf
- fluentd
- awslogs(CloudWatch Logs)
ドキュメントを読むと、Docker Engine を起動する際、Docker コンテナを起動する際にオプションとして Logging Driver を指定できるようだ。
以下、Docker Engine 起動時のオプション。(ドキュメントより抜粋)
$ docker daemon --log-driver=json-file --log-opt labels=foo --log-opt env=foo,fizz
以下、コンテナ起動時のオプション。(ドキュメントより抜粋)
$ docker run --log-driver=syslog --log-opt syslog-address=tcp://192.168.0.42:123
ECS で Logging Driver CloudWatch Logs 試す
教材
引き続き、教材は以下の教材を利用する。
まずは Credential
以下のような IAM Policy をコンテナインスタンスに適用する必要がある。
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "*" } ] }
教材の terraform/iam.tf を以下のように修正する。
$ git diff iam.tf diff --git a/terraform/iam.tf b/terraform/iam.tf index 3734e62..8811f67 100644 --- a/terraform/iam.tf +++ b/terraform/iam.tf @@ -50,6 +50,14 @@ resource "aws_iam_role_policy" "ecs_iam_role" { ], "Effect": "Allow", "Resource": "*" + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": "*" } ] }
次に CloudWatch Logs の Log Group を作っておく
これも教材に追加。
$ cat cwlog.tf # # Create CloudWatch Logs Log Group # resource "aws_cloudwatch_log_group" "oreno_cw_log" { name = "docker-logging" }
terraform apply
あとは terraform apply
するだけ。(教材では make tf-apply
)
$ make tf-apply (snip) Outputs: CloudWatch Logs Log Group Name = docker-logging EC2 IP address = xxx.xxx.xxx.xxx EC2 Instance ID = i-xxxxxxxx ECS Cluster Name = oreno-cluster
hello-world
コンテナインスタンスにログインして hello-world してみる。
$ docker run \ > --log-driver=awslogs \ > --log-opt awslogs-region=ap-northeast-1 \ > --log-opt awslogs-group=docker-logging \ > hello-world Hello from Docker. This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker Hub account: https://hub.docker.com For more examples and ideas, visit: https://docs.docker.com/userguide/
以下のようにログが出力されている。
Log Stream 名を指定しなければ上記のようにコンテナ ID が Log Stream 名となる。
おお簡単。
CloudWatch Logs Logging Driver について
ドキュメントより抜粋。
- Docker Engine のオプションとして
$ docker daemon --log-driver=awslogs
- コンテナの起動時にオプションとして
$ docker run --log-driver=awslogs
awslogs-region
オプション
リージョンを指定する。
$ docker run --log-driver=awslogs --log-opt awslogs-region=ap-northeast-1...
awslogs-group
オプション
Log Group を指定する。
$ docker run --log-driver=awslogs --log-opt awslogs-region=ap-northeast-1 --log-opt awslogs-group=docker-logging ...
Log Group は事前に作成しておく必要があるので注意。
awslogs-stream
オプション
Log Stream を指定する。これは必須ではない。
$ docker run --log-driver=awslogs --log-opt awslogs-region=ap-northeast-1 --log-opt awslogs-group=docker-logging --log-opt=awslogs-stream=foo ...
指定しない場合にはコンテナ ID が Log Stream 名を指定する。
Log Stream 名については以下のような注意書きがある。
Log streams within a given log group should only be used by one container at a time. Using the same log stream for multiple containers concurrently can cause reduced logging performance.
同一の Log Stream に複数のコンテナからのログを送るとログの収集パフォーマンスに影響を及ぼす...(という解釈)。
以上
疑問は...
解けました。
もう少し...
Log Driver については触れていきたいと思う。