Amazon ECSのログをEFSに保存しEC2で確認する

社内のとあるプロジェクトではAmazon ECSを使用しているのですが、アプリケーションから出力するログはDockerコンテナ内に出力されるため、Amazon EFSに保存できるか試してみました。

ログはCloudWatchにも転送しているのですが、スタックトレースが1行ごとに別のログとして扱われたりいまいち検索しづらいので、従来通りファイルとして扱えないか調べたところ、Amazon EFSに保存できそうなことがわかりました。

Amazon EFSはネットワークファイルシステムという言わばWindowsの共有ドライブのような機能で、複数のサーバーからネットワーク経由で接続することができます。そこで、ECSから出力するログをEFSに保存し、別のEC2にログインしてアクセスできるよう設定してみます。

1.セキュリティグループの作成

EFSへのアクセスのためセキュリティグループを2つ作ります。
EFSへのアクセスにはTCPポート2049(NFS)を使用するのでセキュリティグループで許可を与える必要があります。
コンテナのIPアドレスは変動するので、IPアドレスの代わりにセキュリティグループに対して許可を与えるようにします。

まず、コンテナ用のセキュリティグループを作成します。
(ここではEFSとは関係ないですが動作確認用に8080を開放しています)

次に、EFS用のセキュリティグループを作成し、コンテナ用のセキュリティグループからポート2049番へのアクセスを許可します。(ソースにコンテナ用のセキュリティグループを指定します)

2.EFSの作成

EFSを作成します。

EFSのネットワークの設定から最初に作成したEFS用のセキュリティグループを割り当てます。

3.dockerイメージの準備

docker用のイメージを用意しECRに登録します。
詳細は省略しますが、ここでは動作確認用にTypeScriptでexpressを起動し、アクセスごとにログを出力するアプリを作成します。
ログは /app/log に出力します。

########################################
#index.ts

import express from 'express'
import log4js from 'log4js';

const app = express()

log4js.configure({
appenders: {
file: { type: 'file', filename: 'log/default.log' }
},
categories: {
default: { appenders: ['file'], level: 'all' }
}
});

const logger = log4js.getLogger('default');

const router = express.Router()
router.get('/', (req: express.Request, res: express.Response) => {
logger.info("request: " + req.ip)
res.send("Hello efs-test world. " + new Date())
})
app.use(router)

logger.info("server start")

app.listen(8080)

########################################
Dockerfile

FROM node:14-alpine

WORKDIR app

RUN apk add --no-cache nodejs
ADD package.json .
RUN npm install
RUN mkdir log
ADD index.js .

CMD node index.js

4.ECSのタスクとサービスを作成

ECSのタスクを作成する際にボリュームを作成します。

コンテナを追加しストレージとログのマウントポイントを追加します。
EFSのボリュームとマウントするコンテナ内のディレクトリを指定します。

ECSのタスクにサービスを追加します。
ネットワーク構成で最初に作成したコンテナー用のセキュリティグループを割り当てます。
これにより、コンテナーからEFSにアクセスできるようになります。

なお、セキュリティグループの設定に誤りがありEFSに接続できないとタスクが停止し、タスクの停止理由には以下のようなエラーメッセージが表示されます。

Error response from daemon: create ecs-efs-test-task... : Post http://%2Frun%2Fdocker%2Fplugins%2Famazon-ecs-volume-plugin.sock/VolumeDriver.Create: context deadline exceeded

タスクが起動したらブラウザからアクセスできるか確認します。

5.EC2へのマウント

次に、EFSに出力されているはずのログをEC2から確認します。

まずはEC2にコンテナと同じようにセキュリティグループを割り当て、EFSにNFSで接続できるようにします。

AWS上のUbuntuからEFSに接続するために以下のパッケージを追加します。

sudo apt install rpcbind
sudo apt install nfs-common

EFSのURLを確認します。EFSのネットワークを開くとURLが確認できます。

EFSをマウントしログが出力されているか表示します。
マウントする際にはローカルの空のディレクトリをあらかじめ作成する必要があります。
また、URLに続けてセミコロンとディレクトリ(通常は”/”)を追加します。
アプリケーションにアクセスするたびにアクセスログが出力されれば成功です。

mkdir /opt/efs-test
mount -t nfs4 fs-00000000.efs.ap-northeast-1.amazonaws.com:/ /opt/efs-test
tail -3 /opt/efs-test/default.log

参考

チュートリアル 使用 Amazon EFS ファイル システム Amazon

関連記事

最近の記事 おすすめ記事
  1. 新人さん向けの品質についての読書会

  1. エンジニア成長への取り組み:フィードバックランチ

  2. 現役エンジニアがChatGPT、Copilotを使った所感

  3. withコロナの時代の在宅勤務

カテゴリー

アーカイブ

検索


TOP
TOP