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ロールアタッチ
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ポリシーの権限追加が必要となります。
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実行時のログが出力されます。