ポートとは何か? ネットワークサービスのための番号付きエンドポイント
ポートとは、IPアドレスと組み合わせてホスト上の特定のサービスを指し示す数値識別子であり、OSがトラフィックを正しいプロセスへルーティングできるようにするものです。
1台のサーバーは同時に多くのサービスを実行できるため、各コネクションを正しいサービスへ送る手段が必要です。ポートがそれを担います。プロセスはあるポート番号でリッスンし、クライアントはその番号へ接続します。CIのservice container、ローカルのテストサーバー、デプロイ先はすべてポートにbindしており、ポートの不一致はpipelineで "connection refused" が起きる一般的な原因です。
アドレスとポート
IPアドレスがホストを見つけ、ポートがその上のサービスを見つけます。この組はコネクションの一方の端点を完全に識別するため、同じホスト上の2つのサービスは単に異なるポートを使います。
well-known ポート
- HTTPは80、HTTPSは443。
- SSHは22。
- PostgreSQLは5432、MySQLは3306。
- Redisは6379。
リッスンとbind
サービスはコネクションを受け付けるためにポートへbindします。別のプロセスがすでにそのポートを保持していると、bindは "address already in use" で失敗します。これはテストサーバーがクリーンにシャットダウンしなかったときに頻発するエラーです。
CIのservice containerにおけるポート
CIがデータベースやcacheをservice containerとして起動すると、jobは既知のポートでそれに接続します。そのポートを誤設定したり、サービスがリッスンする前に接続したりすると、connection refusedエラーが発生します。
デプロイにおけるポート
containerはload balancerやproxyがパブリックポートへマッピングするポートを公開します。誤ったcontainerのポートをマッピングするデプロイはトラフィックをどこにも送らず、health checkの失敗や502として現れます。
タイミング対設定
サービスがポートにbindする前に接続するのはタイミングの問題で、短い待機やretryで解決します。一方、誤ったポートへの接続は設定のバグです。Latchkeyのrunnerは一時的な "まだリッスンしていない" ケースを一般的なサービスに対してretryするため、起動レースがjobを失敗させることはありません。
重要なポイント
- ポート番号にIPアドレスを加えると、ホスト上の特定のサービスを識別できます。
- ポートがすでに使用中だとbindが失敗し、クライアントは誤ったポートを狙うと失敗します。
- ポート上の起動レースはretry可能ですが、誤ったポート番号は設定のバグです。