かまたま日記3

プログラミングメイン、たまに日常

Nginxで同じポートでUDPとTCPをリッスンして別のバックエンドにプロキシする

たとえばNLBを使ってUDPをロードバランシングする場合、ヘルスチェックのために、UDPをリッスンするのと同じポートでTCPをリッスンする必要があります *1

そういう場合、バックエンドがNginxの場合は以下のような map$protocol を使った方法で振り分けることが出来ます。ここでは5001番がヘルスチェック用のポートです

stream {
  map $server_port:$protocol $backend {
    5000:UDP "example.com:5000";
    5000:TCP "127.0.0.1:5001";
  }

  server {
    listen 5000 udp;
    listen 5000;
    proxy_pass $backend;
  }

  # Health check
  server {
    listen 5001;
    return "OK";
  }
}

余談

このmapでbackendを切り替える方法は。Nginxが動的にホスト名の名前解決をしてくれない問題の対策にもなります。 (httpの方でよく使う set $backend example.com と同じ効果を得られる)

*1:デフォルトの場合。設定でヘルスチェックを別ポートにすることも可能