はじめに

AWS 上に ECS を使い、Fluentd の Forwarders / Aggregators 構成を構築します。

Fluentd - High Availability Config の Network Topology にある Forwarders, Aggregators の構成と同様です。 ( Aggregators はバックアップを使用しないでアクティブを複数台用意する構成 )

AutoScaling や SpotInstance を使用するため、 Forwarders, Aggregators 共にタスク/インスタンスの入れ替えが発生します。そのため Forwarders が Aggregators を動的に見つけられる必要があります。

Load Balancer を間に入れる構成もとれますが、今回は Fluentd の Service Discovery を使って構築していきます。

この Service Discovery が今回の記事の内容となります。

その他の ECS の構築等は今回の記事には記載致しません。

構成概要

  • アプリケーションは、 ECS on EC2 にて構築
  • Fluentd の Forwarders は、 ECS のデーモンで構築 (アプリケーションと同じ Container Instance に起動する)
  • Fluentd の Aggregators は、 ECS on EC2 にて構築
  • Forwarders は、 Fluentd の Service Discovery を使って Aggregators を見つける
  • Forwarders, Aggregators は ECS Rolling Update でデプロイする

Fluentd Service Discovery

Service Discovery をみると、 static, file, srv と 3 つ種類があります。

static, file 共に、設定ファイルに Aggregators を記載する必要があるため、今回は動的に Aggregators を見つけられる srv を使用します。

srv は、 DNS の SRV Record を使った Service Discovery です。 srv を使うと以下の流れになります。

  1. DNS の SRV Record に、 Aggregators を登録する
  2. Forwarders は、 DNS に登録されている SRV Record より、 Aggregators の IP を取得してログを転送する

1 の DNS への登録は、 ECS Service Discovery を使って実現していきます。 ECS Service Discovery を使用すると、 Aggregators を起動/停止した時に自動で SRV Record の登録/削除をしてくれるようになります。

2 の機能が Fluentd の srv Service Discovery の機能になります。

構築

今回は、 Terraform で構築する流れを記載します。

ホストゾーンの作成

AWS を使用するので、 DNS には Route53 を使用します。

まず、SRV Record を作るホストゾーンを用意します。 ECS Service Discovery を使う場合は、 AWS Cloud Map を使ってホストゾーン(名前空間)を定義します。

今回は、VPC 内に構築するため、 プライベート DNS 名前空間で定義しています。

# Terraformでの例

resource "aws_service_discovery_private_dns_namespace" "fluentd_service_discovery" {
  # Service Discovery で使用するホストゾーン
  name        = "fluentd.local"
  vpc         = "Fluentdを配置するVPCのID"
}

CloudMap サービスの作成

次に、上記で作成した名前空間に Fluentd Aggregators 用 CloudMap サービスを作成します。

CloudMap サービスには、 DNS に登録するレコードの定義をします。

今回は、 SRV Record を使用するので、 SRV Record の定義をします。

ヘルスチェックも定義できるのですが、今回はプライベート DNS のため不要となります。

また、今回は ECS を使用しているのでコンテナのヘルスチェックおよびタスクの状態より CloudMap が正常性を判断してくれます。 (異常と判断されたタスクは SRV Record から除外される)

# Terraformでの例

resource "aws_service_discovery_service" "fluentd_service_discovery" {

  name = "_fluentd-aggregators._tcp"

  dns_config {
    # 上記で作成した名前空間のid
    namespace_id = aws_service_discovery_private_dns_namespace.fluentd_service_discovery.id

    dns_records {
      ttl  = 10
      type = "SRV"
    }

    routing_policy = "MULTIVALUE"
  }
}
  • name: DNS のレコード名を指定 (SRV Record)
    _${サービス名}._${プロトコル} で指定します。
    プロトコルは、Fluentd が TCP で通信するため tcp を指定しています。
    サービス名、プロトコルの前には、 アンダースコア をつけます。SRV Record を参照
  • routing_policy の MULTIVALUE: Fluentd Aggregators を複数台起動するので複数定義できるように設定

Fluentd Aggregators の ECS サービス

Fluentd Aggregators の ECS サービスに ECS Service Discovery の設定をします。初回構築時に設定する必要があります。

この設定を入れることで SRV Record の自動登録が有効化されます。

# Terraformでの例 (ECS Service Discovery以外の箇所は割愛します)

resource "aws_ecs_service" "fluentd_aggregators" {

  〜

  "service_registries" {
    # 上記で作成したサービスのARN
    registry_arn   = aws_service_discovery_service.fluentd_service_discovery.arn
    container_name = "fluentd-aggregator"
    container_port = 24224
  }

  〜
}
  • container_name: Fluentd Aggregators のタスク定義に定義したコンテナの名称を指定
  • container_port: Fluentd Aggregators が通信に使用するポートを指定

ここまでで Fluentd Aggregators に必要な ECS Service Discovery の設定を完了です。

実際に構築した後、 Route53 / CloudMap / ECS コンソールのそれぞれで SRV Record の設定が確認できます。

Fluentd Forwarders の設定

Fluentd の Service Discovery を有効化します。

以下の設定を入れることで Service Discovery が有効化されます。

<match "**">
  @type forward
  〜
  <service_discovery>
    @type srv
    service fluentd-aggregators
    proto tcp
    hostname fluentd.local
    interval 20s
  </service_discovery>
  〜
</match>
  • service: CloudMap サービスに指定したサービス名を指定
  • proto: CloudMap サービスに指定したプロトコルを指定
  • hostname: 作成したホストゾーンを指定

CloudMap サービスに指定したアンダースコアは、Fluentd が自動で付与してくれるようになっています。 参考

Forwarders の設定は以上となります。

Aggregators の起動後に、Forwarders を起動すると以下のログが出力され Aggregators と接続できているのが確認できます。

# Aggregatorsが接続先に繋がったログの例
2021-0x-0x xx:xx:xx +0000 [info]: adding forwarding server 'zf36d70f71fx4e8d86c0a1b9dc296cf8._fluentd-aggregators._tcp.fluentd.local' host="${IPアドレス}" port=24224 weight=1 plugin_id="object:xxxxxx"

Aggregators デプロイ時の考慮事項

Aggregators デプロイ時に Forwarders から Aggregators が見えなくなると転送が一時的に停止してしまいます。(リトライが発生する)

以下の点を考慮するとリトライを 0 に近づけられます。

  • Aggregators の ECS RollingUpdate を 1 台ずつ置き換えるようにする (1 台でなくても良いが、一度に全台を置き換えない)
  • SRV Record の TTL を短くする
  • Forwarders の以下の設定を調整する
<match "**">
  @type forward
  〜
  hard_timeout 20s # 調整対象
  connect_timeout 20s # 調整対象
  ack_response_timeout 21s # 調整対象
  <service_discovery>
    @type srv
    〜
    interval 20s # 調整対象
  </service_discovery>
  〜
</match>

まとめ

Service Discovery を使った Fluentd Forwarders / Aggregators の構築を記載しました。

Load Balancer (ALB, NLB 等) を不要にできるのはメリットの 1 つになるのではないでしょうか。

Service Discovery は、マイクロサービス構築等にも使える機能なので用途は色々とあります!

最後まで読んで頂きありがとうございました!