Logstash와 Elasticsearch 노드의 연결이 끊어졌습니다.

Logstash와 Elasticsearch 노드의 연결이 끊어졌습니다.

우리는 로그를 Elasticsearch 클러스터로 푸시하는 서버에서 Logstash를 실행하고 있습니다. Logstash 로그에는 연결 재설정 오류로 인해 Elasticsearch 서버와의 연결이 끊어지는 것을 볼 수 있습니다. 모든 서버의 모든 logstash와 elasticsearch 인스턴스 사이에서 이를 확인할 수 있습니다. 이 예에서는 logtash3(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를 비활성화하고 로그스태시 로그에 여전히 오류가 표시되는지 확인했습니다. 여러 서버에서 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:: 호스트UnreachableError"}

패킷 캡처에서 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되면 _bulk400을 얻습니다.

로그스태시 -> 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}

내가 살펴봐야 할 다른 항목에 대한 제안이 있습니까?

관련 정보