Netramesh - hafif servis ağı çözümü

Monolitik bir uygulamadan mikro hizmet mimarisine geçtikçe yeni zorluklarla karşı karşıya kalıyoruz.

Monolitik bir uygulamada hatanın sistemin hangi kısmında oluştuğunu belirlemek genellikle oldukça kolaydır. Büyük olasılıkla sorun monolitin kodunda veya veritabanındadır. Ancak mikro hizmet mimarisinde sorun aramaya başladığımızda artık her şey o kadar açık değil. İsteğin baştan sona izlediği yolun tamamını bulmamız ve onu yüzlerce mikro hizmet arasından seçmemiz gerekiyor. Üstelik birçoğunun kendi depolama tesisleri de var ve bu da mantıksal hataların yanı sıra performans ve hata toleransı sorunlarına da neden olabiliyor.

Netramesh - hafif servis ağı çözümü

Uzun zamandır bu tür sorunların üstesinden gelmeye yardımcı olacak bir araç arıyordum (bunun hakkında Habré'de yazdım: 1, 2), ancak sonunda kendi açık kaynak çözümümü oluşturdum. Bu makalede hizmet ağı yaklaşımının faydalarından bahsedeceğim ve uygulanması için yeni bir araç paylaşacağım.

Dağıtılmış izleme, dağıtılmış sistemlerde hataları bulma sorununa yaygın bir çözümdür. Peki ya ağ etkileşimleri hakkında bilgi toplamaya yönelik bu yaklaşım sistemde henüz uygulanmadıysa veya daha kötüsü, sistemin bir kısmı zaten düzgün çalışıyorsa, ancak eski hizmetlere eklenmediği için kısmen çalışmıyorsa ne olur? ? Bir sorunun kesin kök nedenini belirlemek için sistemde olup bitenlerin tam bir resmine sahip olmak gerekir. İş açısından kritik önemli yollarda hangi mikro hizmetlerin yer aldığını anlamak özellikle önemlidir.

Burada, ağ bilgilerini toplamaya yönelik tüm makineleri, hizmetlerin çalıştığı seviyeden daha düşük bir düzeyde ele alacak olan hizmet ağı yaklaşımı yardımımıza gelebilir. Bu yaklaşım, tüm trafiği yakalamamıza ve anında analiz etmemize olanak tanır. Üstelik uygulamaların bu konuda hiçbir şey bilmesine bile gerek yok.

Hizmet ağı yaklaşımı

Servis ağı yaklaşımının ana fikri, servisler arası etkileşim ile her şeyi yapmamızı sağlayacak şekilde ağ üzerine başka bir altyapı katmanı eklemektir. Uygulamaların çoğu şu şekilde çalışır: her mikro hizmete, hizmetin tüm gelen ve giden trafiğinin içinden geçirildiği, şeffaf bir proxy içeren ek bir sepet konteyneri eklenir. Ve burası tam da istemci dengeleme yapabileceğimiz, güvenlik politikalarını uygulayabileceğimiz, istek sayısına kısıtlamalar getirebileceğimiz ve üretimdeki hizmetlerin etkileşimi hakkında önemli bilgiler toplayabileceğimiz yerdir.

Netramesh - hafif servis ağı çözümü

Çözümler

Bu yaklaşımın halihazırda birkaç uygulaması vardır: Istio и linkerd2. Kutunun dışında birçok özellik sağlarlar. Ancak aynı zamanda kaynaklar üzerinde de büyük bir yük söz konusu. Üstelik böyle bir sistemin faaliyet gösterdiği küme ne kadar büyük olursa, yeni altyapının bakımı için de o kadar fazla kaynağa ihtiyaç duyulacaktır. Avito'da binlerce hizmet örneğini içeren (ve sayıları hızla artmaya devam eden) kubernetes kümelerini işletiyoruz. Mevcut uygulamasında Istio, hizmet örneği başına ~300 Mb RAM tüketiyor. Olasılıkların çokluğu nedeniyle şeffaf dengeleme, hizmetlerin genel yanıt süresini de etkiler (10 ms'ye kadar).

Sonuç olarak, şu anda tam olarak hangi yeteneklere ihtiyacımız olduğuna baktık ve bu tür çözümleri uygulamaya başlamamızın ana nedeninin, izleme bilgilerini tüm sistemden şeffaf bir şekilde toplayabilme yeteneği olduğuna karar verdik. Ayrıca servislerin etkileşimi üzerinde kontrol sahibi olmak ve servisler arasında aktarılan başlıklarla çeşitli manipülasyonlar yapmak istedik.

Sonuç olarak şu karara vardık:  Netrameş.

Netrameş

Netrameş sistemdeki hizmet sayısına bakılmaksızın sonsuz ölçeklendirme yeteneğine sahip hafif bir hizmet ağı çözümüdür.

Yeni çözümün ana hedefleri düşük kaynak yükü ve yüksek performanstı. Ana özelliklerden, izleme aralıklarını anında Jaeger sistemimize şeffaf bir şekilde gönderebilmek istedik.

Günümüzde çoğu bulut çözümü Golang'da uygulanmaktadır. Ve elbette bunun nedenleri de var. Golang'da, G/Ç ile eş zamanlı olmayan şekilde çalışan ve ihtiyaç halinde çekirdekler arasında ölçeklenen ağ uygulamaları yazmak kullanışlı ve oldukça basittir. Ve çok önemli olan, performansın bu sorunu çözmeye yeterli olmasıdır. Bu yüzden biz de Golang'ı seçtik.

Proizvoditelnost

Çabalarımızı maksimum üretkenliğe ulaşmaya odakladık. Hizmetin her örneğinin yanına dağıtılan bir çözüm için küçük bir RAM ve CPU zamanı tüketimi gerekir. Ve tabii ki yanıt gecikmesi de küçük olmalıdır.

Bakalım ne gibi sonuçlar elde ettik.

RAM

Netramesh, trafik olmadan ~10 Mb ve örnek başına 50 RPS'ye kadar yük ile maksimum 10000 Mb tüketir.

Istio elçi proxy'si, binlerce örnekle kümelerimizde her zaman ~300 Mb tüketir. Bu, kümenin tamamına ölçeklendirilmesine izin vermez.

Netramesh - hafif servis ağı çözümü

Netramesh - hafif servis ağı çözümü

Netramesh ile bellek tüketiminde ~10 kat azalma elde ettik.

işlemci

Yük altında CPU kullanımı nispeten eşittir. Sepete birim zaman başına yapılan istek sayısına bağlıdır. Zirvede saniyede 3000 istekteki değerler:

Netramesh - hafif servis ağı çözümü

Netramesh - hafif servis ağı çözümü

Önemli bir nokta daha var: Netramesh - kontrol düzlemi olmayan ve yüksüz bir çözüm, CPU zamanını tüketmez. Istio ile sepetler her zaman hizmet uç noktalarını günceller. Sonuç olarak bu resmi yüksüz olarak görebiliriz:

Netramesh - hafif servis ağı çözümü

Hizmetler arasındaki iletişim için HTTP/1 kullanıyoruz. Elçi aracılığıyla proxy yaparken Istio'nun yanıt süresindeki artış 5-10 ms'ye kadar çıktı; bu, bir milisaniyede yanıt vermeye hazır hizmetler için oldukça fazla bir rakam. Netramesh ile bu süre 0.5-2 ms'ye düştü.

ölçeklenebilirlik

Her proxy tarafından tüketilen kaynakların az miktarda olması, onu her hizmetin yanına yerleştirmeyi mümkün kılar. Netramesh, her sepeti hafif tutmak için kasıtlı olarak bir kontrol düzlemi bileşeni olmadan oluşturuldu. Genellikle servis ağı çözümlerinde kontrol düzlemi, servis keşif bilgilerini her sepete dağıtır. Bununla birlikte zaman aşımları ve dengeleme ayarları hakkında bilgi gelir. Bütün bunlar pek çok yararlı şey yapmanıza olanak tanır, ancak ne yazık ki sepetlerin boyutunu şişirir.

Hizmet keşfi

Netramesh - hafif servis ağı çözümü

Netramesh, hizmet keşfi için herhangi bir ek mekanizma eklemez. Tüm trafik, netra sepet aracılığıyla şeffaf bir şekilde proxy edilir.

Netramesh, HTTP/1 uygulama protokolünü destekler. Bunu tanımlamak için yapılandırılabilir bir bağlantı noktası listesi kullanılır. Tipik olarak sistem, HTTP iletişiminin gerçekleştiği birkaç bağlantı noktasına sahiptir. Örneğin hizmetler ve harici istekler arasındaki etkileşim için 80, 8890, 8080 kullanıyoruz. Bu durumda bunlar bir ortam değişkeni kullanılarak ayarlanabilir. NETRA_HTTP_PORTS.

Kubernetes'i bir orkestratör olarak ve hizmetler arasındaki küme içi iletişim için Hizmet varlığı mekanizmasını kullanırsanız mekanizma tamamen aynı kalır. Öncelikle mikro hizmet kube-dns kullanarak bir hizmet IP adresi alır ve ona yeni bir bağlantı açar. Bu bağlantı ilk olarak yerel netra sepeti ile kurulur ve tüm TCP paketleri başlangıçta netra'ya ulaşır. Daha sonra netra-secar orijinal hedefle bağlantı kurar. Düğümdeki pod IP'sindeki NAT, netra olmadan tamamen aynı kalır.

Dağıtılmış izleme ve bağlam iletme

Netramesh, HTTP etkileşimleriyle ilgili izleme aralıklarını göndermek için gereken işlevselliği sağlar. Netra-sidecar, HTTP protokolünü ayrıştırır, istek gecikmelerini ölçer ve gerekli bilgileri HTTP başlıklarından çıkarır. Sonuçta tüm izleri tek bir Jaeger sisteminde elde ediyoruz. Ayrıntılı yapılandırma için resmi kitaplık tarafından sağlanan ortam değişkenlerini de kullanabilirsiniz. jaeger git kütüphanesi.

Netramesh - hafif servis ağı çözümü

Netramesh - hafif servis ağı çözümü

Ama bir problem var. Hizmetler özel bir uber başlığı oluşturup gönderene kadar sistemde bağlı izleme aralıklarını görmeyeceğiz. Sorunların nedenini hızla bulmamız gereken şey de budur. Burada yine Netramesh'in bir çözümü var. Proxy'ler HTTP başlıklarını okur ve uber izleme kimliğini içermiyorlarsa bir tane oluşturur. Netramesh ayrıca gelen ve giden isteklerle ilgili bilgileri bir sepette saklar ve bunları gerekli giden istek başlıklarıyla zenginleştirerek eşleştirir. Servislerde yapmanız gereken tek şey sadece bir başlık göndermek X-Request-Idbir ortam değişkeni kullanılarak yapılandırılabilen NETRA_HTTP_REQUEST_ID_HEADER_NAME. Netramesh'te bağlamın boyutunu kontrol etmek için aşağıdaki ortam değişkenlerini ayarlayabilirsiniz: NETRA_TRACING_CONTEXT_EXPIRATION_MILLISECONDS (bağlamın saklanacağı süre) ve NETRA_TRACING_CONTEXT_CLEANUP_INTERVAL (bağlam temizleme sıklığı).

Sisteminizde birden fazla yolu özel bir oturum belirteci ile işaretleyerek birleştirmek de mümkündür. Netra yüklemenizi sağlar HTTP_HEADER_TAG_MAP HTTP başlıklarını karşılık gelen izleme aralığı etiketlerine dönüştürmek için. Bu özellikle test için yararlı olabilir. Fonksiyonel testi geçtikten sonra ilgili oturum anahtarı sayesinde sistemin hangi kısmının filtrelemeden etkilendiğini görebilirsiniz.

İstek Kaynağının Belirlenmesi

İsteğin nereden geldiğini belirlemek için kaynağa otomatik olarak başlık ekleme işlevini kullanabilirsiniz. Ortam değişkeni kullanma NETRA_HTTP_X_SOURCE_HEADER_NAME Otomatik olarak yüklenecek bir başlık adı belirleyebilirsiniz. Kullanarak NETRA_HTTP_X_SOURCE_VALUE tüm giden istekler için X-Source başlığının ayarlanacağı değeri ayarlayabilirsiniz.

Bu, bu yararlı başlığın dağıtımının ağ boyunca eşit şekilde dağıtılmasına olanak tanır. Daha sonra bunu hizmetlerde kullanabilir ve günlüklere ve ölçümlere ekleyebilirsiniz.

Trafik yönlendirme ve Netramesh dahili bileşenleri

Netramesh iki ana bileşenden oluşur. Birincisi, netra-init, trafiği engellemek için ağ kurallarını belirler. O kullanır iptables yönlendirme kuralları Netramesh'in ikinci ana bileşeni olan sepetteki trafiğin tamamını veya bir kısmını kesmek. Gelen ve giden TCP oturumları için hangi bağlantı noktalarının ele geçirilmesi gerektiğini yapılandırabilirsiniz: INBOUND_INTERCEPT_PORTS, OUTBOUND_INTERCEPT_PORTS.

Aracın ayrıca ilginç bir özelliği de var: olasılığa dayalı yönlendirme. Netramesh'i yalnızca izleme aralıklarını toplamak için kullanıyorsanız, üretim ortamında kaynakları kaydedebilir ve değişkenleri kullanarak olasılıksal yönlendirmeyi etkinleştirebilirsiniz. NETRA_INBOUND_PROBABILITY и NETRA_OUTBOUND_PROBABILITY (0'dan 1'e). Varsayılan değer 1'dir (tüm trafik kesilir).

Başarılı bir müdahalenin ardından netra sepet yeni bağlantıyı kabul eder ve kullanır SO_ORIGINAL_DST Orijinal hedefi almak için soket seçeneği. Netra daha sonra orijinal IP adresine yeni bir bağlantı açar ve üzerinden geçen tüm trafiği dinleyerek taraflar arasında iki yönlü TCP iletişimi kurar. Bağlantı noktası HTTP olarak tanımlanmışsa Netra onu ayrıştırmaya ve izlemeye çalışır. HTTP ayrıştırması başarısız olursa Netra, TCP'ye geri döner ve baytları şeffaf bir şekilde proxy olarak kullanır.

Bağımlılık grafiği oluşturma

Jaeger'de büyük miktarda izleme bilgisi aldıktan sonra sistemdeki etkileşimlerin tam bir grafiğini elde etmek istiyorum. Ancak sisteminiz oldukça yüklüyse ve günde milyarlarca izleme aralığı birikiyorsa, bunları bir araya getirmek o kadar da kolay bir iş olmaz. Bunu yapmanın resmi bir yolu var: kıvılcım bağımlılıkları. Ancak tam bir grafiği oluşturmak saatler alacak ve sizi Jaeger'den son 24 saate ait tüm veri setini indirmeye zorlayacaktır.

İzleme aralıklarını depolamak için Elasticsearch'ü kullanıyorsanız şunu kullanabilirsiniz: basit bir Golang yardımcı programıElasticsearch'ün özelliklerini ve yeteneklerini kullanarak aynı grafiği dakikalar içinde oluşturacak.

Netramesh - hafif servis ağı çözümü

Netramesh nasıl kullanılır?

Netra, herhangi bir orkestratörü çalıştıran herhangi bir hizmete kolayca eklenebilir. Bir örnek görebilirsiniz burada.

Şu anda Netra, sepetleri hizmetlere otomatik olarak uygulama yeteneğine sahip değil, ancak uygulamaya yönelik planlar var.

Netramesh'in geleceği

Ana amaç Netrameş servisler arası iletişimin gözlemlenebilirliği ve kontrolü için temel yetenekleri sağlayarak minimum kaynak maliyeti ve yüksek performans elde etmektir.

Gelecekte Netramesh, HTTP'nin yanı sıra diğer uygulama katmanı protokollerini de destekleyecektir. L7 yönlendirmesi yakın gelecekte kullanıma sunulacaktır.

Benzer sorunlarla karşılaşırsanız Netramesh'i kullanın, soru ve önerilerinizi bize yazın.

Kaynak: habr.com

Yorum ekle