Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın
Bu məqalə Kubernetes-də yük balansının necə işlədiyini, uzunmüddətli bağlantıları miqyaslandırarkən nə baş verdiyini və HTTP/2, gRPC, RSockets, AMQP və ya digər uzunömürlü protokollardan istifadə edirsinizsə, niyə müştəri tərəfində balanslaşdırmanı nəzərdən keçirməli olduğunuzu anlamağa kömək edəcək. . 

Kubernetes-də trafikin necə yenidən paylanması haqqında bir az 

Kubernetes proqramların yerləşdirilməsi üçün iki rahat abstraksiya təqdim edir: Xidmətlər və Yerləşdirmələr.

Tətbiqlər istənilən vaxt tətbiqinizin necə və neçə nüsxəsinin işlədilməsini təsvir edir. Hər bir proqram bir Pod kimi yerləşdirilir və bir IP ünvanı təyin olunur.

Xidmətlər funksiyasına görə yük balanslaşdırıcısına bənzəyir. Onlar trafiki çoxlu podlar arasında paylamaq üçün nəzərdə tutulub.

Gəlin görək necə görünür.

  1. Aşağıdakı diaqramda eyni tətbiqin üç nümunəsini və yük balanslaşdırıcısını görə bilərsiniz:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  2. Yük balanslaşdırıcısı Xidmət adlanır və ona IP ünvanı verilir. İstənilən daxil olan sorğu podlardan birinə yönləndirilir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  3. Yerləşdirmə ssenarisi tətbiqin nümunələrinin sayını müəyyən edir. Siz demək olar ki, heç vaxt birbaşa aşağıda genişlənməli olmayacaqsınız:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  4. Hər bir pod öz IP ünvanı təyin edilir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Xidmətləri IP ünvanlarının toplusu kimi düşünmək faydalıdır. Siz xidmətə hər dəfə daxil olanda siyahıdan IP ünvanlarından biri seçilir və təyinat ünvanı kimi istifadə olunur.

Bu belə görünür.

  1. Xidmətə curl 10.96.45.152 sorğusu qəbul edilir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  2. Xidmət təyinat olaraq üç pod ünvanından birini seçir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  3. Trafik xüsusi poda yönləndirilir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Tətbiqiniz ön və arxa hissədən ibarətdirsə, hər biri üçün həm xidmət, həm də yerləşdirmə olacaq.

Frontend backend-ə sorğu göndərdikdə, arxa tərəfin neçə pod-a xidmət etdiyini dəqiq bilməyə ehtiyac yoxdur: bir, on və ya yüz ola bilər.

Həmçinin, frontend, arxa tərəfə xidmət edən podların ünvanları haqqında heç nə bilmir.

Frontend backend-ə sorğu göndərdikdə, dəyişməyən backend xidmətinin IP ünvanından istifadə edir.

Burada görünür necə.

  1. 1 altında daxili backend komponenti tələb olunur. Backend üçün xüsusi birini seçmək əvəzinə, xidmətə sorğu göndərir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  2. Xidmət təyinat ünvanı kimi arxa panellərdən birini seçir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  3. Trafik xidmət tərəfindən seçilmiş Pod 1-dən Pod 5-ə keçir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  4. 1-dən aşağı xidmətin arxasında 5-dən aşağı kimi neçə podun gizləndiyini dəqiq bilmir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Bəs xidmət sorğuları tam olaraq necə paylayır? Deyəsən, round-robin balanslaşdırma istifadə olunur? Gəlin bunu anlayaq. 

Kubernetes xidmətlərində balanslaşdırma

Kubernetes xidmətləri mövcud deyil. IP ünvanı və port təyin edilmiş xidmət üçün heç bir proses yoxdur.

Siz klasterdəki istənilən node daxil olmaqla və netstat -ntlp əmrini işlətməklə bunu yoxlaya bilərsiniz.

Siz hətta xidmətə ayrılmış IP ünvanını tapa bilməyəcəksiniz.

Xidmətin IP ünvanı idarəetmə təbəqəsində, nəzarətçidə yerləşir və verilənlər bazasında qeyd olunur - və s. Eyni ünvan başqa bir komponent tərəfindən istifadə olunur - kube-proxy.
Kube-proxy bütün xidmətlər üçün IP ünvanlarının siyahısını alır və klasterdəki hər bir qovşaqda bir sıra iptables qaydaları yaradır.

Bu qaydalar deyir: "Xidmətin IP ünvanını görsək, sorğunun təyinat ünvanını dəyişdirməli və onu podlardan birinə göndərməliyik."

Xidmətin IP ünvanı yalnız giriş nöqtəsi kimi istifadə olunur və həmin IP ünvanı və portu dinləyən heç bir proses tərəfindən xidmət edilmir.

Gəlin buna baxaq

  1. Üç qovşaqdan ibarət klasteri nəzərdən keçirək. Hər bir qovşaqda podlar var:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  2. Bej rəngə boyanmış bağlanmış podlar xidmətin bir hissəsidir. Xidmət bir proses olaraq mövcud olmadığı üçün boz rəngdə göstərilir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  3. Birinci pod xidmət tələb edir və əlaqəli podlardan birinə keçməlidir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  4. Amma xidmət yoxdur, proses yoxdur. Bu necə işləyir?

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  5. Sorğu qovşağı tərk etməzdən əvvəl iptables qaydalarından keçir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  6. iptables qaydaları xidmətin mövcud olmadığını bilir və onun IP ünvanını həmin xidmətlə əlaqəli podların IP ünvanlarından biri ilə əvəz edir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  7. Sorğu təyinat ünvanı kimi etibarlı IP ünvanı alır və normal şəkildə emal olunur:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  8. Şəbəkə topologiyasından asılı olaraq sorğu nəhayət pod-a çatır:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

iptables balansı yükləyə bilərmi?

Xeyr, iptables filtrləmə üçün istifadə olunur və balanslaşdırma üçün nəzərdə tutulmamışdır.

Bununla belə, kimi işləyən bir sıra qaydalar yazmaq mümkündür psevdo balanslaşdırıcı.

Və Kubernetes-də məhz bu həyata keçirilir.

Üç podunuz varsa, kube-proxy aşağıdakı qaydaları yazacaq:

  1. 33% ehtimalı ilə birinci sub seçin, əks halda növbəti qaydaya keçin.
  2. 50% ehtimalı ilə ikincisini seçin, əks halda növbəti qaydaya keçin.
  3. Altında üçüncü seçin.

Bu sistem hər bir podun 33% ehtimalla seçilməsinə səbəb olur.

Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Pod 2-nin Pod 1-dən sonra seçiləcəyinə heç bir zəmanət yoxdur.

Qeyd: iptables təsadüfi paylanma ilə statistik moduldan istifadə edir. Beləliklə, balanslaşdırma alqoritmi təsadüfi seçimə əsaslanır.

İndi xidmətlərin necə işlədiyini başa düşdüyünüz üçün, daha maraqlı xidmət ssenarilərinə baxaq.

Kubernetes-də uzun ömürlü bağlantılar standart olaraq ölçülənmir

Frontenddən backendə qədər hər bir HTTP sorğusu açılır və bağlanan ayrıca TCP bağlantısı ilə xidmət göstərir.

Əgər frontend arxa hissəyə saniyədə 100 sorğu göndərirsə, o zaman 100 müxtəlif TCP bağlantısı açılır və bağlanır.

Siz bir TCP bağlantısı açmaqla və ondan sonrakı bütün HTTP sorğuları üçün istifadə etməklə sorğunun emal vaxtını və yüklənməsini azalda bilərsiniz.

HTTP protokolunda HTTP-nin canlı qalması və ya əlaqənin təkrar istifadəsi adlı bir xüsusiyyət var. Bu halda, çoxsaylı HTTP sorğuları və cavabları göndərmək və qəbul etmək üçün tək TCP bağlantısı istifadə olunur:

Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Bu funksiya defolt olaraq aktiv edilməyib: həm server, həm də müştəri müvafiq olaraq konfiqurasiya edilməlidir.

Quraşdırma özü sadədir və əksər proqramlaşdırma dilləri və mühitləri üçün əlçatandır.

Müxtəlif dillərdəki nümunələrə bəzi keçidlər:

Kubernetes xidmətində canlı saxlamaqdan istifadə etsək nə baş verir?
Fərz edək ki, həm frontend, həm də arxa hissə canlı qalmağı dəstəkləyir.

Bizdə frontendin bir nüsxəsi və arxa tərəfin üç nüsxəsi var. Frontend ilk sorğunu edir və arxa tərəfə TCP bağlantısı açır. Sorğu xidmətə çatır, təyinat ünvanı kimi arxa panellərdən biri seçilir. Backend cavab göndərir və frontend onu qəbul edir.

Cavab aldıqdan sonra TCP bağlantısının bağlandığı adi vəziyyətdən fərqli olaraq, o, artıq HTTP sorğuları üçün açıq saxlanılır.

Frontend arxa hissəyə daha çox sorğu göndərsə nə olar?

Bu sorğuları yönləndirmək üçün açıq TCP bağlantısından istifadə ediləcək, bütün sorğular ilk sorğunun getdiyi eyni backend-ə gedəcək.

İptables trafiki yenidən bölüşdürməli deyilmi?

Bu halda yox.

TCP bağlantısı yaradıldıqda, o, trafikin gedəcəyi xüsusi bir backend seçən iptables qaydalarından keçir.

Bütün sonrakı sorğular artıq açıq TCP bağlantısında olduğundan, iptables qaydaları artıq çağırılmır.

Gəlin görək necə görünür.

  1. Birinci pod xidmətə sorğu göndərir:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  2. Bundan sonra nə olacağını artıq bilirsiniz. Xidmət mövcud deyil, lakin sorğunu emal edəcək iptables qaydaları var:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  3. Təyinat ünvanı kimi arxa panellərdən biri seçiləcək:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  4. Sorğu qovluğa çatır. Bu nöqtədə, iki pods arasında davamlı TCP bağlantısı qurulacaq:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  5. Birinci poddan istənilən sonrakı sorğu artıq qurulmuş əlaqədən keçəcək:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Nəticə daha sürətli cavab müddəti və daha yüksək ötürmə qabiliyyətidir, lakin siz arxa planı miqyaslaşdırmaq qabiliyyətini itirirsiniz.

Daimi əlaqə ilə arxa tərəfdə iki pods olsa belə, trafik həmişə onlardan birinə gedəcək.

Bu düzəldilə bilərmi?

Kubernetes davamlı əlaqələri necə tarazlaşdıracağını bilmədiyi üçün bu vəzifə sizin üzərinizə düşür.

Xidmətlər son nöqtələr adlanan IP ünvanları və portların toplusudur.

Tətbiqiniz xidmətdən son nöqtələrin siyahısını əldə edə və sorğuların onlar arasında necə bölüşdürülməsinə qərar verə bilər. Siz hər bir pod üçün davamlı əlaqə aça və round-robin istifadə edərək bu bağlantılar arasında sorğuları balanslaşdıra bilərsiniz.

Və ya daha çox müraciət edin kompleks balanslaşdırma alqoritmləri.

Balanslaşdırmaya cavabdeh olan müştəri tərəfi kodu bu məntiqə əməl etməlidir:

  1. Xidmətdən son nöqtələrin siyahısını əldə edin.
  2. Hər son nöqtə üçün davamlı əlaqə açın.
  3. Sorğu etmək lazım olduqda, açıq bağlantılardan birini istifadə edin.
  4. Son nöqtələrin siyahısını müntəzəm olaraq yeniləyin, yenilərini yaradın və ya siyahı dəyişərsə, köhnə davamlı əlaqələri bağlayın.

Bu belə görünəcək.

  1. Xidmətə sorğu göndərən ilk pod əvəzinə siz müştəri tərəfindəki sorğuları balanslaşdıra bilərsiniz:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  2. Hansı podların xidmətin bir hissəsi olduğunu soruşan kod yazmalısınız:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  3. Siyahı əldə etdikdən sonra onu müştəri tərəfində saxlayın və podlara qoşulmaq üçün ondan istifadə edin:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

  4. Siz yük balanslaşdırma alqoritminə cavabdehsiniz:

    Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

İndi sual yaranır: bu problem yalnız HTTP-nin canlı saxlanmasına aiddir?

Müştəri tərəfində yük balansı

HTTP davamlı TCP bağlantılarından istifadə edə bilən yeganə protokol deyil.

Tətbiqiniz verilənlər bazasından istifadə edirsə, onda hər dəfə sorğu vermək və ya verilənlər bazasından sənəd götürmək lazım olanda TCP bağlantısı açılmır. 

Bunun əvəzinə verilənlər bazasına davamlı TCP bağlantısı açılır və istifadə olunur.

Əgər verilənlər bazanız Kubernetes-də yerləşdirilibsə və giriş xidmət kimi təmin edilibsə, əvvəlki bölmədə təsvir olunan eyni problemlərlə qarşılaşacaqsınız.

Bir verilənlər bazası replikası digərlərindən daha çox yüklənəcək. Kube-proxy və Kubernetes əlaqələri balanslaşdırmağa kömək etməyəcək. Sorğuları verilənlər bazanızla balanslaşdırmağa diqqət yetirməlisiniz.

Verilənlər bazasına qoşulmaq üçün hansı kitabxanadan istifadə etdiyinizdən asılı olaraq, bu problemi həll etmək üçün müxtəlif seçimləriniz ola bilər.

Aşağıda Node.js-dən MySQL verilənlər bazası klasterinə daxil olmaq nümunəsi verilmişdir:

var mysql = require('mysql');
var poolCluster = mysql.createPoolCluster();

var endpoints = /* retrieve endpoints from the Service */

for (var [index, endpoint] of endpoints) {
  poolCluster.add(`mysql-replica-${index}`, endpoint);
}

// Make queries to the clustered MySQL database

Davamlı TCP bağlantılarından istifadə edən bir çox başqa protokollar var:

  • WebSockets və təhlükəsiz WebSockets
  • HTTP / 2
  • gRPC
  • RSockets
  • AMQP

Bu protokolların əksəriyyəti ilə artıq tanış olmalısınız.

Bəs bu protokollar bu qədər populyardırsa, niyə standartlaşdırılmış balanslaşdırma həlli yoxdur? Müştərinin məntiqi niyə dəyişməlidir? Doğma Kubernetes həlli varmı?

Kube-proxy və iptables Kubernetes-ə yerləşdirərkən ən ümumi istifadə hallarını əhatə etmək üçün nəzərdə tutulmuşdur. Bu rahatlıq üçündür.

REST API-ni ifşa edən veb xidmətindən istifadə edirsinizsə, şanslısınız - bu halda davamlı TCP bağlantıları istifadə edilmir, istənilən Kubernetes xidmətindən istifadə edə bilərsiniz.

Ancaq davamlı TCP bağlantılarından istifadə etməyə başladıqdan sonra, yükü arxa tərəflər arasında bərabər şəkildə necə bölüşdürəcəyinizi anlamalı olacaqsınız. Kubernetes-də bu iş üçün hazır həllər yoxdur.

Bununla belə, əlbəttə ki, kömək edə biləcək variantlar var.

Kubernetes-də uzunömürlü əlaqələrin balanslaşdırılması

Kubernetes-də dörd növ xidmət var:

  1. ClusterIP
  2. NodePort
  3. LoadBalancer
  4. Başsız

İlk üç xidmət kube-proxy tərəfindən iptables qaydalarını qurmaq üçün istifadə edilən virtual IP ünvanı əsasında fəaliyyət göstərir. Lakin bütün xidmətlərin təməl əsası başsız xidmətdir.

Başsız xidmətin onunla əlaqəli heç bir IP ünvanı yoxdur və yalnız onunla əlaqəli podların (son nöqtələrin) IP ünvanlarının və portlarının siyahısını əldə etmək üçün bir mexanizm təqdim edir.

Bütün xidmətlər başsız xidmətə əsaslanır.

ClusterIP xidməti bəzi əlavələri olan başsız xidmətdir: 

  1. İdarəetmə təbəqəsi ona bir IP ünvanı təyin edir.
  2. Kube-proxy lazımi iptables qaydalarını yaradır.

Bu yolla siz kube-proxy-yə məhəl qoymayaraq, tətbiqinizi balanslaşdırmaq üçün başsız xidmətdən əldə edilən son nöqtələrin siyahısını birbaşa istifadə edə bilərsiniz.

Bəs biz klasterdə yerləşdirilmiş bütün tətbiqlərə oxşar məntiqi necə əlavə edə bilərik?

Tətbiqiniz artıq yerləşdirilibsə, bu tapşırıq qeyri-mümkün görünə bilər. Bununla belə, alternativ variant var.

Service Mesh sizə kömək edəcək

Yəqin ki, artıq müştəri tərəfində yük balanslaşdırma strategiyasının olduqca standart olduğunu fərq etmisiniz.

Tətbiq başlayanda o:

  1. Xidmətdən IP ünvanlarının siyahısını alır.
  2. Bağlantı hovuzunu açır və saxlayır.
  3. Son nöqtələri əlavə etmək və ya silməklə hovuzu vaxtaşırı yeniləyir.

Tətbiq sorğu vermək istədikdə:

  1. Bəzi məntiqdən istifadə edərək mövcud əlaqəni seçir (məsələn, round-robin).
  2. Müraciəti yerinə yetirir.

Bu addımlar həm WebSockets, həm gRPC, həm də AMQP bağlantıları üçün işləyir.

Siz bu məntiqi ayrı bir kitabxanaya ayırıb tətbiqlərinizdə istifadə edə bilərsiniz.

Bununla birlikdə, bunun əvəzinə Istio və ya Linkerd kimi xidmət şəbəkələrindən istifadə edə bilərsiniz.

Service Mesh tətbiqinizi aşağıdakı proseslə genişləndirir:

  1. Avtomatik olaraq xidmət IP ünvanlarını axtarır.
  2. WebSockets və gRPC kimi əlaqələri sınaqdan keçirir.
  3. Sorğuları düzgün protokoldan istifadə edərək balanslaşdırır.

Service Mesh klaster daxilində trafiki idarə etməyə kömək edir, lakin o, kifayət qədər resurs tələb edir. Digər seçimlər Netflix Ribbon kimi üçüncü tərəf kitabxanalarından və ya Envoy kimi proqramlaşdırıla bilən proksilərdən istifadə etməkdir.

Balans məsələlərinə məhəl qoymasanız nə olar?

Siz yük balansından istifadə etməməyi seçə bilərsiniz və hələ də heç bir dəyişiklik hiss etməməlisiniz. Bir neçə iş ssenarisinə baxaq.

Əgər serverlərdən daha çox müştəriniz varsa, bu o qədər də böyük problem deyil.

Tutaq ki, iki serverə qoşulan beş müştəri var. Balanslaşdırma olmasa belə, hər iki server istifadə olunacaq:

Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Əlaqələr bərabər paylanmaya bilər: bəlkə də dörd müştəri eyni serverə qoşulur, lakin hər iki serverin istifadə olunması şansı yüksəkdir.

Daha problemli olan isə əks ssenaridir.

Əgər daha az müştəriniz və daha çox serveriniz varsa, resurslarınız kifayət qədər istifadə oluna bilər və potensial darboğaz yarana bilər.

Tutaq ki, iki müştəri və beş server var. Ən yaxşı halda, beşdən iki serverə iki daimi əlaqə olacaq.

Qalan serverlər boş olacaq:

Kubernetes-də uzun ömürlü bağlantıları yükləyin və balanslaşdırın

Bu iki server müştəri sorğularını idarə edə bilmirsə, üfüqi miqyaslama kömək etməyəcək.

Nəticə

Kubernetes xidmətləri əksər standart veb tətbiqi ssenarilərində işləmək üçün nəzərdə tutulub.

Bununla belə, verilənlər bazası, gRPC və ya WebSockets kimi davamlı TCP bağlantılarından istifadə edən proqram protokolları ilə işləməyə başladıqdan sonra xidmətlər artıq uyğun deyil. Kubernetes davamlı TCP əlaqələrini balanslaşdırmaq üçün daxili mexanizmləri təmin etmir.

Bu o deməkdir ki, siz proqramları müştəri tərəfində balanslaşdırmanı nəzərə alaraq yazmalısınız.

Tərcümə komanda tərəfindən hazırlanmışdır Mail.ru-dan Kubernetes aaS.

Mövzuda başqa nə oxumaq olar:

  1. Kubernetes-də avtomatik ölçmənin üç səviyyəsi və onlardan necə səmərəli istifadə etmək olar
  2. Piratlıq ruhunda Kubernetes həyata keçirmək üçün şablon ilə.
  3. Rəqəmsal transformasiya haqqında Telegram kanalımız.

Mənbə: www.habr.com

Добавить комментарий