mixi engineer blog

*** 引っ越しました。最新の情報はこちら → https://medium.com/mixi-developers *** ミクシィ・グループで、実際に開発に携わっているエンジニア達が執筆している公式ブログです。様々なサービスの開発や運用を行っていく際に得た技術情報から採用情報まで、有益な情報を幅広く取り扱っています。

BFDをサーバで実装してみた話

※こちらの記事は過去のブログから転載したものです。

XFLAG™ スタジオの吉野です。普段は、ネットワークの設計・調達・構築・運用、インフラに関連したちょっとした開発やバックオフィス業務をしています。前回は、拠点冗長した話をさせていただきましたが、今回は、BFDをサーバで実装してみた話を書こうと思います。

 

システムを組むときは迂回手段や正常性確認手段を考えながら組んでいくと思います。サーバでのパケット処理基盤を作る上で、ネットワーク機器と協働しながらどのように上記手段を実装し安定したものにするかを考えた結果、サーバでのBFDの活用を実装してみました。

 

ToRまでレイヤ3で組む構成が流行っているかと思います。サーバのNICまでをレイヤ3で運用し、NICに入ってくるパケットを処理するプログラムが正常な時のみ、ネットワークからパケットが流入するような設計をしています。バージョンアップ等の作業も考慮し、GracefulなShutdownも可能にしています。

BFDとはなんなのか

BFDはBidirectional Forwarding Detectionの略です。これは1対1での正常性をチェックするプロトコルです。

 

ルーティングプロトコル等での処理は障害切り替わりのタイマーが数十秒と長いものが一般的なのに対して、CPUからハードウエアにオフロードしやすいプロトコルとして分離し、短い間隔(数百ミリ秒等)での切り替わりを可能にする技術です。RFCは、5880や5881、そこから関連するものや更新するものがいろいろ出ています。

 

ざっくり書くと以下のような挙動をするシンプルなプロトコルです。

  • パケットを送り、ネゴシエーションする
  • 相互に送りあって、設定した回数だけ応答がないと落ちたとみなす
  • IPでのBFDの場合にはUDPを送り合う

自前のパケット処理するコードやアプリにBFDの機能を埋め込むと切り替え速度が大幅に向上させることができると期待できます。

ネットワーク全体の中でどう切り替わるのか

現在検証中の構成を下記の図で説明します。

f:id:mixi_PR:20210202184927j:plain

 

図中のアドレスの用途を説明していきます。

  • 203.0.113.0/24 サービスなトラフィックが流れるアドレス帯
  • 198.51.100.0/24 BGPのプロトコル上のnext hopアドレス
  • 192.0.2.0/24 ネットワーク機器とサーバが繋がり、BFDを話すアドレス(2つセグメントを書きたいために/25で分割しています)

ここからは各プロトコルの連携を説明します。ネットワーク機器は、OSPFとiBGPで経路を交換している。また、OSPFではstaticの経路をredistributeしている。BGPのprotocol next hopは再帰的にstaticの経路を使って解決されて、next hopにパケットを転送します。ポイントは、BFDがupではないときは再帰的解決が不可能になり、その経路は使われないことです。データベース等に入った情報をもとに、BGPの経路を生成するデーモンからネットワーク機器に経路を送ることで、全体としてパケットフォワーディングされるようになります。

 

この構成のメリットは以下のように考えています。

  • BGPの経路情報には変動をなくすことができる
  • staticとBGPでは、staticの方がプロトコルとして優先度が高いために、staticのみで実装すると迂回できないパターンが発生する
  • パケット処理に必要な情報のロードが終わるまではBFDの応答をしないことで無駄に吸い込む事を抑制できる
  • BFDの応答を止めた後に迂回完了までに入ってきたパケットも継続的に処理すればGracefulなShutdownができる

BFDの実装について

基本的にはRFCに沿って実装すればOKです。注意する点は、以下の点です。

  • IP TTLを255にする必要がある。
  • ソースポートに制限がある 。(49152 から65535)
  • IPv4チェックサムは正しい必要がある。

楽をする手段として、IPv4チェックサムの再計算をサボる方法があります。IPv4チェックサムの計算は、送信IPと受信IPを入れ替えても、他のフィールドが変わらなければ値が変わりません。また、今回試した相互接続確認で、UDPチェックサムも0としても受信してくれる実装もありました。

 

これを活用するとnetmap等のLinuxプロトコルスタックを通さない開発を行う場合に楽ができます。

  • Etherのsrc/dstを入れ替える。
  • IPのsrc/dstを入れ替える。
  • UDPチェックサムを0にする。
  • BFDのペイロードを自分のコンテキストに合わせて変更して送り返す。

サンプルコードはこちら https://github.com/xflagstudio/network-bfd-sample にあります。Juniper Networks社の機器でBFDがUPすることを確認しています。RFCを忠実に実装したものではありません。

まとめ

今回は、BFDを実装し、サーバまでをL3での経路制御にする方法を紹介しました。XFLAG™ スタジオでは、様々なポジションで積極採用中ですが、こういったコードを開発したい人やこの基盤のマネージメントツールを書きたい人も歓迎しています。

━・ネットワーク・プログラマー採用中!・━
https://career.xflag.com/career/engineer/872/
https://www.wantedly.com/projects/93043
━━━━━━━━━━━━━━━━━━━━━