バインディングに失敗しました、アドレスを使用しています:送信元と宛先の両方にTCPポートを使用できませんか?

バインディングに失敗しました、アドレスを使用しています:送信元と宛先の両方にTCPポートを使用できませんか?

起動しないHadoop DataNodeをデバッグしています。私たちはマシンでsaltstackとelasticsearchを使用しています。

Hadoop DataNodeエラーは非常に明白です。

java.net.BindException: Problem binding to [0.0.0.0:50020]    
java.net.BindException: Address already in use; 
      For more details see:  http://wiki.apache.org/hadoop/BindException

[...]

Caused by: java.net.BindException: Address already in use

[...]

(ExitUtil.java:terminate(124)) - Exiting with status 1

lsof -i -nポート 50020 の場合、すでに使用中であるが宛先ポートではなく、ソースポートとしてのみ使用されます。

salt-mini 1733          root   25u  IPv4  17452      0t0  TCP xx.xx.132.72:50020->xx.xx.132.20:4505 (ESTABLISHED)
java      2789 elasticsearch 2127u  IPv6   9808      0t0  TCP xx.xx.132.72:50020->xx.xx.132.55:9300 (ESTABLISHED)

しかし、0.0.0.0のバインディングは機能しないようです。

root@host:~# nc -l 50020
nc: Address already in use

意図的なことでしょうか?そのポートがすでにソースポートとして使用されている場合は、0.0.0.0にバインドできませんか?ソケットから何も受信しません。なぜ動作しないのかわかりません。

Ubuntu 14.04:

root@host:~# uname -a
Linux host 4.2.0-19-generic #23~14.04.1-Ubuntu SMP Thu Nov 12 12:33:30 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

ベストアンサー1

50020 が送信元ポートか宛先ポートであるかは重要ではありません。宣言されると宣言されたのです。

IANAで定義された一時ポートなので、49152 - 65535の範囲の特定のポートでサービスを開始する必要があるのはバグだと思います。多くのLinuxディストリビューションでは、32768以上のポートを一時ポートとして扱います。次のコマンドを使用して、現在の一時ポート範囲を表示できます。

cat /proc/sys/net/ipv4/ip_local_port_range

すべてのアプリケーションは一時ポート範囲のみを使用できるため、特定のポートが常に無料であるという保証はありません。 1024から32767の間で未使用のポートを選択するのが最善です。

紹介を見る一時ポート

Hadoop DataNodeの要件を満たすために一時範囲を変更するには、/etc/sysctl.conf次のように行を編集して設定します。

net.ipv4.ip_local_port_range=56000 65000

編集する:まったく新しいカーネル(変更は2010年5月にコミット)を使用すると、この範囲に例外が適用される可能性があることを間接的に指摘した@mr.spuraticに感謝します。スコープで遊ぶことはそれ自体かなりの変化なので、これはお勧めです。

sysctl -w net.ipv4.ip_local_reserved_ports = 50020, 50021

から引用ドキュメント/ネットワーク/ip-sysctl.txt

ip_local_reserved_ports - list of comma separated ranges

Specify the ports which are reserved for known third-party
applications. These ports will not be used by automatic port
assignments (e.g. when calling connect() or bind() with port
number 0). Explicit port allocation behavior is unchanged.

The format used for both input and output is a comma separated
list of ranges (e.g. "1,2-4,10-10" for ports 1, 2, 3, 4 and
10). Writing to the file will clear all previously reserved
ports and update the current list with the one given in the
input.

Note that ip_local_port_range and ip_local_reserved_ports
settings are independent and both are considered by the kernel
when determining which ports are available for automatic port
assignments.

You can reserve ports which are not in the current
ip_local_port_range, e.g.:

$ cat /proc/sys/net/ipv4/ip_local_port_range
32000   60999
$ cat /proc/sys/net/ipv4/ip_local_reserved_ports
8080,9148

although this is redundant. However such a setting is useful
if later the port range is changed to a value that will
include the reserved ports.

Default: Empty

おすすめ記事