11. 回避すべき既知の落とし穴
システムの再起動後に haproxy サービスが起動せず、手動で起動すると動く、という報告をときどき受けます。多くの場合、keepalived などのクラスター IP アドレス管理機構を使い、マスターノードだけにサービスの IP アドレスを割り当てています。haproxy を 0.0.0.0 にバインドしていたときは動作していたものが、仮想 IP アドレスにバインドするように変更すると動かなくなります。これは、サービスの起動時点ではローカルノードが仮想 IP アドレスをまだ所有しておらず、HAProxy がそのアドレスにバインドしようとすると、ローカルの IP アドレスではないためシステムが拒否することが原因です。解決策は haproxy サービスの起動を遅らせることではありません。それでは再起動に対応できません。ローカルに存在しないアドレスへのバインドを許可するよう、システムを正しく設定します。Linux では、net.ipv4.ip_nonlocal_bind sysctl を 1 に設定するだけです。この設定は、特定の宛先アドレスに向けて HAProxy を通過する IP トラフィックを透過的に捕捉する場合にも必要です。
送信元ポートの範囲を使用するマルチプロセス構成は、一見動作しているようでも、高負荷時にランダムな障害を起こします。複数のプロセスが同じ送信元ポートを使って同じサーバーに接続しようとする可能性があり、それはできないためです。システムがエラーを返し、別のポートを選んで再試行します。“retries” パラメーターに大きな値を設定すれば影響をある程度隠せますが、CPU 使用量と処理時間も増加します。ログにも一定数の再試行が記録されます。このため、マルチプロセス構成ではポート範囲の使用を避けてください。
HAProxy は SO_REUSEPORT を使用し、複数の独立したプロセスを同じ IP:port にバインドできます。このため、トラブルシューティング中に古いプロセスを停止しないまま新しいプロセスを起動してしまうことがあります。その結果、設定の変更がすべて無視されているかのような、不可解なテスト結果が得られます。新しいプロセスを新しい設定で再起動しても、古いプロセスが受信接続の一部を処理し、想定外の結果を返すためです。疑わしい場合は新しいプロセスを停止し、もう一度試してください。それでも動作するなら、古いプロセスが残っていて停止する必要がある可能性が非常に高いと考えられます。Linux の “netstat -lntp” が調査に役立ちます。
コマンドラインから ACL にエントリーを追加する場合、たとえば送信元アドレスをブラックリストに登録する場合は、これらのエントリーがファイルに同期されないことに注意してください。誰かが設定をリロードすると、更新内容は失われます。ブラックリストへの登録ではこの動作が望ましいことも多いものの、問題を修正するための変更であれば、期待どおりとは限りません。CLI インターフェースの “add acl” アクションを参照してください。