DockerのログをS3バケットにアップロードする

EC2上で動作するDockerコンテナから出力されたログをS3バケットにアップロードすることが出来ましたので、備忘録として残したいと思います。

ここでの操作を行う前に、作業を行うサーバまたはPCにAWSCLIとjqコマンドがインストールされている事を確認します。まだインストールされていない場合はインストールします。

Dockerからのログは以下のように流れていくので、各サービスで設定を行います

[Docker]→[EC2]→[Cloud Watch Logs]→[Kinesis Data Firehose]→[S3]

1、CloudWatchLogsに書き込み権限のあるIAMロールの作成


Dockeが動作しているEC2インスタンスがCloudWatchLogsにログを書き込めるようにするため、ロールを作成します。

既にEC2にIAMロールがアタッチされている場合は、「1、」の操作を行わずにアタッチされたロールにCloudWatchLogs書き込み許可用のポリシーをアタッチします。

ここに記載したコマンドは、Linuxコンソールで実行してください。また、全て同じコンソール画面で実行してください。(別ウィンドウを開くと環境変数の再設定とかめんどくさいので)

1-1、ロール、ポリシー名の設定

以下のコマンドを実行してロール、ポリシー名を設定します。

<hogehoge>部分を任意の名前に変更します。

IAM_ROLE_NAME="hogehoge"
INLINE_POLICIE_NAME="hogehoge"

1-2、IAMロールの作成

以下のコマンドを実行し、IAMロールを作成します。

role_arn_id=`aws iam create-role \
 --role-name ${IAM_ROLE_NAME} \
 --assume-role-policy-document '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
         "Service": "ec2.amazonaws.com"
       },
      "Action": "sts:AssumeRole"
    }
  ]
}' | jq -r '.Role | .Arn'`

1-3、ポリシーの作成とポリシーアタッチ

以下のコマンドを実行し、ポリシーを作成してロールにアタッチします。

policy_arn_id=`aws iam create-policy \
 --policy-name ${INLINE_POLICIE_NAME} \
 --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}' | jq -r '.Policy | .Arn'`

#ポリシーアタッチ
aws iam attach-role-policy \
 --policy-arn ${policy_arn_id} \
 --role-name ${IAM_ROLE_NAME}

1-4、インスタンスプロファイルの設定

以下のコマンドを実行し、インスタンスプロファイルの作成、インスタンスプロファイルへロールの登録を行います。

aws iam create-instance-profile \
 --instance-profile-name ${IAM_ROLE_NAME}

aws iam add-role-to-instance-profile \
 --role-name ${IAM_ROLE_NAME} \
 --instance-profile-name ${IAM_ROLE_NAME}

2、EC2へのIAMロールアタッチ


手順参照:Amazon Web Services ブログ

2-1、EC2へロールのアタッチ

「1、」で作成したIAMロールをDockerを動作させるEC2にアタッチします。

aws ec2 associate-iam-instance-profile \
 --instance-id <対象サーバのインスタンスID> \
 --iam-instance-profile Name=${IAM_ROLE_NAME}

2-2、アタッチの確認

正常にEC2へアタッチされたか確認します。

aws ec2 describe-iam-instance-profile-associations

3、CloudWatchロググループ作成


3-1、ロググループ作成

以下のコマンドを実行して、Dockerコンテナのログが出力されるCloudWatchロググループを作成します。

LOG_GROUP_NAME="hogehoge"

aws logs create-log-group \
 --log-group-name ${LOG_GROUP_NAME}

3-2、ロググループ作成確認

以下のコマンドを実行して、ロググループが作成されたことを確認します。

aws logs describe-log-groups \
 --log-group-name-prefix ${LOG_GROUP_NAME}

4、Dockerのログ出力先設定


S3へログ出力するDockerコンテナの設定を変更します。

この手順では、Docker-composeファイルにログ出力用の設定を追加する方法で行います。

Docker-composeファイルの対象コンテナ部分に以下の記述を追加します。

※「1、」で設定したIAMロールの適用に時間がかかる場合がある為、ロールアタッチ後、5分間待機してから実行する。

#docker-compose.yml
version: '2'
services:
  サービス名:
      image: イメージ名
      container_name: コンテナ名
      volumes:
        - ボリューム設定
      ports:
        - ポート設定
      restart: always
以降を記述する============================
      logging:
        driver: "awslogs"
        options:
          awslogs-region: "リージョン識別子"
          awslogs-group: "ロググループ名(「3、」で設定した名前)"
          awslogs-stream: "ログストリーム名(任意)"
===================================

5、Kinesis Data Firehoseの設定


5-1、Firehose用ロールの作成

以下のコマンドを実行して必要Firehose用のロールを作成します。ロール名・ポリシー名は任意です。

5-1-1、ロール、ポリシー名の設定

以下のコマンドを実行して、ロール、ポリシー名を設定します。

IAM_ROLE_NAME="KinesisFirehoseServiceRole-hogehoge"
INLINE_POLICIE_NAME="KinesisFirehoseServicePolicy-hogehoge"

5-1-2、IAMロールの作成

以下のコマンドを実行し、IAMロールを作成します。

FIREHOSE_ROLE_ARN=`aws iam create-role \
 --role-name ${IAM_ROLE_NAME} \
 --assume-role-policy-document '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
         "Service": "firehose.amazonaws.com"
       },
      "Action": "sts:AssumeRole"
    }
  ]
}' | jq -r '.Role | .Arn'`

5-1-3、ポリシーの作成とポリシーアタッチ

今回は最小構成用のポリシーを作成していますが、Firehoseの追加オプションを指定した場合は、ポリシーの変更が必要です。

policy_arn_id=`aws iam create-policy \
 --policy-name ${INLINE_POLICIE_NAME} \
 --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject"
            ],
            "Resource": "*"
        }
    ]
}' | jq -r '.Policy | .Arn'`


#ポリシーアタッチ
aws iam attach-role-policy \
 --policy-arn ${policy_arn_id} \
 --role-name ${IAM_ROLE_NAME}

5-2、ログ保存用S3バケットの作成

以下のコマンドを使用して、ログ保存用のS3バケットを作成します。

S3_BUCKET_NAME="hogehoge"
aws s3 mb s3://$S3_BUCKET_NAME
aws s3 ls | grep $S3_BUCKET_NAME

5-3、Firehoseの作成

5-3-1、構成ファイルの作成

この設定は基本構成となります。設定オプションの詳細については以下を参照してください。また、ここで指定するオプションによってはIAMポリシーの権限追加が必要となります。

create-delivery-stream

S3_PREFIX="Firehose/"
cat <<EOF > s3_destination_configuration
{
    "DeliveryStreamName": "hogehoge",
    "S3DestinationConfiguration": {
        "RoleARN": "$FIREHOSE_ROLE_ARN",
        "BucketARN": "arn:aws:s3:::${S3_BUCKET_NAME}",
        "Prefix": "${S3_PREFIX}",
        "BufferingHints": {
            "SizeInMBs": 1,
            "IntervalInSeconds": 60
        },
        "CompressionFormat": "GZIP",
        "EncryptionConfiguration": {
            "NoEncryptionConfig": "NoEncryption"
        }
    }
}
EOF

5-3-2、Firehoseの作成

FIREHOSE_ARN=`aws firehose create-delivery-stream \
 --cli-input-json file://s3_destination_configuration | jq -r '.DeliveryStreamARN'`

6、CWL サブスクリプションの作成


CloudWatch Logs サブスクリプションを設定すると、ログ出力時に自動でサブスクリプション先のサービスを起動します。

今回はCloudWatch Logsにログが出力されるとKinesis Data Firehoseが自動で動作します。

6-1、CWL サブスクリプション用ロールの作成

6-1-1、ロール、ポリシー名の設定

以下のコマンドを実行して、ロール、ポリシー名を設定します。

IAM_ROLE_NAME="CWLSubscriptionRole-hogehoge"
INLINE_POLICIE_NAME="CWLSubscriptionPolicy-hogehoge"

6-1-2、IAMロールの作成

以下のコマンドを実行して、CloudWatchログサブスクリプションにアタッチするロールを作成します。

CWLS_ROLE_ARN=role_arn_id=`aws iam create-role \
 --role-name ${IAM_ROLE_NAME} \
 --assume-role-policy-document '{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
         "Service": "logs.amazonaws.com"
       },
      "Action": "sts:AssumeRole"
    }
  ]
}' | jq -r '.Role | .Arn'`

6-1-3、ポリシーの作成とポリシーアタッチ

以下のコマンドを実行して、ポリシーを作成し、ロールへアタッチします。

policy_arn_id=`aws iam create-policy \
 --policy-name ${INLINE_POLICIE_NAME} \
 --policy-document '{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "firehose:PutRecord",
                "firehose:PutRecordBatch"
            ],
            "Resource": "*"
        }
    ]
}' | jq -r '.Policy | .Arn'`

#ポリシーアタッチ
aws iam attach-role-policy \
 --policy-arn ${policy_arn_id} \
 --role-name ${IAM_ROLE_NAME}

6-2、CWL サブスクリプションの作成

以下のコマンドを実行し、CWL サブスクリプションを作成します。

filter_name="subscription"
aws logs put-subscription-filter \
 --log-group-name ${LOG_GROUP_NAME} \
 --filter-name ${filter_name} \
 --filter-pattern "" \
 --destination-arn ${FIREHOSE_ARN} \
 --role-arn ${CWLS_ROLE_ARN}

以上の設定を行うと項目「5-2」で作成したS3バケットにDocker実行時のログが出力されます。

参考資料

docker-composeのログを雑にCloudWatchに投げつける

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)