CoreOS: tcpdump gizemli bir şekilde ağ sorununu çözüyor (aşırı sayıda soket kullanılıyor)


14

Bugün senin için bir gizem var. Azure'da CoreOS (2023.5.0 / Linux 4.19.25-coreos) tabanlı küçük, üç düğümlü bir Elasticsearch kümesi çalıştırıyoruz. Elasticsearch, ana bilgisayar ağ modunda bir docker konteynerinin içinde çalıştırılır. Bir yıldan uzun süredir neredeyse tamamen bakım gerektirmeden çalıştıktan sonra makinelerin çok ilginç bir duruma girdiğini görüyoruz.

Güncelleme

Bu sorun Linux çekirdeğindeki bir sürücüye yönelik bir düzeltme ile çözüldü . Aşağıdaki cevaba bakınız.

belirtiler

Temel olarak, etkilenen makine ile diğer iki düğüm arasındaki ağ ölür. Hepsi aynı sanal ağda ve aynı alt ağdadır ve diğerleriyle normal olarak iletişim kurabilir. Etkilenen düğüme hala diğer alt ağlardan (içine ssh olabilirim) ve farklı bir eşleştirilmiş sanal ağdan erişilebilir. Makine ayrıca internete (çok sivilceli) bağlantı vardır, ancak çoğu istek sadece zaman aşımı.

Etkilenen bir düğümde, bildirilen "kullanılan soket" sayısının /proc/net/sockstatçok yüksek olduğunu gözlemledik (sağlıklı bir düğümde ~ 300 yerine ~ 4.5k). İzleme, bu numaranın düğümün kullanılamadığı andan itibaren hızla arttığını göstermektedir.

Eğlenceli olan şey, bu kullanılan soketlerin kaynağını tanımlayamayacağımızdır:

# 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

Bunun dışında makine iyi görünüyor. Çalışan şüpheli işlem yoktur, CPU kullanımı minimum düzeydedir ve yeterli miktarda bellek vardır.

Aynı alt ağda "erişilemeyen" bir VM'ye ping EAGAINatmak birkaç yanıta neden olur recvmsgve ardından ENOBUFSgeri dönmeye geçer sendmsg. burada strace ping çıkışı

Bazı ek çıktılar topladım (sistemde herhangi bir değişiklik yapılmadan önce) ve bu özette yayınladım: https://gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c

analiz

Sunucuda düşünebileceğimiz her şeyi kapatmayı denedik, elasticsearch ilk şüpheli oldu. Ancak, elasticsearch kapsayıcısının kapatılması, kullanılan soketleri serbest bırakmaz. CoreOS ile ilgili tüm işlemler (güncelleme motoru, çilingir, ...) veya Docker çalışma zamanının tamamı veya Azure'a özgü şeyler için aynı şey. Hiçbir şey yardımcı görünmüyordu.

Ama şimdi daha da garip: tcpdumpNeler olduğunu görmek için makineye koşmaya çalıştık . Ve bakın: Sorun kendi kendine çözüldü, bağlantı yeniden sağlandı. Teorimiz, tcpdump'ın onu çözen bir tür sistem çağrısı yapmasıydı. Tcpdump'ı gdb ile çalıştırdık ve tüm sistem çağrılarında kesme noktaları belirledik. Bir sürü kesme noktasından geçtikten sonra, yakalama soketinde (özellikle libpcap'ta bu satır ) karışık mod ayarlama eyleminin, kullanılan soketleri sıfırlayan ve bizi normal bir duruma döndüren şey olduğunu gördük .

Ek Bulgular

  • Bayrakla çalışmanın tcpdump, -p/--no-promiscuous-modekullanılan sayacı temizlemediğini ve makineyi kullanılabilir bir duruma döndürmediğini doğruladık .
  • Koşu ifconfig eth0 txqueuelen 1001sıfırlanır prizler kullanılan sayaç ancak bağlantı olduğunu değil restore.
  • Promisc modunu manuel olarak ayarlamak ip link set eth0 promisc onda bağlantıyı geri yüklemez.
    • net.ipv4.xfrm4_gc_thresh 32768 olarak ayarlanmış ve biraz arttırmak sorunu çözmez.

kullanılan prizler

Bu kadar şaşırmış Azure ile temas halindeyiz. Bunun muhtemelen sorun değil, sadece bir semptom olduğunu anlıyorum. Ama şimdiye kadar bulduğum tek somut şey. Umudum, belirtiyi anlayarak kök nedene yaklaşabileceğimdir. Azure'daki ağ arabirimleri bu ağ sürücüsü ile çalıştırılır .

Belki CoreOS / Kernel sorumludur?

Zaman çizelgesi açısından, problemler CoreOS'un otomatik olarak en son sürüme güncellendiği 2019-03-11'de başladı. Sürüm notlarına göre , bu güncelleştirme 4.15.23'ten 4.19.25'e kadar bir çekirdek güncelleştirmesi içeriyordu . Ben hala orada bir şey olup olmadığını görmek için changelogs geçiyorum. Şimdiye kadar, sadece hiperv ağ sürücüsünün son aylarda 4.19.25'in bir parçası gibi görünmeyen birkaç güncelleme aldığını keşfettim. CoreOS'un 4.19.25'e uyguladığı yama seti o kadar etkileyici değil , ancak sahte bir nf_conntrack_ipv4 modülünü tanıtan yama yeni.

Güncelleme: Gelen çekirdek yamasıyla ilgili?

Yardım!

Şimdiye kadar sahip olduğumuz sorular şunlardır:

  • Bu "kullanılan soketlerin" metriğinin havaya uçmasına ne sebep olabilir? Bu metrik için çekirdek kaynaklarını okudum ve gerçekte ne tür soketler olduğuna ya da onları ne yarattığına atıfta bulunmayan bir sayaç gibi görünüyor .

  • Sayı neden yaklaşık 4,5k. Hangi sınır buna neden olur?

  • 4.14.96 ve 4.19.25 çekirdeği arasında önemli bir değişiklik oldu mu?

  • Neden setsockopt()libpcap'taki çağrı durumu sıfırlar?

İlgili CoreOS hatası: https://github.com/coreos/bugs/issues/2572


Açık yuvalar, IMHO kök sorunu değil, ortaya çıkan bir sorundur. Ben bir köprü cihazında macvlan cihazları (kendi mac adresleri ile) bir linux sistemde bu davranış vardı. Köprüyü promisc'e ayarlamak macvlan cihazlarının çalışmasını sağladı. Coreos veya masmavi bilmiyorum. Sorun, altta yatan bir katmanın üst düzeylerdeki mac adresleri hakkında bilgi sahibi olmamasıdır.
AndreasM

Yorumun için teşekkür ederim! Kullanılan çok sayıda soketin temel neden olmadığını anlıyorum, sadece makinede anormal olarak tanımlayabildiğim somut bir şeye yapışıyorum.
Stephan Klein

Merhaba Stephan. Haber var mı? lütfen rapor 1) WOL etkin mi? 2) sysctl -w net.ipv4.route.flush = 1 çözülüyor mu? 3) arp önbellek çalışma durumu nedir? çalışma durumunda?
Massimo

Yanıtlar:


4

Her şeyden önce, çok iyi yazılmış bir soru için teşekkür ederim!

Açıkladığınız ayrıntı seviyesi çok yüksek ve zaten gdb seviyesinde olduğunuz için, cevabımın sizin için çok fazla faydası olmayacağını düşünüyorum. Her neyse, işte bir deneme:

  • Muhtemelen zaten böyle bir şey denediniz ss -aeve lsof -n?
  • Does dmesgbu olduğunda dönüş İlginç bir şey?
  • Sunucuda iptables kullanıyor musunuz?
  • Karışık modu tcpdump (diyelim ip link set [interface] promisc on) dışında bir yol kullanarak ayarlarsanız, bu da sorunu çözüyor mu?
  • Herhangi bir şüpheli süreç, dosya veya başka garip bir etkinlik olup olmadığını kontrol ettiniz mi? Sadece davetsiz bir kötü sürecin kendisini gizleyen gölgelerde gizlendiğini ve karışık mod ayarlandığında sessizleştiğini mi düşünüyorsunuz?
  • Eğer tcpdump arka planda çalışıyorsa, bu sorun geri dönecek mi?

Umarım bu yardımcı olur.


1
Cevabın için teşekkürler! Gerçekten referans verdiğiniz bazı komutların çıktısını topladım. Şimdi soruda da bağlantılıdırlar ( gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c ). Tuhaf bir şey bu olsun yoludur az prizler bildirilen ss, lsofve netstatde "kullanılmış yuvalarına" dan daha /proc/net/sockstat. Yalnızca toplam sayı (bu dosyadan okunmuş gibi görünüyor) aynıdır. iptablesçalışır ama özel kuralları yok (bkz. gist), ben karışık mod kendim ayarlamayı veya sürekli tcpdump çalıştırmak denemedim. Bunu bir dahaki sefere yapacağım.
Stephan Klein

Ben çıktısını eklemiş ss -aepi: my çıktı koleksiyonuna gist.github.com/privatwolke/... Ne yazık ki dmesg getiriler bu başladığında kesin bir şey -. Aslında, olaydan önceki son giriş 5 günlük.
Stephan Klein


ip link set eth0 promisc onMakineyi tek başına kullanılabilir bir duruma getirmediğini doğruladım .
Stephan Klein

Merhaba, Bu sitedeki bu soruya bir göz attınız mı? serverfault.com/questions/614453/… Görünüşe göre xfrm4 hedef önbelleğini tüketiyor olabilirsiniz. Bunu bu çekirdek ayarıyla artırabilirsiniz: xfrm4_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv4 destination cache entries. At twice this value the system will refuse new allocations. Bence, burada da çalışmıyor gibi görünen IPsec ile ilgili.
Pedro Perez

0

Bu, Linux çekirdeğindeki hv_netsvc sürücüsündeki bir hatadan kaynaklandı. Bunu bir Microsoft geliştiricisi ile çözebilir ve düzeltmenin yukarı yönde uygulanmasını başardık.

Burada taahhüt mesajını alıntılayacağım çünkü problemi oldukça iyi özetliyor:

RX tamamlama mesajları nedeniyle halka arabelleği dolmak üzere olduğunda, bir TX paketi "düşük filigran" a ulaşabilir ve kuyruğun durmasına neden olabilir. TX tamamlama kuyruğun durdurulmasından önce gelirse, uyanma kaçırılabilir.

Bu düzeltme eki, son bekleyen paketin denetimini hem EAGAIN hem de başarı durumlarını kapsayacak şekilde taşır, böylece kuyruk gerektiğinde güvenilir bir şekilde uyanır.

İleride başvurmak için, bunu düzelten taahhüt https://github.com/torvalds/linux/commit/6d9cfab853ca60b2f77b5e4c40443216988cba1f'dir .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.