もう20年ほど前になると思うけれど、親会社の作った大規模システムの顧客への導入に携わったことがあった。
なんせ当時の新技術に次ぐ新技術で構築されたそのシステムは、客先によって導入日を前倒しされ、新技術×短納期という最悪の組み合わせから無事大炎上したのであった。
さて、そのシステムに関係するほとんどの疑問は、その後月日を重ねることで理解に変わっていったのだけれど、1つだけどうしても解けない謎が残った。
クラスタリングという技術がある。この技術は、複数のサーバによって1つ以上のサービスを提供する技術だ。1つのサービスを2つのサーバどちらかで提供したり、2つのサービスを2つのサーバどちらかで提供したりする。早い話「1台以上のサーバが停止しても、残りのサーバでサービスを継続する」という仕組みだ。これは「サービスに紐づいたIPアドレス」を提供することで実装できる。クレジットの問い合わせしたければ「特定のIP」に問い合わせればよく、そのIPは現在サービスが動作しているサーバに付加されていればよいのだ。
サーバ台数M台に対して、サービスとサービスに紐づくIPアドレスがN個あり、サーバの生き死ににかかわらずサービスN個が提供し続けられるような設計。これがクラスタリングなのだ。
さて、長年の疑問はここからだ。なぜか「NTP」だけはサービスに紐づくIPアドレスではなく、サーバに常に付与されているIPアドレスに問い合わせるような設定を行えという指示があったのだ。
20年前なので、今となってはレガシーなFTP、HTTPとソケット通信あたりを使用してサービスを提供していたシステムであるが、なぜか「NTP」だけはサーバのIPアドレスに問い合わせる必要があった。当時SEや開発者にも聞いて回ったのだけれど、この理由がわからなかった、そしてわからないまま20年が経過したのであった。
先日、このことを思い出してClaudeさんに、「なぜクラスタリングでNTPだけがサーバのIP問い合わせだったのか」を質問してみた。
クラスタリング環境にて、仮想IPアドレスを使用したい場合、一般的にIPエイリアスが使用されると思います。今はどうかわかりませんが、Linux環境でクラスタリングソフトを使用した際に、TCPは問題なくクラスタ環境と接続できるのですが、UDPではできないので、UDP使う場合は実IPでと言われたことがありました。具体的には時刻合わせのプロトコルであるNTPです。 このようなことがあり得るでしょうか?
回答
はい、十分にあり得る話です。これは「クラスタソフトの実装がおかしい」というより、TCPとUDPのプロトコル的な性質の違いに起因する、よく知られた現象です。 核心:ソケットの「ローカルアドレスの確定タイミング」の違い TCPの場合 クライアントが仮想IP(VIP)宛にSYNを送ると、サーバ側でacceptしたコネクションは、そのSYNの宛先アドレス(=VIP)を自分のローカルアドレスとして「確定」します。以降そのコネクション上でやり取りされるパケットは、OSのルーティングテーブルの都合とは無関係に、必ずそのVIPを送信元IPとして使います。これはTCP/IPスタックのコネクション管理の仕組み上、保証された動作です。 UDPの場合 UDPはコネクションレスなので、この「確定」が自動的には起きません。サーバプロセスがrecvfrom()で受信してsendto()で返信する、という素朴な実装をしていると、返信パケットの送信元IPは「宛先IPへの経路を引いたときの、そのインタフェースのプリファードソースアドレス(多くの場合プライマリIP)」がカーネルによって選ばれてしまうことがあります。つまり、届いたパケットの宛先がVIPだったにもかかわらず、返信は実IPから出てしまう、ということが起こり得ます。 NTPで問題になりやすい理由 NTPクライアントは、問い合わせを送った宛先IPと、応答パケットの送信元IPが一致することを前提にした実装が多いです(そうでないとスプーフィング対策上も都合が悪い)。なので、 クライアント → VIP宛にNTPリクエスト サーバ側UDPソケットがワイルドカード(0.0.0.0)バインドで受信 返信の送信元IPがカーネルの経路選択でVIPではなく実IPになる クライアントが「問い合わせ先と送信元が違う」として応答を破棄(あるいはそもそも到達しても無視) という流れで、TCPでは問題なくUDP(NTP)だけ通らない、という現象が説明できます。 (以下略)
要はUDP+仮想IPだったので、アプリの実装によっては「時刻を問い合わせたIP以外から時刻応答が返ってくる」ことになってしまっていたわけだ。そして、最近のNTPの実装「Chrony」などではこの問題が発生しにくくなっているらしい。
長年の疑問は氷解したのであった。なので、昔から何となく疑問に思っていて、回答の出ていないことがあれば、いったんAIに聞いてみるのもよいかもしれない。少なくとも私は嬉しかったよというほのぼのしたBlogになったのであった。