Edited at

NLBでfluentdのforwardパケットを分散させてみた

More than 1 year has passed since last update.

AWSの新しいロードバランサであるNLB(Network Load Balancer)を使ってfluentdのforwardパケットを分散してみたので、レポートをまとめておく。

NLB自体については、クラスメソッドのブログ等で紹介されているのでそちらを参照するのが分かり易い。

静的なIPを持つロードバランサーNetwork Load Balancer(NLB)が発表されました!

試してわかった NLB の細かいお作法

ざっくり言うと、TCPプロトコルを対象にしたALBって感じ。

ターゲットグループはポートレベルで設定できるので、コンテナ環境と相性が良い。

ポート違いで複数fluentdが立っていても同じグループとしてまとめて分散できる。


利用までの流れ


  1. ターゲットグループを作成し、TCPレベルでコネクションが貼れるかのヘルスチェックの設定をする

  2. インスタンスもしくは対象IPと、ポートの組をターゲットグループに登録する

  3. NLBを作成し対象となるAZを設定、リスナーポートとターゲットグループを紐付ける

  4. DNSを登録してそのDNS向けにforwardパケットを流す様にする


fluentdで利用する場合

普通、fluentdのforwardパケットはクローズドなネットワークを流れるので、internal NLBとして作成した。

この時、NLBはEIPを紐付けられる様になっているので、必要があればEIPを準備する。その場合AZ毎に必要になる。後からの変更はできないらしい。

EIPを紐付けない場合は自動でプライベートIPが採番される。

ヘルスチェックパケットは、NLBのIPからやってくる。

NLBはセキュリティグループを持つことができないので、ヘルスチェックを通過するにはノード側のセキュリティグループでNLBのIPから対象ポートへの通信を許可する必要がある。

VPCのレベルで通信を許可して問題になることはあんまり無さそうなので、VPCのCIDRレベルで通信を許可しておくのが楽だろう。

エントリポイントとしてDNS名が自動で生成されるので、そこかもしくはEIPを対象にしたDNSのレコードを作っておく。

どうもALIASレコードには対応していない様なので、NLBのDNS名を登録する場合はCNAMEレコードになる。

一回作ろうとして失敗した記憶があるんですが、さっき試してみたらALIASレコード作れました。


実際に通信する時の動きについて

forwardの送信元になるノードはNLBのIPに対してTCP接続している様に見える。

forwardを受信するノードは送信元のノードのIPからTCP接続されている様に見える。

コネクションは長時間に渡って維持できるので、どちらかの要求で再接続されない限りは同じコネクションをずっと使い回すことができる。

動作を見るにProxyはせずに、IPの送信先だけを書き換えてパケットフローをコントロールしているっぽい。

しかし、これでは送信側と受信側でIPが噛み合わないので、戻りパケットがどうやって戻ってきているのか良く分からん。

送信側と受信側でtcpdumpを使ってパケットをキャプチャした結果、送信側はNLBとやり取りしている様に見えてるし、受信側は各個別のノード宛にパケットを送っている。

受信側のルーティングテーブルを弄ることなく繋がっているので、VPC内のスイッチで何らかの魔法が行われていないと戻りパケットがNLBに戻らないと思うのだが、この理解で合ってんのかな。

まあ、VPCとはいえ内部では色々とスイッチレイヤーを経てインスタンス同士が通信しているだろうし、そういう事は出来そうだけどちょっと気持ち悪いw


health checkについて

NLBからのhealth checkはTCPで疎通できれば通過するので、実際にfowardパケットが届くかどうかまでは分からない。

out_forwardプラグインのhealth checkは0.14系からはtransportモードがデフォルトになっていて実際に通信を行うコネクションをそのまま利用してheartbeatを送っている。

デフォルトだと基本的にはTCPのコネクションをそのまま利用するはずなので、ちゃんとheartbeatの疎通が通る。

もしノードが死んだ場合、即座にheartbeatパケットが反応してconnectionが切断される。(この辺からもTCPレベルでは直結してる様に見える)

再接続する際は、実際にout_forwardのheartbeatパケットが届く所に対して接続されるので、すぐに生きてるノードに対してのコネクションが復活する。

LBを噛ました時の動作としては望ましい感じがする。


パフォーマンスについて

今のところ最大で40Mbpsぐらいの流量でパケットを受け取っている。

すごい大規模なサービスではないので、そんなに大した量ではない。

アクティブなコネクション数は、2箇所のAZを合計して200前後。

LBのCapacityUnitは大体0.3ぐらいを推移している。

パケットの分散具合も安定している。

当分は使っていけそう。

面倒だったので実際のレイテンシまでは測定してない。まあうちぐらいだと問題になることは無さそう。

弊社の流量では限界があるので、もっと大規模なトラフィックが流れている環境でのレポートがあると良さそう。