오늘 미스터리가 있습니다. Azure에서 CoreOS (2023.5.0 / Linux 4.19.25-coreos) 기반의 소규모 3 노드 Elasticsearch 클러스터를 실행합니다. Elasticsearch는 호스트 네트워크 모드의 도커 컨테이너 내에서 실행됩니다. 거의 1 년 이상 유지 보수가 거의 필요없는 상태에서 기계가 매우 흥미로운 상태로 전환되는 것을 보았습니다.
최신 정보
이 문제는 Linux 커널 의 드라이버 수정으로 해결되었습니다 . 아래 답변을 참조하십시오.
조짐
기본적으로 영향을받는 시스템과 다른 두 노드 사이의 네트워킹은 죽습니다. 모두 동일한 가상 네트워크와 동일한 서브넷에 있으며 보통 다른 사람과 통신 할 수 있습니다. 영향을받는 노드는 여전히 다른 서브넷 (및 ssh로 연결할 수 있음)과 다른 피어링 된 가상 네트워크에서 도달 할 수 있습니다. 컴퓨터는 인터넷에 (매우 드문) 연결되어 있지만 대부분의 요청은 시간 초과됩니다.
영향을받는 노드에서보고 된 "소켓 사용"수가 /proc/net/sockstat
매우 높은 것으로 나타났습니다 (정상 노드에서 ~ 300 대신 ~ 4.5k). 모니터링에 따르면이 수는 노드를 사용할 수 없게 된 순간부터 빠르게 증가합니다.
재밌는 점은 사용 된 소켓의 소스를 식별 할 수 없다는 것입니다.
# cat /proc/net/sockstat
sockets: used 4566
TCP: inuse 2 orphan 0 tw 2 alloc 98 mem 4
UDP: inuse 1 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0
# cat /proc/net/sockstat6
TCP6: inuse 98
UDP6: inuse 1
UDPLITE6: inuse 0
RAW6: inuse 1
FRAG6: inuse 0 memory 0
그 외에는 기계가 괜찮아 보입니다. 실행중인 의심스러운 프로세스가없고 CPU 사용량이 최소화되며 사용 가능한 메모리가 충분합니다.
동일한 서브넷에 "연결할 수없는"VM을 핑 (Ping)하면 몇 가지 EAGAIN
응답이 발생 recvmsg
하고 ENOBUFS
에서 다시 가져 옵니다 sendmsg
. 여기에 strace ping 출력
추가 출력을 수집하여 (시스템을 수정하기 전에) https://gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c 에 게시했습니다.
분석
우리는 서버에서 생각할 수있는 모든 것을 종료하려고 시도했으며, elasticsearch가 첫 번째 용의자입니다. 그러나 elasticsearch 컨테이너를 종료해도 사용 된 소켓이 해제되지 않습니다. 모든 CoreOS 관련 프로세스 (update-engine, locksmithd, ...) 또는 전체 Docker 런타임 또는 Azure 관련 항목에 대해서도 동일합니다. 아무것도 도움이되지 않는 것 같습니다.
그러나 이제는 더 이상해집니다. 우리는 tcpdump
무슨 일이 일어나고 있는지 확인하기 위해 머신에서 실행 을 시도 했습니다. 보라 : 문제는 스스로 해결되었고 연결성은 회복되었다. 우리의 이론은 tcpdump가 그것을 해결하는 일종의 syscall을 수행한다는 것입니다. gdb로 tcpdump를 실행하고 모든 syscall에 중단 점을 설정했습니다. 많은 중단 점을 단계별로 수행 한 후, 캡처 소켓에서 프로 미스 쿠스 모드 (특히 libpcap의이 행 )를 설정하는 작업은 사용 된 소켓을 재설정하고 정상 상태로 되 돌리는 것입니다.
추가 결과
- 우리는 실행중인 것을 확인했다
tcpdump
와-p/--no-promiscuous-mode
플래그하면 소켓을 사용 카운터를 삭제하고 사용 가능한 상태로 기계를 반환하지 않습니다. - 실행
ifconfig eth0 txqueuelen 1001
하면 사용 된 소켓 카운터가 재설정 되지만 연결은 복원 되지 않습니다 . - 수동 모드를 사용하여 수동 모드
ip link set eth0 promisc on
를 설정해도 연결이 복원되지 않습니다.net.ipv4.xfrm4_gc_thresh
이 32768로 설정되어 있고 약간 늘리면 문제가 해결되지 않습니다.
우리는 우리와 마찬가지로 당황한 Azure와 연락을 취했습니다. 이것이 문제가 아니라 증상 일 뿐이라는 것을 이해합니다. 그러나 그것은 내가 지금까지 찾은 유일한 유형의 것입니다. 내 희망은 증상을 이해함으로써 근본 원인에 더 가까이 갈 수 있다는 것입니다. Azure의 네트워크 인터페이스는 이 네트워크 드라이버 로 실행됩니다 .
아마 CoreOS / Kernel이 책임이 있습니까?
타임 라인 관점에서 볼 때 2019-03-11에 CoreOS가 최신 버전으로 자동 업데이트 된 날에 문제가 시작되었습니다. 릴리스 노트에 따르면 이 업데이트에는 4.15.23 에서 4.19.25로 커널 업데이트가 포함 되었습니다 . 여전히 변경 로그를 통해 문제가 있는지 확인하고 있습니다. 지금까지 나는 최근 몇 달 동안 hyperv 네트워크 드라이버가 상당히 많은 업데이트를 받았음을 알았지 만 , 전부 4.19.25의 일부인 것 같지는 않습니다. CoreOS가 4.19.25에 적용한 패치 세트는 그다지 인상적이지는 않지만 가짜 nf_conntrack_ipv4 모듈을 도입 한 패치는 새로운 것입니다.
업데이트 : 가능한 관련 들어오는 커널 패치?
도움!
지금까지 우리가 가진 질문은 다음과 같습니다.
이 "소켓 사용"메트릭이 급상승하는 원인은 무엇입니까? 이 메트릭에 대한 커널 소스 를 읽었으며 실제로 어떤 종류의 소켓인지 또는 어떤 소켓을 만들 었는지에 대한 참조가없는 카운터 인 것 같습니다 .
왜 숫자가 약 4.5k로 평평합니까? 어떤 한계로 인해이 문제가 발생합니까?
커널 4.14.96과 4.19.25 사이에 중요한 변화가 있었습니까?
setsockopt()
libpcap 의 호출이 상태를 재설정하는 이유는 무엇 입니까?
관련 CoreOS 버그 : https://github.com/coreos/bugs/issues/2572