管理人Kのひとりごと

デジモノレビューやプログラミングや写真など

docker on Lightsailで、ログをCloudWatch Logsに出力する

VPSとして、Amazon Lightsailを使ってみています。
aws.amazon.com

Lightsail上でdockerを稼働させて、各コンテナのログをCloudwatch Logsへ飛ばそうとしましたが、うまくいかなかったのでうまくいった方法を残します。

確認環境

[ec2-user@ip-172-XX-XX-XX ~]$ cat /etc/*release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
Amazon Linux release 2 (Karoo)

[ec2-user@ip-172-XX-XX-XX ~]$ docker --version
Docker version 20.10.7, build f0df350

logging設定だけではダメでした

docker-composeの定義内容

version: '3'

services:
  app:
    image: ***:latest
    tty: true
    container_name: '***'
    depends_on:
      - appdb
    logging: # ログをCloudwatch Logsへ飛ばすための定義
      driver: "awslogs"
      options:
        awslogs-region: "ap-northeast-1"
        awslogs-group: "***"
        awslogs-stream: "***"
  # appdbサービスにも同様の設定を行っています
...

実行時のエラーメッセージ

[ec2-user@ip-172-XX-XX-XX ~]$ docker-compose -f dockerfiles/docker-compose.yml up -d
Starting appdb ... error

ERROR: for appdb  Cannot start service appdb: failed to initialize logging driver: failed to create Cloudwatch log stream: AccessDeniedException: User: arn:aws:sts::XXXXXXXXXXXX:assumed-role/AmazonLightsailInstanceRole/i-XXXXXXXXXXXXXXXXX is not authorized to perform: logs:CreateLogStream on resource: arn:aws:logs:ap-northeast-1:XXXXXXXXXXXX:log-group:***:log-stream:***
        status code: 400, request id: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

ERROR: Encountered errors while bringing up the project.

LightsailはIAMやインスタンスといったAWS的な要素を意識せずに使えるサービスですので、IAMロールだとか、STSだとかがメッセージに出てきて???となりました。が、Lightsailのインスタンスに対応するEC2インスタンスに割り当てられたIAMロールには、Cloudwatch Logsに書き込むような権限はない、ということだと理解し、別の手段で対応することとしました。

参考情報を基に、dockerサービスにcredentialを渡して成功

参考とした情報

stackoverflow.com
上記URLの情報を参考に、dockerサービスにAWSのクレデンシャルを渡して、そちらを利用してCloudwatch Logsに書き込むこととしました。その結果、dockerコンテナからのCloudwatch Logsへのログ転送に成功しました。

対応内容

# 事前準備
1. Lightsail用のIAMユーザを作成し、そのユーザに以下のIAMポリシーを割り当て、credentialsを作成。
"logs:CreateLogStream",
"logs:PutLogEvents"

2. 上記IAMユーザのcredentialを作成し、Lightsailインスタンスで、「aws configure」する(awscliを導入したうえで)

3. サービス定義のファイルを編集する
[ec2-user@ip-172-XX-XX-XX ~]$ sudo systemctl edit docker

# エディタ内に以下を記載(credentialsファイルが/home/ec2-user/.aws/credentialsにある場合)
========
[Service]
Environment="AWS_SHARED_CREDENTIALS_FILE=/home/ec2-user/.aws/credentials"
========

4. サービスを再起動する
[ec2-user@ip-172-XX-XX-XX ~]$ sudo systemctl daemon-reload
[ec2-user@ip-172-XX-XX-XX ~]$ sudo systemctl restart docker