Anycastでレイテンシの課題を解決する
DNSやグローバルに分散されたアプリのような高トラフィックなサービスは、最終的に「光の速度」という物理的な限界に突き当たります。データベースをどれだけ最適化しても、シンガポールのユーザーがニューヨークのサーバーに接続する場合、少なくとも200〜250msのレイテンシが発生します。標準的なユニキャストルーティング(Unicast routing)は、トラフィックを特定の1つの宛先に送信します。ロードバランサーも役立ちますが、多くの場合、単一のデータセンターやリージョン内に限定されます。
Anycastは、この「道路のルール」を書き換えます。BGP(Border Gateway Protocol)を介して, 複数の地理的拠点から同じIPアドレスを広報(advertise)することで、インターネットの基幹インフラが自動的にユーザーを「最も近い」正常なノードにルーティングします。
私はこのアーキテクチャを本番環境に導入し、以前は単一リージョンの入り口を圧倒していたリージョンごとのトラフィック急増に対処してきました。ノードが故障すると、BGPは数秒以内にルートを撤回し、トラフィックはシームレスに次に最適なサイトへと移行します。これは設計レベルで自己修復機能を備えています。
今回はFRRouting(FRR)を使用して、Linux上にAnycast IPをセットアップします。このシナリオでは、2台のサーバーが1つのIPを共有し、従来のDNSベースのフェイルオーバーよりも高速に反応する高可用性サービスを提供します。
「近接性」のアーキテクチャ
ターミナルを操作する前に、設計図を確認しましょう。標準的なセットアップでは、各サーバーは固有のIPを持ちます。Anycastでは、すべてのノードのダミーインターフェースに共有の「Anycast IP」を割り当てます。そして、各サーバーが上位のルーターに対して、自分がそのIPの正当な所有者であることを伝えます。
なぜGSLB(Global Server Load Balancer)ではなく、これを選ぶのでしょうか?
- 1秒未満のフェイルオーバー: BGPの収束は、世界中に浸透するのに数分かかることもあるDNSのTTL更新よりも高速であることが多いです.
- 1つのIPですべてを管理: クライアントは、1つの宛先だけをホワイトリストに登録または設定すれば済みます。
- 自然なDDoS吸収: 攻撃トラフィックは、1つの回線に集中するのではなく、グローバルな拠点全体に分散されます。
AnycastはDNSのようなUDPベースのサービスにとってゴールドスタンダードです。BGPルーティングが安定していれば、TCP(HTTP/HTTPS)でも機能します。ルートが頻繁に「フラッピング(flap)」すると、同じセッションのパケットが異なるサーバーに到達する可能性があるため、TCPセッションが切断されます。
インストール:FRRoutingのセットアップ
LinuxでのBGPには、FRRouting(FRR)が業界標準です。これはQuaggaのハイパフォーマンスなフォークであり、CiscoやJuniperの機器を使用したことがある人なら馴染みのあるCLIを備えています。この例ではUbuntu 22.04を使用しますが、論理は現代のあらゆるディストリビューションに適用可能です。
FRRのリポジトリとパッケージをインストールします:
# FRRのGPGキーとリポジトリを追加
curl -s https://deb.frrouting.org/frr/keys.asc | sudo apt-key add -
FRRVER="frr-stable"
echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) $FRRVER | sudo tee /etc/apt/sources.list.d/frr.list
# アップデートとインストール
sudo apt update
sudo apt install frr frr-pythontools
FRRはモジュール形式のデーモンシステムを実行します。手動でBGPのスイッチをオンにする必要があります。
# BGPデーモンを有効化
sudo sed -i 's/bgpd=no/bgpd=yes/' /etc/frr/daemons
sudo systemctl restart frr
設定:BGPを活用する
設定は、LinuxのネットワークスタックとFRRルーティングエンジンの2つのレイヤーにわたります。
1. ダミーインターフェース
Anycast IPを保持するための仮想インターフェースが必要です。物理インターフェース(eth0など)の使用を避けるのは、ローカルサービスが失敗した場合に、サーバーの管理用接続を切断することなくAnycast IPを「隠す」ことができるようにするためです。
# 'anycast0'という名前のダミーインターフェースを作成
sudo ip link add anycast0 type dummy
sudo ip link set anycast0 up
# Anycast IPを割り当て (例: 192.0.2.100)
sudo ip addr add 192.0.2.100/32 dev anycast0
2. vtysh経由のBGPピアリング
次に、このIPを世界中に広報するようFRRに指示します。統合シェルであるvtyshを使用します。自律システム番号(ASN)と上位ピア(peer)のIPが必要です。
sudo vtysh
configure terminal
# 65001を自分のASNに置き換え
router bgp 65001
bgp router-id 1.1.1.1
# 上位のネイバー (例: ISPまたはToRスイッチ)
neighbor 203.0.113.1 remote-as 65000
neighbor 203.0.113.1 description Upstream_Transit
address-family ipv4 unicast
# 特定のAnycast IPを広報
network 192.0.2.100/32
neighbor 203.0.113.1 activate
exit-address-family
exit
write memory
3. 「ブラックホール」を回避する
私が苦労して学んだ教訓はこれです。NginxやBINDサービスがクラッシュしてもサーバーが稼働し続けている場合、BGPは世界中にトラフィックを送信し続けるように伝え続けます。これにより「ブラックホール」が発生します。BGPの広報をサービスの健全性(ヘルスチェック)に関連付ける必要があります。
シンプルなBashスクリプトでアプリケーションを監視し、curl -s localhostが失敗した場合にはanycast0インターフェースをダウンさせることができます。インターフェースがダウンすると、FRRはルートの広報を停止し、インターネットは数秒以内に自動的に他のノードへトラフィックをリダイレクトします。
検証:動作の確認
vtysh内からルートの伝播を確認します:
show ip bgp summary
show ip bgp 192.0.2.100/32
ステータスコード *> が表示されれば成功です。これは有効で最適なパス(best-path)であることを確認するものです。しかし、ローカルの出力だけを信じてはいけません。真のAnycastの挙動を検証するには、世界各地のVPSからRIPE Atlasやmtrなどのツールを使用します。
# リモートクライアントから実行
mtr -rw 192.0.2.100
ロンドンからはサーバーAに、東京からはサーバーBに到達していることが確認できれば、セットアップは完了です。本番環境の安定稼働のために、frr_exporterを使用してPrometheus経由でこれらのBGPセッションを監視することは必須です。かつてAnycastは巨大企業のためのツールでしたが、現代のLinuxを使えば、ASNを持つあらゆるチームがグローバルで回復力の高いネットワークを構築できます。

