Tinderin Kubernetes'ə köçməsi

Müəllif: Chris O'Brien, Mühəndislik meneceri | Chris Thomas, Engineering Manager | Jinyong Lee, Baş Proqram Mühəndisi | Redaktə etdi: Cooper Jackson, Proqram Mühəndisi

Niyə

Təqribən iki il əvvəl Tinder platformasını Kubernetesə köçürməyə qərar verdi. Kubernetes bizə dəyişməz yerləşdirmə yolu ilə Tinder Engineering-ı konteynerləşdirmə və aşağı toxunuşlu əməliyyat istiqamətinə aparmaq imkanı verdi. Tətbiq qurma, yerləşdirmə və infrastruktur kod olaraq təyin ediləcəkdi.

Həm də miqyaslılıq və sabitlik problemlərini həll etməyə çalışırdıq. Ölçəkləmə kritik hal aldıqda, yeni EC2 nümunələrinin internetə girməsini gözləyəndən sonra bir neçə dəqiqə əziyyət çəkdik. Konteynerlərin dəqiqədə əksinə saniyə ərzində trafikin planlaşdırılması və xidmət edilməsi fikri bizi cəlbedici etdi.

Bu asan deyildi. 2019-cu ilin əvvəlində köç etdiyimiz dövrdə Kubernetes klasterimizdəki kritik bir kütləyə çatdıq və nəqliyyatın həcmi, çoxluq ölçüsü və DNS səbəbiylə müxtəlif çətinliklərlə qarşılaşmağa başladıq. 200 xidmət köçürmək və Kubernetes klasterini cəmi 1000 qovşaq, 15,000 pods və 48.000 işləyən konteynerdə idarə etmək üçün maraqlı problemləri həll etdik.

Necə

2018-ci ilin yanvar ayından başlayaraq miqrasiya səylərinin müxtəlif mərhələlərindən keçərək yolumuzu davam etdirdik. Bütün xidmətlərimizi konteynerləşdirərək Kubernetes'in ev sahibi bir sıra sahələrə yerləşdirməsindən başladıq. Oktyabr ayından başlayaraq, bütün miras xidmətlərimizi metodik olaraq Kubernetes'ə köçürməyə başladıq. Növbəti ilin mart ayına qədər köçümüzü başa çatdırdıq və Tinder platforması indi yalnız Kubernetesdə işləyir.

Kubernetes üçün Şəkillərin qurulması

Kubernetes çoxluğunda işləyən mikroservislər üçün 30-dan çox mənbə kodu depo var. Bu depolardakı kod eyni dildə çox işləmə mühiti olan müxtəlif dillərdə (məsələn, Node.js, Java, Scala, Go) yazılmışdır.

Qurma sistemi, adətən Dockerfile və bir sıra shell əmrlərindən ibarət olan hər mikroservis üçün tam özelleştirilebilir bir "qurulma kontekstində" işləmək üçün hazırlanmışdır. Onların məzmunu tamamilə özelleştirilebilir, bu qurulma kontekstləri hamısı standart bir formata uyğun yazılır. Qurma kontekstlərinin standartlaşdırılması vahid bir quruluş sisteminin bütün mikroservisləri idarə etməyə imkan verir.

Şəkil 1-1. Builder konteyneri vasitəsilə standartlaşdırılmış tikinti prosesi

İş vaxtı mühitləri arasındakı maksimum ardıcıllığa nail olmaq üçün inkişaf və sınaq mərhələsində eyni qurulma prosesi istifadə olunur. Bu platformada ardıcıl bir mühit təmin etmək üçün bir yol hazırlamalı olduğumuz zaman unikal bir problem yaratdı. Nəticədə, bütün qurma prosesləri xüsusi bir "İnşaatçı" konteynerində aparılır.

İnşaatçı konteynerinin tətbiqi bir sıra qabaqcıl Docker texnikalarını tələb edir. Bu Builder konteyner yerli istifadəçi identifikatorunu və sirlərini (məsələn, SSH açarı, AWS etimadnaməsi və s.) Tinder şəxsi depolarına daxil olmaq üçün tələb olunur. İnşaat əsərlərini saxlamaq üçün təbii bir yola sahib olmaq üçün mənbə kodu olan yerli qovluqları birləşdirir. Bu yanaşma performansını yaxşılaşdırır, çünki Builder konteyneri və ev maşını arasında quraşdırılmış əsərlərin surətini çıxarmağı aradan qaldırır. Saxlanılan artefaktlar növbəti dəfə daha konfiqurasiyasız təkrar istifadə olunur.

Müəyyən xidmətlər üçün tərtib vaxtı mühitini iş vaxtı mühiti ilə uyğunlaşdırmaq üçün Builder-də başqa bir konteyner yaratmalı olduq (məsələn, Node.js bcrypt kitabxanasını quraşdırmaq platformaya məxsus ikili əsərlər yaradır). Kompilyasiya vaxtı tələbləri xidmətlər arasında fərqlənə bilər və son Dockerfile tez hazırlanır.

Kubernetes Klaster Memarlıq və Miqrasiya

Çoxluq ölçüsü

Amazon EC2 nümunələrində avtomatlaşdırılmış çoxluq təmin edilməsi üçün kube-lardan istifadə etmək qərarına gəldik. Erkən, hər şeyi bir ümumi node hovuzda işləyirdik. Resurslardan daha yaxşı istifadə etmək üçün iş yüklərini fərqli ölçülərə və növlərə ayırmaq ehtiyacını tez bir zamanda müəyyən etdik. Bunun səbəbi, daha az ağır yivli podların birlikdə işlənməsi, daha çox sayda tək yivli podlarla birlikdə yaşamaqdan daha çox proqnozlaşdırılan performans nəticələrini verməsi idi.

Qərar verdik:

  • monitorinq üçün m5.4 ölçü (Prometheus)
  • Node.js iş yükü üçün c5.4x böyütmək (tək yivli iş yükü)
  • Java və Go üçün c5.2x böyütmək (çox yivli iş yükü)
  • nəzarət təyyarəsi üçün c5.4 ölçü (3 qovşaq)

Köç

İrəli infrastrukturumuzdan Kubernetes'ə köçmək üçün hazırlıq addımlarından biri, mövcud xidmət-xidmət əlaqəsini müəyyən bir Virtual Şəxsi Bulud (VPC) alt şəbəkəsində yaradılan yeni Elastik Yük Balanslaşdırıcılarına (ELBs) yönəltmək idi. Bu alt şəbəkə Kubernetes VPC-yə baxıldı. Bu, xidmət asılılıqları üçün xüsusi sifariş almadan modulları xırda bir şəkildə köçürməyə imkan verdi.

Bu son nöqtələr, hər yeni ELB-yə işarə edən CNAME olan ölçülmüş DNS qeyd dəstləri istifadə edərək yaradıldı. Kəsmə üçün 0 kub ağırlığı olan yeni Kubernetes xidmət ELB-yə işarə edərək yeni bir qeyd əlavə etdik. Daha sonra Yaşayış vaxtını (TTL) 0-a yazdıq. Yaşlı və yeni çəkilər daha sonra yavaş-yavaş düzəldildi. nəticədə 100% yeni serverdə bitir. Kəsmə başa çatdıqdan sonra TTL daha məqsədəuyğun bir şeyə qoyuldu.

Java modullarımız aşağı DNS TTL-lərə layiq görüldü, lakin Node tətbiqlərimiz alınmadı. Mühəndislərimizdən biri bağlantı hovuz kodunun bir hissəsini, hər 60-cı illərdə hovuzları təzələyəcək bir menecerə yazmaq üçün yenidən yazdı. Bu, bizim üçün çox yaxşı bir nəticə göstərmədi.

Öyrənmələr

Şəbəkə parça məhdudiyyətləri

8 yanvar 2019-cu il səhər erkən saatlarda Tinder Platforması davamlı kəsilməyə məruz qaldı. Əvvəllər səhər platforma gecikməsində əlaqəsiz bir artıma cavab olaraq, çoxluqda pod və node sayları ölçüldü. Bu, bütün qovşaqlarımızda ARP cache tükənməsi ilə nəticələndi.

ARP cache ilə əlaqəli üç Linux dəyərləri var:

Kredit

gc_thresh3 sərt qapaqdır. "Qonşu süfrəsinin daşması" giriş girişlərini əldə edirsinizsə, bu ARP önbelleğindəki sinxron zibil toplama (GC) sonra da qonşu girişini saxlayacaq yer olmadığını göstərir. Bu vəziyyətdə, çek sadəcə paketi tamamilə atır.

Flanel'i Kubernetesdəki şəbəkə parça olaraq istifadə edirik. Paketlər VXLAN vasitəsilə göndərilir. VXLAN, Layer 3 şəbəkəsi üzərindəki Layer 2 üst-üstə düşmə sxemidir. Layer 2 şəbəkə seqmentlərini genişləndirmək üçün bir vasitə təmin etmək üçün MAC Ünvanı İstifadəçi Datagram Protokolu (MAC-in-UDP) istifadə edir. Fiziki məlumat mərkəzi şəbəkəsi üzərindəki nəqliyyat protokolu IP plus UDP-dir.

Şəkil 2-1 Flanel diaqramı (kredit)

Şəkil 2-2 VXLAN paketi (kredit)

Hər Kubernetes işçi nodu özünün / 24 virtual ünvan sahəsini daha böyük / 9 blokdan ayırır. Hər node üçün bu 1 marşrut cədvəli girişi, 1 ARP masa girişi (flanel.1 interfeysdə) və 1 ekspedisiya bazası (FDB) girişi ilə nəticələnir. Bunlar işçi nodu ilk işə salındıqda və ya hər yeni node aşkar edildikdə əlavə olunur.

Bundan əlavə, node-pod (və ya pod-pod) rabitə nəticədə eth0 interfeysi (yuxarıdakı Flannel diaqramında təsvir olunur) üzərində axır. Bu, hər bir uyğun node mənbəyi və node təyinatı üçün ARP cədvəlində əlavə bir giriş əldə edəcəkdir.

Ətrafımızda bu ünsiyyət növü çox yaygındır. Kubernetes xidmət obyektlərimiz üçün bir ELB yaradılır və Kubernetes hər nodu ELB ilə qeyd edir. ELB xəbərdar deyil və seçilmiş node paketin son təyinat yeri ola bilməz. Bunun səbəbi, node paketi ELB-dən aldıqda, xidmət üçün iptable qaydalarını qiymətləndirir və təsadüfi başqa bir node üzərində bir pod seçir.

Kəsilmə zamanı çoxluqda 605 ümumi qovşaq vardı. Yuxarıda göstərilən səbəblərə görə, bu, standart gc_thresh3 dəyərini tutmaq üçün kifayət idi. Bu baş verdikdə, yalnız paketlər atılmır, ARP cədvəlində bütün Flannel / 24 virtual ünvan sahəsi boşdur. Pod rabitə ilə DNS axtarışları uğursuz. (DNS çoxluq içində yerləşdirilmişdir, daha sonra bu məqalədə daha ətraflı izah ediləcəkdir.)

Həll etmək üçün gc_thresh1, gc_thresh2 və gc_thresh3 dəyərləri qaldırılır və itkin düşmüş şəbəkələri yenidən qeyd etmək üçün Flannel yenidən işə salınmalıdır.

Gözlənilməz dərəcədə DNS çalışır

Köçməyimizi təmin etmək üçün, xidmətlərimiz üçün trafikin formalaşması və irsdən Kubernetes-ə qədər artan kəsilməsini asanlaşdırmaq üçün DNS-dən çox istifadə etdik. Əlaqəli Route53 RecordSets-də nisbətən aşağı TTL dəyərlərini təyin etdik. Keçmiş infrastrukturumuzu EC2 instansiyalarında işlədikdə, həll konfiqurasiya Amazon-un DNS-nə işarə etdi. Bunu məqbul saydıq və xidmətlərimiz və Amazon xidmətləri (məsələn, DynamoDB) üçün nisbətən aşağı bir TTL-in dəyəri nəzərə çarpmadı.

Kubernetes'ə getdikcə daha çox xidmət gəmisiylə, saniyədə 250.000 sorğuya cavab verən DNS xidmətini tapdıq. Tətbiqlərimiz daxilində aralıq və təsirli DNS axtarış vaxtı ilə qarşılaşdıq. Bu, tükənən bir tənzimləmə səyinə və DNS provayderinin bir anda 120 nüvəni istehlak edən 1000 pods-a çatdığı CoreDNS yerləşdirilməsinə keçməsinə baxmayaraq baş verdi.

Digər mümkün səbəbləri və həll yollarını araşdırarkən, Linux paket filtrləmə çərçivəsi netfilterinə təsir edən bir yarış vəziyyətini izah edən bir məqalə tapdıq. Gördüyümüz DNS fasilələri, Flannel interfeysindəki artan bir əlavə_fail sayğac ilə birlikdə məqalənin nəticələri ilə uyğunlaşdırıldı.

Məsələ Mənbə və Destinasiya Şəbəkə Ünvan Tərcümə (SNAT və DNAT) və sonradan bağlantı cədvəlinə daxil edilməsi zamanı baş verir. Daxili müzakirə edilən və icma tərəfindən təklif olunan bir həll yolu DNS'i işçi qovluğuna aparmaq idi. Bu halda:

  • SNAT lazım deyil, çünki trafik node üzərində yerli olaraq qalır. Bu eth0 interfeysi arasında ötürülməsinə ehtiyac yoxdur.
  • DNAT lazım deyil, çünki təyinat IP node yerli və iptables qaydalarına təsadüfi seçilmiş bir pod deyil.

Bu yanaşma ilə irəliləməyə qərar verdik. CoreDNS Kubernetes-də DaemonSet olaraq yerləşdirildi və biz qovelet - klaster-dns əmr bayrağı ilə konfiqurasiya edərək nodun yerli DNS serverini hər pod-un həlli.conf-a vurduq. Çalışma DNS fasilələri üçün təsirli oldu.

Ancaq yenə də düşmüş paketləri və Flannel interfeysinin insert_fail counter artımını görürük. Yuxarıdakı araşdırmadan sonra da davam edəcək, çünki yalnız DNS trafikinə görə SNAT və / və ya DNAT-dan çəkinmişik. Yarış şərti digər nəqliyyat növləri üçün hələ də baş verəcəkdir. Xoşbəxtlikdən, paketlərimizin əksəriyyəti TCP-dir və vəziyyət yarandıqda paketlər uğurla geri göndəriləcəkdir. Hər növ nəqliyyat üçün uzun müddətli bir düzəliş hələ müzakirə etdiyimiz bir şeydir.

Daha yaxşı yük balansına nail olmaq üçün elçidən istifadə

Geri xidmətlərimizi Kubernetes'ə köçürdükdə, podalar arasındakı balanssız yükdən əziyyət çəkməyə başladıq. HTTP Keepalive səbəbiylə ELB əlaqələrinin hər yayma yerləşdirilməsinin ilk hazır podlarına yapışdırıldığını aşkar etdik, buna görə əksər trafik mövcud podların az bir hissəsindən axdı. Keçirdiyimiz ilk yumşalmalardan biri ən pis cinayətkarlar üçün yeni yerlərdə 100% MaxSurge istifadə etmək idi. Bəzi daha böyük yerləşdirmə ilə bu cüzi təsirli və davamlı deyil.

Tətbiq etdiyimiz başqa bir yumşaldıcı yer, digər ağır podlar ilə yanaşı daha çox baş otağına sahib olmaq üçün kritik xidmətlərdəki qaynaq tələblərini süni şəkildə şişirtmək idi. Bu da ehtiyat tullantıları səbəbindən uzun müddətdə dayanıqlı deyildi və Node tətbiqlərimiz tək yivli idi və beləliklə 1 nüvəyə təsirli şəkildə bağlandı. Yeganə aydın həll yolu daha yaxşı yük balansından istifadə etmək idi.

Elçini qiymətləndirmək üçün daxili baxırdıq. Bu, bizə çox məhdud bir şəkildə yerləşdirmək və dərhal qazanc əldə etmək şansı verdi. Elçi, açıq xidmət mənbəyi, geniş xidmət yönümlü arxitekturaları üçün hazırlanmış Layer 7 proxy. Avtomatik təkrar cəhdlər, dövrələrin kəsilməsi və qlobal dərəcələrin məhdudlaşdırılması da daxil olmaqla qabaqcıl yük balanslaşdırma texnikalarını tətbiq edə bilir.

Gördüyümüz konfiqurasiya, yerli marşrut limanına vurmaq üçün bir marşrutu və çoxluğu olan hər podun yanında bir elçi səkisinin olması idi. Potensial kaskadın həcmini minimuma endirmək və kiçik bir partlayış radiusunu saxlamaq üçün hər xidmət üçün hər mövcudluq zonasında (AZ) bir yerləşdirmə olan ön proxy Envoy podslarından istifadə etdik. Bunlar mühəndislərimizdən birinin xidmət üçün kiçik bir kəşf mexanizmini vurdu.

Xidmət ön cəbhəçiləri daha sonra yuxarıdan gələn bir çoxluq və marşrutla bu xidmət kəşf mexanizmindən istifadə etdilər. Biz ağlabatan zaman kəsiklərini konfiqurasiya etdik, bütün kəsicilərin parametrlərini artırdıq və sonra keçid uğursuzluqları və hamar yerdəyişmələrə kömək etmək üçün minimal təkrarlama konfiqurasiyasını etdik. Bu ön elçilərin hər birinin xidmətlərini bir TCP ELB ilə qarşıladıq. Əsas ön proxy qatımızı qoruyan müəyyən elçi podslarında bağlanmış olsa belə, onlar yükü daha yaxşı idarə edə bildilər və minimum_request vasitəsi ilə balansa konfiqurasiya edildi.

Yerləşdirmə üçün həm tətbiqetmədə, həm də sidecar podda bir preStop çəngəlindən istifadə etdik. Sidecar sağlamlıq çeki adlanan bu çəngəl, kiçik bir yuxu ilə birlikdə, işığın bağlantısının tamamlanması və qurudulması üçün biraz vaxt vermək üçün.

Sürətlə hərəkət edə bilməyimizin bir səbəbi, normal Prometheus qurğumuzla asanlıqla inteqrasiya edə biləcəyimiz zəngin ölçülər ilə bağlı idi. Bu, konfiqurasiya parametrlərini təkrarladığımız və trafikin kəsildiyi zaman nəyin baş verdiyini görməyə imkan verdi.

Nəticələr dərhal və aydın oldu. Ən balanssız xidmətlərdən başladıq və bu anda çoxluqdakı ən vacib xidmətlərdən ikisinin qarşısında çalışırıq. Bu il daha inkişaf etmiş bir xidmət kəşfi, dövrə sınması, kənar təsbit, dərəcəni məhdudlaşdırma və izləmə ilə tam xidmətli bir mesha keçməyi planlaşdırırıq.

Şəkil 3-1 Bir elçinin göndərilməsi zamanı bir xidmətin CPU-nun yaxınlaşması

Nəticə

Bu öyrənmələr və əlavə tədqiqatlar sayəsində böyük Kubernetes klasterlərinin dizaynını, yerləşdirilməsini və fəaliyyət göstərməsini çox yaxşı bilən güclü daxili infrastruktur qrupu hazırladıq. Tinderin bütün mühəndislik təşkilatı indi tətbiqlərini Kubernetesdə necə konteynerləşdirmək və yerləşdirmək barədə bilik və təcrübəyə malikdir.

Əvvəlki infrastrukturumuzda əlavə miqyas tələb olunduqda, yeni EC2 nümunələrinin internetə girməsini gözləmək üçün bir neçə dəqiqə əziyyət çəkdik. Konteynerlər dəqiqələrdən fərqli olaraq saniyələr ərzində nəqliyyat qrafikini verir və xidmət göstərir. Tək bir EC2 nümunəsində birdən çox qabın planlaşdırılması da üfüqi sıxlığı təmin edir. Nəticədə, bir il ilə müqayisədə 2019-cu ildə EC2-də əsaslı qənaət layihəsini həyata keçiririk.

Təxminən iki il çəkdi, amma 2019-cu ilin mart ayında köçümüzü sona çatdırdıq. Tinder platforması, yalnız 200 xidmət, 1000 qovşaq, 15,000 pods və 48,000 işləyən konteynerdən ibarət Kubernetes çoxluğunda işləyir. İnfrastruktur artıq əməliyyat qruplarımız üçün qorunan bir vəzifə deyil. Bunun əvəzinə, təşkilatın bütün mühəndisləri bu məsuliyyəti bölüşür və tətbiqlərinin necə qurulduğunu və hər şey kod kimi istifadə edildiyini idarə edirlər.