Kapsayıcılar, mikro hizmetler ve hizmet ağları

İnternette yığın makaleler о servis ağı (servis ağı) ve işte bir tane daha. Yaşasın! Ama neden? Ardından, hizmet ağlarının 10 yıl önce, Docker ve Kubernetes gibi konteyner platformlarının ortaya çıkmasından önce ortaya çıkmasının daha iyi olacağı yönünde fikrimi ifade etmek istiyorum. Benim bakış açımın diğerlerinden daha iyi veya daha kötü olduğunu söylemiyorum ama hizmet ağları oldukça karmaşık hayvanlar olduğundan, çoklu bakış açısı onları daha iyi anlamaya yardımcı olacaktır.

Yüzün üzerinde mikro hizmet üzerine kurulu ve binlerce konteynerli uygulamayı destekleyen dotCloud platformundan bahsedeceğim. Bunu geliştirirken ve piyasaya sürerken karşılaştığımız zorlukları ve hizmet ağlarının nasıl yardımcı olabileceğini (veya yardımcı olamayacağını) açıklayacağım.

dotCloud'un tarihi

dotCloud'un tarihçesi ve bu platformun mimari tercihleri ​​hakkında yazdım ancak ağ katmanından pek bahsetmedim. Okumaya dalmak istemiyorsanız son makale dotCloud hakkında özet olarak özet şu şekildedir: müşterilerin çok çeşitli uygulamaları (Java, PHP, Python...) çalıştırmasına olanak tanıyan ve geniş bir veri yelpazesi desteğine sahip bir hizmet olarak PaaS platformudur. hizmetleri (MongoDB, MySQL, Redis...) ve Heroku gibi bir iş akışı: Kodunuzu platforma yüklersiniz, platform konteyner görüntüleri oluşturur ve bunları dağıtır.

Trafiğin dotCloud platformuna nasıl yönlendirildiğini anlatacağım. Özellikle harika olduğu için değil (her ne kadar sistem kendi zamanına göre iyi çalışsa da!), öncelikle modern araçlarla böyle bir tasarımın, eğer bir grup arasında trafiği yönlendirmek için bir yola ihtiyaç duyulursa, mütevazı bir ekip tarafından kısa sürede kolayca uygulanabilmesi nedeniyle. mikro hizmetler veya bir dizi uygulama. Bu şekilde seçenekleri karşılaştırabilirsiniz: Her şeyi kendiniz geliştirirseniz veya mevcut bir hizmet ağını kullanırsanız ne olur? Standart seçim, kendiniz yapmak veya satın almaktır.

Barındırılan uygulamalar için trafik yönlendirme

dotCloud'daki uygulamalar HTTP ve TCP uç noktalarını açığa çıkarabilir.

HTTP uç noktaları yük dengeleyici kümesi yapılandırmasına dinamik olarak eklendi kalça ağrısı. Bu, kaynakların bugün yaptıklarına benzer Giriş Kubernetes'te ve benzeri bir yük dengeleyicide traefik.

İstemciler, etki alanı adının dotCloud yük dengeleyicilerini işaret etmesi koşuluyla, uygun etki alanları aracılığıyla HTTP uç noktalarına bağlanır. Özel birşey yok.

TCP uç noktaları bir bağlantı noktası numarasıyla ilişkilendirilir ve bu daha sonra ortam değişkenleri aracılığıyla o yığındaki tüm kaplara aktarılır.

İstemciler, uygun ana bilgisayar adını (gateway-X.dotcloud.com gibi bir şey) ve bağlantı noktası numarasını kullanarak TCP uç noktalarına bağlanabilir.

Bu ana bilgisayar adı "nats" sunucu kümesine çözümlenir (ilgili değildir) NATS), gelen TCP bağlantılarını doğru konteynere (veya yük dengeli hizmetler durumunda doğru konteynerlere) yönlendirecektir.

Kubernetes'e aşina iseniz bu size muhtemelen Hizmetleri hatırlatacaktır. Düğüm Bağlantı Noktası.

dotCloud platformunda eşdeğer bir hizmet yoktu Küme IP'si: Basitlik açısından hizmetlere platformun içinden ve dışından aynı şekilde erişildi.

Her şey oldukça basit bir şekilde organize edilmişti: HTTP ve TCP yönlendirme ağlarının ilk uygulamaları muhtemelen her biri yalnızca birkaç yüz Python satırından oluşuyordu. Platform büyüdükçe ve ek gereksinimler ortaya çıktıkça geliştirilen basit (naif diyebilirim) algoritmalar.

Mevcut kodun kapsamlı bir şekilde yeniden düzenlenmesi gerekmedi. Özellikle, 12 faktörlü uygulamalar ortam değişkenleri aracılığıyla elde edilen adresi doğrudan kullanabilir.

Bunun modern hizmet ağından farkı nedir?

Sınırlı görünürlük. TCP yönlendirme ağı için elimizde hiçbir ölçüm yoktu. HTTP yönlendirme söz konusu olduğunda, sonraki sürümler hata kodları ve yanıt süreleri ile birlikte ayrıntılı HTTP ölçümleri sunmuştur, ancak modern hizmet ağları daha da ileri giderek, örneğin Prometheus gibi ölçüm toplama sistemleriyle entegrasyon sağlar.

Görünürlük yalnızca operasyonel açıdan değil (sorunların giderilmesine yardımcı olmak için) aynı zamanda yeni özellikler yayınlanırken de önemlidir. Güvenli olmakla ilgili mavi-yeşil dağıtım и kanarya dağıtımı.

Yönlendirme verimliliği da sınırlıdır. dotCloud yönlendirme ağında, tüm trafiğin özel bir yönlendirme düğümleri kümesinden geçmesi gerekiyordu. Bu, potansiyel olarak birden fazla AZ (Erişilebilirlik Alanı) sınırlarının aşılması ve gecikmenin önemli ölçüde artması anlamına geliyordu. Sayfa başına yüzden fazla SQL sorgusu yapan ve her sorgu için SQL sunucusuna yeni bir bağlantı açan sorun giderme kodunu hatırlıyorum. Yerel olarak çalıştırıldığında sayfa anında yüklenir, ancak dotCloud'da yüklenmesi birkaç saniye sürer çünkü her TCP bağlantısı (ve sonraki SQL sorgusu) onlarca milisaniye sürer. Bu özel durumda kalıcı bağlantılar sorunu çözdü.

Modern hizmet ağları bu tür sorunlarla baş etmede daha iyidir. Öncelikle bağlantıların yönlendirilip yönlendirilmediğini kontrol ederler kaynakta. Mantıksal akış aynıdır: клиент → меш → сервис, ancak artık ağ uzak düğümlerde değil yerel olarak çalışıyor, dolayısıyla bağlantı клиент → меш yereldir ve çok hızlıdır (milisaniye yerine mikrosaniye).

Modern hizmet ağları aynı zamanda daha akıllı yük dengeleme algoritmalarını da uygular. Arka uçların durumunu izleyerek, daha hızlı arka uçlara daha fazla trafik gönderebilirler ve bu da genel performansın iyileşmesini sağlar.

güvenlik çok daha iyi. dotCloud yönlendirme ağı tamamen EC2 Classic üzerinde çalışıyordu ve trafiği şifrelemedi (eğer birisi EC2 ağ trafiğine bir algılayıcı koymayı başarırsa, başınızın zaten büyük belada olduğu varsayımına dayanarak). Modern hizmet ağları, örneğin karşılıklı TLS kimlik doğrulaması ve ardından gelen şifrelemeyle tüm trafiğimizi şeffaf bir şekilde korur.

Platform hizmetleri için trafiği yönlendirme

Tamam, uygulamalar arasındaki trafiği tartıştık, peki ya dotCloud platformunun kendisi?

Platformun kendisi çeşitli işlevlerden sorumlu yaklaşık yüz mikro hizmetten oluşuyordu. Bazıları diğerlerinden gelen istekleri kabul etti, bazıları ise diğer hizmetlere bağlanan ancak bağlantıları kendileri kabul etmeyen arka plan çalışanlarıydı. Her durumda, her hizmetin bağlanması gereken adreslerin uç noktalarını bilmesi gerekir.

Birçok üst düzey hizmet yukarıda açıklanan yönlendirme ağını kullanabilir. Aslında dotCloud'un yüzden fazla mikro hizmetinin çoğu, dotCloud platformunun kendisinde normal uygulamalar olarak konuşlandırılmıştır. Ancak az sayıda düşük seviyeli hizmet (özellikle bu yönlendirme ağını uygulayanlar), daha az bağımlılığa sahip daha basit bir şeye ihtiyaç duyuyordu (çünkü çalışmak için kendilerine güvenemeyeceklerdi - eski güzel tavuk ve yumurta sorunu).

Bu düşük seviyeli, görev açısından kritik hizmetler, konteynerlerin doğrudan birkaç önemli düğümde çalıştırılmasıyla dağıtıldı. Bu durumda standart platform hizmetleri kullanılmadı: bağlayıcı, zamanlayıcı ve çalıştırıcı. Modern konteyner platformlarıyla karşılaştırmak isterseniz, bu bir kontrol düzlemini çalıştırmaya benzer. docker run Görevi Kubernetes'e devretmek yerine doğrudan düğümlerde. Konsept olarak oldukça benzer statik modüller (bölmeler), kullandığı kubeadm veya önyükleme bağımsız bir kümeyi başlatırken.

Bu hizmetler basit ve kaba bir şekilde açığa çıkarıldı: Bir YAML dosyası adlarını ve adreslerini listeliyordu; ve her istemcinin dağıtım için bu YAML dosyasının bir kopyasını alması gerekiyordu.

Bir yandan son derece güvenilirdir çünkü Zookeeper gibi harici bir anahtar/değer deposunun desteğine ihtiyaç duymaz (unutmayın, etcd veya Consul o zamanlar mevcut değildi). Öte yandan hizmetlerin taşınmasını da zorlaştırdı. Her taşıma işleminde, tüm istemciler güncellenmiş bir YAML dosyası alır (ve potansiyel olarak yeniden başlatılır). Pek rahat değil!

Daha sonra, her istemcinin yerel bir proxy sunucusuna bağlandığı yeni bir şema uygulamaya başladık. Bir adres ve port yerine sadece servisin port numarasını bilmesi ve üzerinden bağlanması yeterlidir. localhost. Yerel proxy bu bağlantıyı yönetir ve onu gerçek sunucuya iletir. Artık arka ucu başka bir makineye taşırken veya ölçeklendirirken, tüm istemcileri güncellemek yerine yalnızca tüm bu yerel proxy'leri güncellemeniz gerekir; ve artık yeniden başlatmaya gerek yok.

(Ayrıca TLS bağlantılarındaki trafiğin kapsüllenip alıcı tarafa başka bir proxy sunucu konulması ve yalnızca bağlantı kabul edecek şekilde yapılandırılmış olan alıcı hizmetin katılımı olmadan TLS sertifikalarının doğrulanması da planlandı.) localhost. Bu konuda daha sonra daha fazla bilgi vereceğiz).

Bu şuna çok benzer Akıllı Yığın Airbnb'den, ancak önemli fark, SmartStack'in uygulanıp üretime dağıtılması, dotCloud'un dahili yönlendirme sisteminin ise dotCloud Docker olduğunda rafa kaldırılmış olmasıdır.

Ben şahsen SmartStack'in Istio, Linkerd ve Consul Connect gibi sistemlerin öncüllerinden biri olduğunu düşünüyorum çünkü hepsi aynı modeli izliyor:

  • Her düğümde bir proxy çalıştırın.
  • İstemciler proxy'ye bağlanır.
  • Kontrol düzlemi, arka uçlar değiştiğinde proxy yapılandırmasını günceller.
  • ... Kâr!

Hizmet ağının modern uygulaması

Bugün benzer bir tabloyu uygulamaya ihtiyacımız olsaydı benzer ilkeleri kullanabilirdik. Örneğin, hizmet adlarını alandaki adreslerle eşleyerek dahili bir DNS bölgesi yapılandırın 127.0.0.0/8. Daha sonra kümedeki her düğümde HAProxy'yi çalıştırın ve her hizmet adresindeki (o alt ağdaki) bağlantıları kabul edin. 127.0.0.0/8) ve yükü uygun arka uçlara yönlendirmek/dengelemek. HAProxy yapılandırması kontrol edilebilir güven, arka uç bilgilerini vbd veya Consul'da saklamanıza ve gerektiğinde güncellenmiş yapılandırmayı otomatik olarak HAProxy'ye aktarmanıza olanak tanır.

Istio'nun işleyişi hemen hemen bu şekilde! Ancak bazı farklılıklarla:

  • kullanır Elçi Vekili HAProxy yerine.
  • Arka uç yapılandırmasını etcd veya Consul yerine Kubernetes API aracılığıyla depolar.
  • Hizmetlere, 127.0.0.0/8 yerine dahili alt ağdaki adresler (Kubernetes ClusterIP adresleri) tahsis edilir.
  • İstemci ve sunucular arasında karşılıklı TLS kimlik doğrulaması eklemek için ek bir bileşene (Citadel) sahiptir.
  • Devre kesme, dağıtılmış izleme, kanarya dağıtımı vb. gibi yeni özellikleri destekler.

Şimdi bazı farklılıklara hızlıca göz atalım.

Elçi Vekili

Elçi Proxy'si Lyft [Uber'in taksi pazarındaki rakibi - yaklaşık olarak) tarafından yazılmıştır. Lane]. Birçok yönden diğer proxy'lere benzer (ör. HAProxy, Nginx, Traefik...), ancak Lyft onlarınkini yazdı çünkü diğer proxy'lerin sahip olmadığı özelliklere ihtiyaç duyuyorlardı ve mevcut olanı genişletmek yerine yenisini yapmak daha akıllıca görünüyordu.

Elçi tek başına kullanılabilir. Diğer hizmetlere bağlanması gereken belirli bir hizmetim varsa, onu Envoy'a bağlanacak şekilde yapılandırabilirim ve ardından Envoy'u diğer hizmetlerin konumuyla dinamik olarak yapılandırıp yeniden yapılandırırken görünürlük gibi birçok harika ek işlevsellik elde edebilirim. Özel bir istemci kitaplığı veya koda çağrı izleri eklemek yerine, Envoy'a trafik gönderiyoruz ve o da bizim için ölçümleri topluyor.

Ancak Elçi aynı zamanda şu şekilde de çalışabilir: veri düzlemi (veri düzlemi) servis ağı için. Bu, Envoy'un artık bu hizmet ağı için yapılandırıldığı anlamına gelir kontrol Paneli (kontrol Paneli).

Kontrol Paneli

Istio, kontrol düzlemi için Kubernetes API'sine güveniyor. Bu confd kullanmaktan çok farklı değil, veri deposundaki anahtar kümesini görüntülemek için etcd veya Consul'a güvenir. Istio, bir dizi Kubernetes kaynağını görüntülemek için Kubernetes API'sini kullanır.

Bu ve sonra: Şahsen bunu faydalı buldum Kubernetes API'si açıklamasışu şekilde okunur:

Kubernetes API Sunucusu, API kaynakları için depolama, sürüm oluşturma, doğrulama, güncelleme ve anlambilim sunan "aptal bir sunucudur".

Istio, Kubernetes ile çalışacak şekilde tasarlanmıştır; ve bunu Kubernetes dışında kullanmak istiyorsanız Kubernetes API sunucusunun (ve etcd yardımcı hizmetinin) bir örneğini çalıştırmanız gerekir.

Hizmet adresleri

Istio, Kubernetes'in tahsis ettiği ClusterIP adreslerine güvenir, dolayısıyla Istio hizmetleri dahili bir adres alır (aralık dışında) 127.0.0.0/8).

Istio'suz bir Kubernetes kümesindeki belirli bir hizmet için ClusterIP adresine giden trafik, kube-proxy tarafından durdurulur ve bu proxy'nin arka ucuna gönderilir. Teknik ayrıntılarla ilgileniyorsanız kube-proxy, ClusterIP adresine giden bağlantıların hedef IP adreslerini yeniden yazmak için iptables kurallarını (veya nasıl yapılandırıldığına bağlı olarak IPVS yük dengeleyicilerini) ayarlar.

Istio bir Kubernetes kümesine yüklendikten sonra, belirli bir tüketici için, hatta ad alanının tamamı için bir kapsayıcı tanıtılarak açıkça etkinleştirilene kadar hiçbir şey değişmez sidecar özel bölmelere. Bu konteyner, Envoy'un bir örneğini döndürecek ve diğer hizmetlere giden trafiği engellemek ve bu trafiği Envoy'a yönlendirmek için bir dizi iptables kuralı ayarlayacak.

Kubernetes DNS ile entegre edildiğinde bu, kodumuzun hizmet adına göre bağlanabileceği ve her şeyin "çalıştığı" anlamına gelir. Başka bir deyişle, kodumuz aşağıdaki gibi sorgular yayınlar: http://api/v1/users/4242sonra api talebini çözüme kavuşturmak 10.97.105.48iptables kuralları 10.97.105.48'den gelen bağlantıları kesecek ve bunları yerel Envoy proxy'sine iletecek ve bu yerel proxy, isteği gerçek arka uç API'sine iletecektir. Vay be!

Ek gösterişler

Istio ayrıca mTLS (karşılıklı TLS) aracılığıyla uçtan uca şifreleme ve kimlik doğrulama da sağlar. Adı verilen bir bileşen Kale.

Ayrıca bir bileşen var mikserElçinin talep edebileceği her başlıklar, arka uç yükü vb. gibi çeşitli faktörlere bağlı olarak bu istek hakkında özel bir karar verilmesi talebi... (endişelenmeyin: Mixer'ı çalışır durumda tutmanın birçok yolu vardır ve çökse bile Envoy çalışmaya devam edecektir. vekil olarak gayet iyi).

Ve elbette görünürlükten de bahsettik: Envoy, dağıtılmış izleme sağlarken çok büyük miktarda ölçüm topluyor. Bir mikro hizmet mimarisinde, tek bir API isteğinin A, B, C ve D mikro hizmetlerinden geçmesi gerekiyorsa, oturum açıldığında dağıtılmış izleme, isteğe benzersiz bir tanımlayıcı ekleyecek ve bu tanımlayıcıyı tüm bu mikro hizmetlere yönelik alt istekler aracılığıyla saklayarak izin verecektir. ilgili tüm çağrıların kaydedilmesi, gecikmeler vb.

Geliştirin veya satın alın

Istio'nun karmaşık olmasıyla ünlüdür. Buna karşılık, bu yazının başında anlattığım yönlendirme ağını oluşturmak, mevcut araçları kullanarak nispeten basittir. Peki bunun yerine kendi hizmet ağınızı oluşturmak mantıklı mı?

Mütevazı ihtiyaçlarımız varsa (görünürlüğe, devre kesiciye ve diğer inceliklere ihtiyacımız yok), o zaman kendi aracımızı geliştirme düşünceleri gelir. Ancak Kubernetes kullanırsak buna gerek bile kalmayabilir çünkü Kubernetes zaten hizmet keşfi ve yük dengeleme için temel araçlar sağlar.

Ancak gelişmiş gereksinimlerimiz varsa, o zaman bir hizmet ağını "satın almak" çok daha iyi bir seçenek gibi görünüyor. (Istio açık kaynak olduğundan bu her zaman bir "satın alma" değildir, ancak yine de onu anlamak, dağıtmak ve yönetmek için mühendislik zamanına yatırım yapmamız gerekir.)

Istio, Linkerd veya Consul Connect'i mi seçmeliyim?

Şu ana kadar sadece Istio'dan bahsettik ama tek hizmet ağı bu değil. Popüler alternatif - Bağlayıcıve daha fazlası var Konsolos Bağlantısı.

Ne seçilmelidir?

Açıkçası bilmiyorum. Şu anda kendimi bu soruyu cevaplayacak kadar yetkin görmüyorum. Birkaç tane var ilginç makaleler bu araçların karşılaştırılması ve hatta kıyaslamalar.

Umut verici bir yaklaşım, şöyle bir araç kullanmaktır: SüperGloo. Hizmet ağlarının sunduğu API'leri basitleştirmek ve birleştirmek için bir soyutlama katmanı uygular. Farklı hizmet ağlarının belirli (ve bence nispeten karmaşık) API'lerini öğrenmek yerine, SuperGloo'nun daha basit yapılarını kullanabilir ve sanki HTTP arayüzlerini ve arka uçlarını tanımlayan bir ara yapılandırma formatımız varmış gibi birinden diğerine kolayca geçiş yapabiliriz. Nginx, HAProxy, Traefik, Apache için gerçek konfigürasyonu oluşturma ...

Istio ve SuperGloo ile biraz uğraştım ve bir sonraki makalede SuperGloo kullanarak mevcut bir kümeye Istio veya Linkerd'in nasıl ekleneceğini ve ikincisinin işi nasıl yaptığını, yani bir kümeden diğerine geçiş yapmanızı nasıl sağladığını göstermek istiyorum. konfigürasyonların üzerine yazmaya gerek kalmadan bir hizmet ağının diğerine geçmesi.

Kaynak: habr.com

Yorum ekle