ECSのawsvpcモードではログドライバにサイドカーコンテナを指定できない

下記の構成でサービスを構築したところ,ログが転送されなかった

  • タスク定義のネットワークモードをawsvpcにする
  • fluentdをサイドカーコンテナにする
  • コンテナのログドライバを127.0.0.1:24224に指定する

起動順がおかしいのかと思い,docker-composeで同様の例を作った

github.com

が,こちらは動く上にfluentd-async-connectを外してみると起動順によるエラーが発生するので,原因は起動順でもなさそうという感じになる.

fluentd-max-retriesの数を増やしたりしてもダメで,/var/log/dockerを見に行くとこんなエラーを発見.

time="2019-01-04T12:56:45.789694666Z" level=error msg="Failed to log msg \"\" for logger fluentd: fluent#send: can't send logs, client is reconnecting"

ログを追加するたびに上のエラーが流れるので,やっぱりlocalhostに繋げられてないことがわかる.

以上のことをAWSのサポートに聞いてみたところ,以下の回答をもらった.

  • awsvpcモードではタスクにENIを付与する
  • ログドライバはタスクではなくdockerデーモンの動作となり,コンテナインスタンス本来のENIを使う
  • そのためログドライバはタスクのENIに対して通信を行わず,ログが転送されない

つまりfluentdは関係なく,awsvpcモードでのログドライバ全般で起こりうることだということ.

回避策として,fluentdコンテナをawsvpcモードのサイドカーではなく,インスタンスごとに立ててネットワークモードをhostモードにするという方法を教えてもらった.

各ホストに1つだけコンテナを配置するという構成を取る場合,サービスタイプにDAEMONタイプを指定するのが便利だということも教えてもらった.

fluentdコンテナの数が減り,無駄なリソースも削減できるのもポイント.

dev.classmethod.jp

awsvpcモードにおいてログドライバ全般で転送先にサイドカーはやめようという話だった.

というわけで,動作するタスク定義(一部)は以下.

ログをfluentdに送りたいコンテナのタスク定義

"logConfiguration": {
    "logDriver": "fluentd",
    "options": {
        "fluentd-async-connect": "true",
        "fluentd-address": "127.0.0.1:24224",
        "fluentd-max-retries": "30",
    }
},
"networkMode": "awsvpc",

fluentdコンテナのタスク定義

"portMappings": [
    {
        "hostPort": 24224,
        "protocol": "tcp",
        "containerPort": 24224
    }
],
"networkMode": "host",