序章

HAProxy cannot bind socket エラーメッセージは、HAProxyが使用するように設定されているのと同じインターフェイスとTCPポートの組み合わせでリッスンしている別のプロセスがある場合、またはHAProxyがネットワークインターフェイスに割り当てられていないIPアドレスを使用しようとした場合に生成されます。 どちらのエラー状態も、基盤となるオペレーティングシステムのネットワークスタックに起因します。

最初のケースでは、HAProxyがバインドしようとしているインターフェイスとポートをすでに使用している別のプロセスがある場合、Linuxの根本的なエラーは次のようになります。 EADDRINUSE. 問題は、常に1つのプロセスのみをIPアドレスとポートの組み合わせにバインドできることです。

2番目のケースでは、HAProxyがシステムのインターフェースに割り当てられていないIPアドレスを使用しようとすると、Linuxの根本的なエラーは次のようになります。 EADDRNOTAVAIL. ここでの問題は、オペレーティングシステムで使用できないアドレスを使用してIPソケットを作成できないことです。

ただし、根本的なエラーは両方とも同じHAProxyエラーメッセージを生成するため、トラブルシューティング cannot bind socket エラーが発生した場合は、Linxシステムで現在使用されているソケットとIPアドレスのリストを調べる必要があります。

を検出するには cannot bind socket エラーメッセージ、あなたは調べる必要があります systemctljournalctl エラーの原因となっているIPアドレスとポートの組み合わせを判別するための出力。 次に、実行中の他のプロセスとネットワークインターフェイスを調べて、サーバーの切り替え、HAProxyが使用するIPアドレスまたはポートの変更、またはこれらのオプションの任意の組み合わせによる問題の解決方法を決定できます。

トラブルシューティング systemctl

このシリーズの冒頭にある一般的なHAProxyエラーのトラブルシューティング方法チュートリアルのトラブルシューティング手順に従って、トラブルシューティングを行う際の最初の手順 cannot bind socket エラーメッセージは、HAProxyのステータスを次のように確認することです。 systemctl.

からの出力 systemctl status 多くの場合、エラーを解決するために必要なすべての診断情報が含まれます。 これには、HAProxyが使用しているIPアドレスと、バインドしようとしているポートが含まれる場合があります。 出力には、HAProxyを開始できなかった期間も示されるため、問題がHAProxyに影響を及ぼしている期間を特定できます。

:UbuntuまたはDebianから派生したLinuxディストリビューションを使用している場合は、 systemctl HAProxyからの出力は含まれていません cannot bind socket 問題を説明するエラーメッセージ。 このチュートリアルの次のセクションjournalctlLogs を使用したトラブルシューティングにスキップして、 systemd 競合するIPアドレスまたはポートを見つけるためにログを記録します。

CentOS、Fedora、およびRedHatから派生したシステムでは、これを使用します systemctl HAProxyのステータスを調べるコマンド:

CentOSとFedoraシステム
  1. sudo systemctl status haproxy.service -l --no-pager

The -l フラグは systemctl 楕円で置き換えるのではなく、行の内容全体を出力します()長い行の場合。 The --no-pager フラグは、次のようなツールを呼び出さずにログ全体を画面に出力します less 一度に表示されるのはコンテンツの画面のみです。

トラブルシューティングしているので cannot bind socket エラーメッセージが表示されたら、次のような出力が表示されます。

Output
● haproxy.service - HAProxy Load Balancer Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled) Active: failed (Result: exit-code) since Wed 2020-08-19 14:57:05 UTC; 3s ago Process: 138738 ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE (code=exited, status=1/FAILURE) Process: 138736 ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q (code=exited, status=0/SUCCESS) Main PID: 138738 (code=exited, status=1/FAILURE) Aug 19 14:57:05 92214d8ff5e2 systemd[1]: Starting HAProxy Load Balancer... Aug 19 14:57:05 92214d8ff5e2 haproxy[138738]: [ALERT] 231/145705 (138738) : Starting frontend main: cannot bind socket [0.0.0.0:80] . . . Aug 19 14:57:05 92214d8ff5e2 systemd[1]: Failed to start HAProxy Load Balancer.

この例 systemctl 出力には、 systemd エラーを説明するジャーナル。 これらの行は、さらにトラブルシューティングするために必要なエラーに関するすべての情報を提供します。 具体的には、ライン cannot bind socket [0.0.0.0:80] HAProxyが使用しようとしているソケットについて説明します(0.0.0.0:80)、以下をスキップできます journalctl 手順を実行し、代わりに、このチュートリアルの最後にあるssおよびpsユーティリティのトラブルシューティングセクションに進んでください。 もう1つの強調表示された行は、HAProxyプロセスのステータスを示しています。 cannot bind socket エラーが表示されます Failed to start HAProxy Load Balancer.

もしあなたの systemctl 出力には、エラーの原因となっているIPアドレスとポートに関する特定の情報が表示されません(UbuntuまたはDebianを使用している場合は、これが適用されます)。次に、調査する必要があります。 journalctl からの出力 systemd ログ。 次のセクションでは、使用方法について説明します journalctl トラブルシューティングするには cannot bind socket エラー。

を使用したトラブルシューティング journalctl ログ

もしあなたの systemctl 出力には、 cannot bind socket エラーの場合は、使用を続行する必要があります journalctl 調べるコマンド systemd HAProxyのログ。

UbuntuおよびDebianから派生したシステムでは、次のコマンドを実行します。

  1. sudo journalctl -u haproxy.service --since today --no-pager

CentOS、Fedora、およびRedHatから派生したシステムでは、次のコマンドを使用してログを検査します。

  1. sudo journalctl -u haproxy.service --since today --no-pager

The --since today フラグは、コマンドの出力を、当日の00:00:00から始まるエントリをログに記録するように制限します。 このオプションを使用すると、エラーをチェックするときに調べる必要のあるログエントリの量を制限するのに役立ちます。

HAProxyが使用中のポートにバインドできない場合は、出力を検索して、次のログエントリに類似した行、具体的には cannot bind socket この例で強調表示されているエラーメッセージ:

Output
-- Logs begin at Wed 2020-08-19 19:38:12 UTC, end at Wed 2020-08-19 19:53:53 UTC. -- . . . Aug 19 19:39:21 92214d8ff5e2 systemd[1]: Starting HAProxy Load Balancer... Aug 19 19:39:21 92214d8ff5e2 haproxy[135]: [ALERT] 231/193921 (135) : Starting frontend main: cannot bind socket [0.0.0.0:80] Aug 19 19:39:21 92214d8ff5e2 haproxy[135]: [ALERT] 231/193921 (135) : Starting frontend main: cannot bind socket [:::80] Aug 19 19:39:21 92214d8ff5e2 systemd[1]: haproxy.service: Main process exited, code=exited, status=1/FAILURE Aug 19 19:39:21 92214d8ff5e2 systemd[1]: haproxy.service: Failed with result 'exit-code'. Aug 19 19:39:21 92214d8ff5e2 systemd[1]: Failed to start HAProxy Load Balancer. . . .

出力の最初の強調表示された行は、HAProxyがポートにバインドできないことを示しています 80 利用可能なすべてのIPv4インターフェース( 0.0.0.0 IPアドレス)。 システムの構成によっては、IPアドレスが異なり、個々のIPのみが表示される場合があります。

IPv6でHAProxyを使用している場合、出力には、IPv6固有のインターフェイスとポートエラーで強調表示されている2番目の行のような行も含まれる場合があります。この場合 :::80. 最初の二つ :: 文字は使用可能なすべてのIPv6インターフェースを示し、末尾は :80 ポートを示します。

独自のシステムで競合するインターフェイスとポートが異なる場合でも、エラーはここに示す出力と同様になります。 からのこの出力で journalctl を使用して問題を診断できるようになります ss, ps、 と ip このチュートリアルの次のセクションのコマンド。

トラブルシューティング ssps ユーティリティ

トラブルシューティングするには cannot bind socket エラーは、HAProxyが使用しようとしているIPアドレスとポートで他のどのプロセスがリッスンしているか、またはIPアドレスがHAProxyで使用可能かどうかを判断する必要があります。

たとえば、Nginxなどの別のサーバーが利用可能なすべてのIPv4ネットワークインターフェイスのポート8080でリッスンするように構成されている場合、完全なソケットは次のようになります。 0.0.0.0:8080. HAProxyも使用するように構成されている場合 0.0.0.0:8080 次に、オペレーティングシステムは EADDRINUSE エラー、およびHAProxyは cannot bind socket 自分自身のソケットを要求できないため、エラーメッセージ。

前に journalctl セクションでは、利用可能なすべてのIPv4アドレスにすでに何かがバインドされています( 0.0.0.0:80). 最近のほとんどのLinuxディストリビューションには、 ss これは、システムのネットワークソケットの状態に関する情報を収集するために使用できます。

次のコマンドは、ポートでIPv4インターフェイスにすでにバインドされているプロセスの名前を判別します 80. と異なる場合は、エラーメッセージのポートに置き換えてください。 80 次のコマンドで:

  1. sudo ss -4 -tlnp | grep 80

へのフラグ ss コマンドは、次の方法でデフォルトの出力を変更します。

  • -4 制限します ss IPv4関連のソケット情報のみを表示します。
  • -t 出力をに制限します tcp ソケットのみ。
  • -l すべてのリスニングソケットを -4-t 考慮される制限。
  • -n ‘httpのようなプロトコル名ではなく、ポート番号が表示されるようにしますorhttps`。 HAProxyが非標準のポートにバインドしようとしている可能性があり、実際のポート番号ではなくサービス名が混乱する可能性があるため、これは重要です。
  • -p ポートにバインドされているプロセスに関する情報を出力します。
  • | grep 80 出力を文字を含む行に制限します 80 したがって、調べる必要のある行が少なくなります

注:このIPv4および次のIPv6の例では、出力に一致するポートを持つ行がない場合は、 cannot bind socket エラーは、 EADDRNOTAVAIL エラー。 次のセクションipUtility のトラブルシューティングにスキップして、システムで使用可能なIPアドレスを調べてください。

これらのフラグをすべて使用すると、次のような出力を受け取るはずです。

Output
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=40,fd=6))

トラブルシューティングを行う場合、最初の3つのフィールドは重要ではありません。 cannot bind socket エラーなので無視できます。 重要なフィールドは4番目です(0.0.0.0:80)、これは journalctl 前回と一緒に以前に発見したエラー users:(("nginx",pid=40,fd=6))、具体的には pid=40 部分。

あなたが持っている場合 cannot bind socket IPv6インターフェースに関連するエラー、繰り返します ss 呼び出し、今回はを使用して -6 次のように、インターフェイスをIPv6ネットワークスタックに制限するフラグを設定します。

  1. sudo ss -6 -tlnp |grep 80

The -6 フラグは ip IPv6インターフェイスへのコマンド。 HAProxyがIPv6ソケットにバインドできない場合は、次のような出力が必要です。

Output
LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=40,fd=7))

繰り返しますが、問題のポート番号を journalctl 強調表示されているものと異なる場合は出力 80 ここに与えられます。

IPv4エラーとIPv6エラーの両方の場合で、 ss 出力は、プロセスID 40のプログラムがあることを示します( pid=40 出力で)にバインドされています 0.0.0.0:80[::]:80 それぞれインターフェース。 このプロセスは、HAProxyがすでにポートを所有しているため、HAProxyの起動を妨げています。 プログラムの名前を決定するには、 ps このようなユーティリティは、強調表示された代わりに出力からプロセスIDを置き換えます 40 この例の値:

  1. sudo ps -p 40

次のような出力が表示されます。

Output
PID TTY TIME CMD 40 ? 00:00:00 nginx

強調表示 nginx 出力には、インターフェースをリッスンしているプロセスの名前が含まれています。 これで、HAProxyの起動を妨げているプログラムの名前がわかったので、エラーを解決する方法を決定できます。 あなたは停止することができます nginx プロセス、再構成 nginx 別のインターフェイスとポートでリッスンするか、ポートの衝突を回避するためにHAProxyを再構成します。

プロセスはとは異なる場合があることに注意することが重要です nginx ポートとIPアドレスは必ずしもそうではないかもしれません 0.0.0.0 また [::] あなたが診断している場合 cannot bind socket エラー。 多くの場合、異なるWebサーバーとプロキシが同じサーバーで使用されます。 それぞれが、異なるWebトラフィックを処理するために異なるIPv4ポートおよびIPv6インターフェースにバインドしようとしている可能性があります。 たとえば、IPv4ループバックアドレスをリッスンするHAProxyで構成されたサーバー(別名 localhost)ポート上 8080 表示されます ss このような出力:

Output
LISTEN 0 2000 127.0.0.1:8080 0.0.0.0:* users:(("haproxy",pid=545,fd=7))

組み合わせることが重要です systemctl 出力、または journalctl 特定のIPアドレスとポートを示す出力とからの診断データ ss、 その後 ps HAProxyの起動に失敗する原因となっているプロセスを絞り込みます。

トラブルシューティングをしているとき cannot bind socket エラーメッセージ ssps 出力はまったくありません。つまり、ソケットの競合が原因でエラーが発生した可能性はありません。 このチュートリアルの次のセクションでは、トラブルシューティングの方法について説明します。 cannot bind socket を使用したエラー ip 効用。

でのトラブルシューティング ip 効用

前のセクションでは、 EADDRINUSE オペレーティングシステムエラーにより、 cannot bind socket エラーメッセージ。 ただし、調べた場合 ssps 出力があり、システムにソケットの競合がない場合、問題の原因は次のとおりです。 EADDRNOTAVAIL 代わりにオペレーティングシステムエラー。 この場合、HAProxyは、オペレーティングシステムで使用できないソケットにバインドしようとしている可能性があります。

かどうかを判断するには cannot bind socket エラーの原因は EADDRNOTAVAIL、を使用して、システム上のIPv4とIPv6の両方のネットワークインターフェイスを調べます。 ip 指図。

  1. sudo ip -4 -c address show
  • -4 制限します ip IPv4関連のインターフェース情報のみを表示します。
  • -c 出力に色分けを追加して、視覚的に解析しやすくします。
  • address show インターフェイスのIPアドレスを表示します。 -4-c 考慮されるフラグ。

を含むすべてのLinuxディストリビューションで次のような出力を受け取るはずです。 ip 道具:

Output
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 203.0.113.1/24 brd 203.0.113.255 scope global eth0 valid_lft forever preferred_lft forever inet 192.0.2.1/24 brd 192.0.2.255 scope global eth0 valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 inet 198.51.100.1/24 brd 198.51.100.255 scope global eth1 valid_lft forever preferred_lft forever

この出力で強調表示されている例に対応するIPアドレスをメモします。 IPアドレスとネットワークインターフェイスは、ここに示す例とは異なります。 インターフェースが多かれ少なかれ、それぞれに割り当てられているアドレスが多かれ少なかれある場合があります。 重要な部分は、からのIPアドレスに注意することです ip.

システムに割り当てられているIPv6アドレスを調べるには、 ip とのコマンド -6 このようなフラグ:

  1. sudo ip -6 -c address show

次のような出力を受け取るはずです。

Output
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000 inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000 inet6 2604:a880:400:d1::3d3:6001/64 scope global valid_lft forever preferred_lft forever inet6 fe80::a4ff:aaff:fec9:24f8/64 scope link valid_lft forever preferred_lft forever

この出力例で強調表示されている値に再度注意し、出力で対応するIPv6アドレスを探します。

システムに割り当てられているアドレスのリストを取得したら、に対応する一致するIPアドレスを見つけることができます。 cannot bind socket [x.x.x.x:80] エラー。 一致するIPアドレスがない場合、HAProxyは、システムで使用できないIPアドレスを使用するように構成されている可能性があります。 cannot bind socket エラーは、オペレーティングシステムがスローすることによって引き起こされています EADDRNOTAVAIL エラー。

エラーを解決するには、を編集する必要があります /etc/haproxy/haproxy.cfg ファイルを変更し、 bind 1つまたは複数のアドレスからの出力に基づいてシステムで使用可能なIPアドレスへのアドレス ip 指図。

たとえば、 /etc/haproxy/haproxy.cfg 含まれています bind 次のような行を使用して 198.51.100.123 IPアドレスとして、しかしあなたのシステムは持っています 198.51.100.1 上記の出力例に基づいて割り当てられた場合、バインド行を編集する必要があります。

この架空の例に続いて、これは haproxy.cfg スニペットは無効なIPアドレスを示しています:

/etc/haproxy/haproxy.cfg
. . .
frontend main
        bind 198.51.100.123:80

正しい bind 例のIPアドレスと一致する行 ip 出力は次のようになります。

/etc/haproxy/haproxy.cfg
. . .
frontend main
        bind 198.51.100.1:80

編集したら /etc/haproxy/haproxy.cfg 正しいIPアドレスで、を使用して再起動します systemctl 指図:

  1. sudo systemctl restart haproxy.service

次に、HAProxyのステータスを調べて、出力に active (running) ライン:

  1. sudo systemctl status haproxy.service
Output
● haproxy.service - HAProxy Load Balancer Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-08-19 21:31:46 UTC; 17h ago Docs: man:haproxy(1) file:/usr/share/doc/haproxy/configuration.txt.gz Process: 487 ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS (code=exited, status=0/SUCCESS) . . . Aug 19 21:31:46 d6cdd0c71489 systemd[1]: Started HAProxy Load Balancer.

解決した場合 cannot bind socket エラー出力は、この出力例のようになります。 HAProxyがアクティブであり、プロセスが正常に開始されたことを示す強調表示された行。

結論

このチュートリアルでは、HAProxyのトラブルシューティング方法を学びました cannot bind socket IPv4インターフェイスとIPv6インターフェイスの両方でエラーメッセージが表示されます。 使い方を学びました systemctl HAProxyサーバーのステータスを調べて、エラーメッセージを見つけようとします。 使い方も学びました journalctl 調べるために systemd に関する特定の情報のログ cannot bind socket エラー。

からの適切なエラーメッセージ systemd ログ、あなたはそれからについて学びました ss ユーティリティと、それを使用してシステムのネットワークソケットの状態を調べる方法。 その後、プロセスID情報を組み合わせる方法を学びました。 ss とともに ps HAProxyを起動できなくなる原因となっているプロセスの名前を見つけるためのユーティリティ。

最後に、 cannot bind socket 使用できないIPv4またはIPv6アドレスに関連するエラー、使用方法を学習しました ip システムで使用可能なネットワークインターフェイスを調べるためのユーティリティ。