Logstash が Elasticsearch ノードへの接続を失う

Logstash が Elasticsearch ノードへの接続を失う

Elasticsearch クラスターにログをプッシュしているサーバーで Logstash を実行しています。Logstash ログを見ると、接続リセット エラーにより Elasticsearch サーバーへの接続が失われていることがわかります。これは、すべてのサーバー上のすべての logstash および elasticsearch インスタンス間で発生しています。この例では、logstash3 (192.168.1.133) が elasticsearch4 (192.168.1.88) への接続を失っていることがわかります。

[2018-08-21T20:21:21,414][WARN ][logstash.outputs.elasticsearch] Marking url as dead. Last error: [LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError] Elasticsearch Unreachable: [http://elasticsearch4:9200/][Manticore::SocketException] Connection reset {:url=>http://elasticsearch4:9200/, :error_message=>"Elasticsearch Unreachable: [http://elasticsearch4:9200/][Manticore::SocketException] Connection reset", :error_class=>"LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError"}

syslog を見ると、UFW が数秒前にパケットをブロックしていることがわかります。

Aug 21 20:21:03 logstash3 kernel: [1760565.386970] [UFW BLOCK] IN=enp0s31f6 OUT= MAC=90:1b:0e:cc:50:95:30:b6:4f:d8:05:51:08:00 SRC=192.168.1.88 DST=192.168.1.133 LEN=40 TOS=0x0 PREC=0x00 TTL=57 ID=442 DF PROTO=TCP SPT=9200 DPT=59338 WINDOW=0 RES=0x00 RST URGP=0

ufw には、これらのサーバー間のすべての接続を許可するルールが設定されています。当初は特定のポートのみを許可していましたが、問題が発生する可能性を考慮して、すべてのポートに開放しました。接続を許可するルールは次のとおりです。

logstash3:~$ sudo ufw status | grep '\.88'
Anywhere                   ALLOW       192.168.1.88

logstash を再起動すると、ドロップされた接続は一時的に (約 1 時間) 消えますが、その後再び発生し始めます。

しばらくすると、この現象が発生し始めるので、どこかでキューがいっぱいになっているのではないかと考えています。接続が完全に停止するわけではなく、時々パケットが失われるだけです。接続の追跡に関連しているのではないかと考えましたが、そのことを示すログは表示されていません。conntrack_max以前は、これが問題であると認識していたため、値を増やしましたが、この場合は役に立ちません。

elasticsearch4:~$ cat /proc/sys/net/nf_conntrack_max
262144

一般的なパケットドロップの証拠はありません。

logstash3:~$ ifconfig
enp0s31f6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.133  netmask 255.255.255.255  broadcast 0.0.0.0
        inet6 2a01:4f8:121:53b7::2  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::921b:eff:fecc:5095  prefixlen 64  scopeid 0x20<link>
        ether 90:1b:0e:cc:50:95  txqueuelen 1000  (Ethernet)
        RX packets 7746452399  bytes 8566845158411 (8.5 TB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5792178105  bytes 5164493104253 (5.1 TB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16  memory 0xef000000-ef020000

@Lenniey のアドバイスに従って、UFW を無効にして、logstash ログにエラーがまだ表示されるかどうかを確認してみました。いくつかのサーバーで ufw を無効にしましたが、Connection resetufw が無効になっているサーバー間のログにまだメッセージが表示されていることがわかりました。そのため、syslog の ufw エントリは原因ではなく症状である可能性があります。

sudo tcpdump -i enp0s31f6 -s 65535 -w logstash.pcap 'port 9200'エラーが発生している間にパケットキャプチャ( )を作成しました

[2018-08-23T07:20:11,108][WARN ][logstash.outputs.elasticsearch] Marking url as dead. Last error: [LogStash::Outputs::ElasticSearch::

HttpClient::Pool::HostUnreachableError] Elasticsearch に到達できません: [http://elasticsearch3:9200/][マンティコア::ソケット 例外] 接続がリセットされました {:url=>http://elasticsearch3:9200/, :error_message=>"Elasticsearch に到達できません: [http: //elasticsearch3:9200/][Manticore::SocketException] 接続がリセットされました", :error_class=>"LogStash::Outputs::ElasticSe arch::HttpClient::Pool::HostUnreachableError"}

パケット キャプチャでは、elasticsearch が 400 エラーで応答していることがわかります。

HTTP/1.0 400 Bad Request
content-type: application/json; charset=UTF-8
content-length: 203

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "text is empty (possibly HTTP/0.9)"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "text is empty (possibly HTTP/0.9)"
  },
  "status": 400
}

次に、elasticsearch から logstash への 5 つの TCP RST パケットを確認します。最後の RST パケットは で07:20:11.107663、これは logstash エラーの時刻 と一致します07:20:11,108

パケット キャプチャが少しわかりにくいです。パケット キャプチャを、問題の logstash と ES サーバーの IP と、400 と RST が表示されるポートに絞り込みましたが、400 の前にリクエストが_bulk進行中のようで、リクエストの途中で 414 応答があり_bulk、その後_bulkリクエストが続行され、400 が表示されます。

ログスタッシュ -> ES

POST /_bulk HTTP/1.1
Connection: Keep-Alive
Content-Type: application/json
Content-Length: 167481062
Host: elasticsearch3.channelgrabber.com:9200
User-Agent: Manticore 0.6.1
Accept-Encoding: gzip,deflate
{ ... data ... }

ES -> ログスタッシュ

HTTP/1.1 413 Request Entity Too Large
content-length: 0

ログスタッシュ -> ES

{ ... data continues ... }

ES -> ログスタッシュ

HTTP/1.0 400 Bad Request
content-type: application/json; charset=UTF-8
content-length: 203
{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"text is empty (possibly HTTP/0.9)"}],"type":"illegal_argument_exception","reason":"text is empty (possibly HTTP/0.9)"},"status":400}

他に何に注目すべきか、何かアドバイスはありますか?

関連情報