プライベートサブネットのFargateコンテナのログをCloudWatch Logsに配信する

プライベートサブネットのFargateコンテナのログをCloudWatch Logsに配信する

プライベートサブネットのECS(Fargate)コンテナのログをCloudWatch Logsに配信する

ECSタスク内で実行されているコンテナのログを収集する方法の1つに、CloudWatch Logsを使用する方法があります。

今回はCloudWatch Logsにログを配信する方法を確認します。

構築する環境

Diagram of deliver logs of Fargate containers in private subnets to CloudWatch Logs.

プライベートサブネットに、FargateタイプのECSを作成します。

CloudWatch Logsにログを配信するために、コンテナ用サブネットに、Logs用VPCエンドポイントを作成します。

DockerHubからNginxの公式イメージを取得するために、パブリックサブネットにNATゲートウェイを配置します。

EC2インスタンスを作成します。
コンテナにアクセスするためのクライアントして使用します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/065

テンプレートファイルのポイント解説

本ページはCloudWatch Logsにログを配信する方法を中心に取り上げます。

ECS(Fargate)に関する基本的な事項は、以下のページをご確認ください。

あわせて読みたい
CloudFormationでFargate入門 【CloudFormationでFargateに入門するための構成】 AWS FargateはサーバーレスでDockerコンテナを実行することができるサービスです。今回はFargate入門ということで、C...

プライベートサブネットにFargateを配置する方法については、以下のページをご確認ください。

あわせて読みたい
プライベートサブネットにECS(Fargate)を作成する 【プライベートサブネットにECS(Fargate)を作成する】 以下のページでFargateタイプのECSコンテナを作成する方法をご紹介しました。 https://awstut.com/2022/01/25/int...

CloudWatch Logs用VPCエンドポイント

Resources:
  CloudWatchLogsEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PrivateDnsEnabled: true
      SecurityGroupIds:
        - !Ref EndpointSecurityGroup2
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.logs"
      SubnetIds:
        - !Ref ContainerSubnet
      VpcEndpointType: Interface
      VpcId: !Ref VPC
Code language: YAML (yaml)

プライベートサブネットに配置されたFargateのログをCloudWatch Logsに配信するためには、CloudWatch Logs用のVPCエンドポイントを作成します。

以下が本エンドポイントに適用するセキュリティグループです。

Resources:
  EndpointSecurityGroup2:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: !Sub "${Prefix}-EndpointSecurityGroup2"
      GroupDescription: Allow HTTPS from ContainerSecurityGroup.
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: !Ref HTTPSPort
          ToPort: !Ref HTTPSPort
          SourceSecurityGroupId: !Ref ContainerSecurityGroup
Code language: YAML (yaml)

Fargateに適用したセキュリティグループを送信元として、443/tcpのインバウンド通信を許可する内容です。

CloudWatch Logsロググループ

Resources:
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "${Prefix}-LogGroup"
Code language: YAML (yaml)

シンプルにロググループを作成します。
Fargateコンテナのログを配信するために、特別な設定は不要です。

ECSタスクのログ設定

Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      ContainerDefinitions:
        - Name: !Sub "${Prefix}-container"
          Image: nginx:latest
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref LogGroup
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: !Sub "${Prefix}-container"
      Cpu: !Ref TaskCpu
      ExecutionRoleArn: !Ref FargateTaskExecutionRole
      Memory: !Ref TaskMemory
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      TaskRoleArn: !Ref TaskRole
Code language: YAML (yaml)

ポイントはLogsConfigurationプロパティです。

LogDriverプロパティでログドライバーを指定します。
ログをCloudWatch Logsに配信するためには、「awslogs」を指定します。

Optionsプロパティで配信先のCloudWatch Logsに関するパラメータを設定します。
少なくとも3つのパラメータを設定します。
1つ目はawslogs-groupで、配信先のロググループを指定します。
2つ目はawslogs-regionで、配信先のロググループが作成されているリージョンを指定します。
3つ目はawslogs-stream-prefixで、ロググループ内に作成するストリーム名のプレフィックスを指定します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • ECSクラスター:fa-065-cluster
  • ECSサービス:fa-065-service
  • CloudWatch Logsロググループ:fa-065-LogGroup
  • EC2インスタンス:i-0be518a618c126bbf

作成されたリソースをAWS Management Consoleから確認します。
まずECSクラスターを確認します。

Detail of Fargate Cluster 1.

正常にクラスターが作成され、ECSサービスが動作していることがわかります。

サービス内に作成されたタスクの詳細を確認します。

Detail of Fargate Cluster 2.

タスク内にコンテナが作成され、正常に動作していることがわかります。
またタスクにプライベートアドレスが付与されていることが確認できます。
今回付与されたアドレスは「10.0.3.77」でした。

動作確認

準備が整いましたので、EC2インスタンスにアクセスします。

% aws ssm start-session --target i-0be518a618c126bbf

Starting session with SessionId: root-0ba9574fb6aac6aaf
sh-4.2$
Code language: Bash (bash)

SSM Session Managerの詳細につきましては、以下のページをご確認ください。

あわせて読みたい
LinuxインスタンスにSSM Session Manager経由でアクセスする 【LinuxインスタンスにSSM Session Manager経由でアクセスする】 EC2インスタンスにSSM Session Manager経由でアクセスする構成を確認します。 Session Manager は完全...

curlコマンドを使って、タスク内のコンテナにアクセスします。

sh-4.2$ curl http://10.0.3.77
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Code language: Bash (bash)

正常にアクセスすることができました。

続いてCloudWatch Logsを確認します。

Detail of CloudWatch Logs 1.

正常にロググループが作成され、内部にログストリームが作成されていることがわかります。

ログストリームを確認します。

Detail of CloudWatch Logs 2.

先ほどEC2インスタンスからアクセスした際のログが書き込まれていることがわかります。
以上のことから、CloudWatch Logs用VPCエンドポイントを使用することによって、プライベートサブネットのFargateコンテナのログを、CloudWatch Logsに配信できることがわかりました。

まとめ

プライベートサブネットのFargateコンテナのログを、CloudWatch Logsに配信する方法を確認しました。