Tinderning Kubernetesga o'tishi

Eslatma. tarjima.: Yaqinda dunyoga mashhur Tinder xizmati xodimlari o'z infratuzilmasini Kubernetesga ko'chirishning ba'zi texnik tafsilotlari bilan bo'lishdi. Jarayon deyarli ikki yil davom etdi va natijada K8-larda 200 ming konteynerda joylashtirilgan 48 ta xizmatdan iborat juda keng ko'lamli platforma ishga tushirildi. Tinder muhandislari qanday qiziqarli qiyinchiliklarga duch kelishdi va ular qanday natijalarga erishishdi? Ushbu tarjimani o'qing.

Tinderning Kubernetesga o'tishi

Nima uchun?

Deyarli ikki yil oldin, Tinder o'z platformasini Kubernetesga ko'chirishga qaror qildi. Kubernetes Tinder jamoasiga konteynerlarni joylashtirish va o'zgarmas joylashtirish orqali minimal kuch bilan ishlab chiqarishga o'tish imkonini beradi. (o'zgarmas joylashtirish). Bunday holda, ilovalarni yig'ish, ularni joylashtirish va infratuzilmaning o'zi kod bilan noyob tarzda aniqlanadi.

Shuningdek, biz miqyoslilik va barqarorlik muammosiga yechim izladik. Masshtabni o'zgartirish muhim bo'lganida, biz ko'pincha yangi EC2 nusxalari paydo bo'lishi uchun bir necha daqiqa kutishimiz kerak edi. Konteynerlarni ishga tushirish va tirbandlikka daqiqalar o'rniga soniyalarda xizmat ko'rsatishni boshlash g'oyasi biz uchun juda jozibali bo'ldi.

Jarayon qiyin bo'lib chiqdi. 2019 yil boshida bizning migratsiyamiz davomida Kubernetes klasteri kritik massaga yetdi va biz trafik hajmi, klaster hajmi va DNS tufayli turli muammolarga duch kela boshladik. Yo'l davomida biz 200 ta xizmatlarni ko'chirish va 1000 ta tugun, 15000 48000 pods va XNUMX XNUMX ishlaydigan konteynerdan iborat Kubernetes klasterini saqlash bilan bog'liq ko'plab qiziqarli muammolarni hal qildik.

Qanday qilib?

2018-yil yanvar oyidan boshlab biz migratsiyaning turli bosqichlaridan o‘tdik. Biz barcha xizmatlarimizni konteynerlashtirish va ularni Kubernetes sinov bulutli muhitlariga joylashtirishdan boshladik. Oktyabr oyidan boshlab biz barcha mavjud xizmatlarni Kubernetesga metodik ravishda ko'chirishni boshladik. Keyingi yilning mart oyigacha biz migratsiyani yakunladik va endi Tinder platformasi faqat Kubernetesda ishlaydi.

Kubernetes uchun rasmlar yaratish

Bizda Kubernetes klasterida ishlaydigan mikroservislar uchun 30 dan ortiq manba kodlari omborlari mavjud. Ushbu omborlardagi kod turli tillarda (masalan, Node.js, Java, Scala, Go) bir xil til uchun bir nechta ish vaqti muhitlari bilan yozilgan.

Qurilish tizimi har bir mikroservis uchun to'liq moslashtirilgan "qurilish konteksti" ni ta'minlash uchun mo'ljallangan. Odatda u Dockerfile va qobiq buyruqlar ro'yxatidan iborat. Ularning mazmuni butunlay sozlanishi va shu bilan birga, ushbu kontekstlarning barchasi standartlashtirilgan formatga muvofiq yozilgan. Qurilish kontekstlarini standartlashtirish bitta qurish tizimiga barcha mikroservislarni boshqarish imkonini beradi.

Tinderning Kubernetesga o'tishi
1-1-rasm. Builder konteyneri orqali standartlashtirilgan qurilish jarayoni

Ish vaqtlari orasidagi maksimal muvofiqlikka erishish uchun (ish vaqti muhitlari) ishlab chiqish va sinovdan o'tkazishda bir xil qurish jarayoni qo'llaniladi. Biz juda qiziqarli muammoga duch keldik: biz butun platforma bo'ylab qurilish muhitining izchilligini ta'minlash usulini ishlab chiqishimiz kerak edi. Bunga erishish uchun barcha yig'ish jarayonlari maxsus idish ichida amalga oshiriladi. quruvchi.

Uning konteynerni amalga oshirishi ilg'or Docker texnikasini talab qildi. Builder shaxsiy Tinder omborlariga kirish uchun zarur bo'lgan mahalliy foydalanuvchi identifikatorini va sirlarni (masalan, SSH kaliti, AWS hisob ma'lumotlari va boshqalar) meros qilib oladi. Qurilish artefaktlarini tabiiy ravishda saqlash uchun manbalarni o'z ichiga olgan mahalliy kataloglarni o'rnatadi. Ushbu yondashuv unumdorlikni yaxshilaydi, chunki u Builder konteyneri va xost o'rtasida qurilish artefaktlarini nusxalash zaruratini yo'q qiladi. Saqlangan qurilish artefaktlari qo'shimcha konfiguratsiyalarsiz qayta ishlatilishi mumkin.

Ba'zi xizmatlar uchun biz kompilyatsiya muhitini ish vaqti muhitiga solishtirish uchun boshqa konteyner yaratishimiz kerak edi (masalan, Node.js bcrypt kutubxonasi o'rnatish vaqtida platformaga xos ikkilik artefaktlarni yaratadi). Kompilyatsiya jarayonida talablar xizmatlarga qarab farq qilishi mumkin va yakuniy Dockerfile tezda kompilyatsiya qilinadi.

Kubernetes klaster arxitekturasi va migratsiya

Klaster hajmini boshqarish

Biz foydalanishga qaror qildik kube-aws Amazon EC2 nusxalarida avtomatlashtirilgan klasterni joylashtirish uchun. Eng boshida hamma narsa bitta umumiy tugunlar hovuzida ishlagan. Resurslardan samaraliroq foydalanish uchun ish yuklarini o‘lcham va namuna turi bo‘yicha ajratish zarurligini tezda angladik. Mantiq shundan iboratki, bir nechta yuklangan ko'p tarmoqli podlarni ishga tushirish, ularning ko'p sonli bitta ipli podlar bilan birga yashashidan ko'ra, unumdorlik nuqtai nazaridan ko'proq prognoz qilinadigan bo'lib chiqdi.

Oxir-oqibat biz qaror qildik:

  • m5.4x katta — kuzatish uchun (Prometey);
  • c5.4x katta - Node.js ish yuki uchun (bir torli ish yuki);
  • c5.2x katta - Java va Go uchun (ko'p bosqichli ish yuki);
  • c5.4x katta — boshqaruv paneli uchun (3 tugun).

Migratsiya

Eski infratuzilmadan Kubernetesga o'tish uchun tayyorgarlik bosqichlaridan biri xizmatlar o'rtasidagi mavjud to'g'ridan-to'g'ri aloqani yangi yuk balanslagichlariga (Elastic Load Balancers (ELB)) yo'naltirish edi. Ular virtual xususiy bulutning (VPC) ma'lum bir quyi tarmog'ida yaratilgan. Bu quyi tarmoq Kubernetes VPC ga ulangan. Bu bizga modullarni xizmatga bog'liqliklarning aniq tartibini hisobga olmagan holda bosqichma-bosqich ko'chirish imkonini berdi.

Ushbu so'nggi nuqtalar har bir yangi ELBga ishora qiluvchi CNAME-larga ega bo'lgan DNS yozuvlarining vaznli to'plamlari yordamida yaratilgan. Oʻtish uchun biz Kubernetes xizmatining yangi ELB ga ishora qiluvchi 0 ogʻirlikdagi yangi yozuvni qoʻshdik. Soʻngra biz kiritishning Yashash vaqtini (TTL) 0 ga oʻrnatdik. Shundan soʻng eski va yangi vaznlar oʻrnatildi. asta-sekin sozlandi va oxir-oqibat yukning 100% yangi serverga yuborildi. Kommutatsiya tugagandan so'ng, TTL qiymati yanada mos darajaga qaytdi.

Bizda mavjud bo'lgan Java modullari past TTL DNS bilan bardosh bera olardi, ammo Node ilovalari buni qila olmadi. Muhandislardan biri ulanish hovuz kodining bir qismini qayta yozdi va uni har 60 soniyada hovuzlarni yangilab turadigan menejerga o'rab oldi. Tanlangan yondashuv juda yaxshi ishladi va unumdorlikni sezilarli darajada yomonlashtirmadi.

Kurslar

Tarmoq matosining chegaralari

8-yil 2019-yanvar kuni erta tongda Tinder platformasi kutilmaganda qulab tushdi. O'sha kuni ertalab platformadagi kechikishning bog'liq bo'lmagan o'sishiga javoban, klasterdagi podalar va tugunlar soni ko'paydi. Bu barcha tugunlarimizda ARP keshining tugashiga olib keldi.

ARP keshi bilan bog'liq uchta Linux varianti mavjud:

Tinderning Kubernetesga o'tishi
(manba)

gc_thresh3 - bu qattiq chegara. Jurnalda "qo'shni jadvalni to'ldirish" yozuvlarining ko'rinishi sinxron axlat yig'ish (GC) dan keyin ham qo'shni yozuvni saqlash uchun ARP keshida etarli joy yo'qligini anglatadi. Bunday holda, yadro paketni butunlay tashlab yubordi.

Biz foydalanamiz Flanel Kubernetesda tarmoq matosi sifatida. Paketlar VXLAN orqali uzatiladi. VXLAN L2 tarmog'ining tepasida ko'tarilgan L3 tunnelidir. Texnologiya MAC-in-UDP (MAC Address-in-User Datagram Protocol) inkapsulyatsiyasidan foydalanadi va Layer 2 tarmoq segmentlarini kengaytirish imkonini beradi. Jismoniy ma'lumotlar markazi tarmog'idagi transport protokoli IP plus UDP hisoblanadi.

Tinderning Kubernetesga o'tishi
2-1-rasm. Flanel diagrammasi (manba)

Tinderning Kubernetesga o'tishi
2-2-rasm. VXLAN paketi (manba)

Har bir Kubernetes ishchi tuguni kattaroq /24 blokidan /9 maskasi bilan virtual manzil maydonini ajratadi. Har bir tugun uchun bu degani marshrutlash jadvalidagi bitta yozuv, ARP jadvalidagi bitta yozuv (flanel.1 interfeysida) va kommutatsiya jadvalidagi (FDB) bitta yozuv. Ular ishchi tugun birinchi marta ishga tushirilganda yoki har safar yangi tugun ochilganda qo'shiladi.

Bundan tashqari, tugun-pod (yoki pod-pod) aloqasi oxir-oqibat interfeys orqali o'tadi eth0 (yuqoridagi Flanel diagrammasida ko'rsatilganidek). Bu har bir mos manba va maqsad xost uchun ARP jadvaliga qo'shimcha yozuvni keltirib chiqaradi.

Bizning muhitimizda bu turdagi aloqa juda keng tarqalgan. Kubernetesdagi xizmat ko'rsatish ob'ektlari uchun ELB yaratiladi va Kubernetes har bir tugunni ELB bilan qayd qiladi. ELB podlar haqida hech narsa bilmaydi va tanlangan tugun paketning yakuniy manzili bo'lmasligi mumkin. Gap shundaki, tugun ELB dan paketni olganda, uni qoidalarni hisobga olgan holda ko'rib chiqadi. iptables muayyan xizmat uchun va tasodifiy boshqa tugundagi podani tanlaydi.

Muvaffaqiyatsizlik vaqtida klasterda 605 ta tugun mavjud edi. Yuqorida aytib o'tilgan sabablarga ko'ra, bu muhimlikni bartaraf etish uchun etarli edi gc_thresh3, bu standart hisoblanadi. Bu sodir bo'lganda, nafaqat paketlar tashlab keta boshlaydi, balki /24 niqobli butun Flanel virtual manzil maydoni ARP jadvalidan yo'qoladi. Node-pod aloqasi va DNS so'rovlari uzilgan (DNS klasterda joylashtirilgan; batafsil ma'lumot uchun ushbu maqolani keyinroq o'qing).

Ushbu muammoni hal qilish uchun siz qiymatlarni oshirishingiz kerak gc_thresh1, gc_thresh2 и gc_thresh3 va etishmayotgan tarmoqlarni qayta ro'yxatdan o'tkazish uchun Flannel-ni qayta ishga tushiring.

Kutilmagan DNS masshtablashi

Migratsiya jarayonida biz trafikni boshqarish va xizmatlarni eski infratuzilmadan Kubernetesga bosqichma-bosqich o‘tkazish uchun DNS-dan faol foydalandik. Biz Route53-da bog'langan RecordSets uchun nisbatan past TTL qiymatlarini o'rnatdik. Qadimgi infratuzilma EC2 nusxalarida ishlayotganida, bizning hal qiluvchi konfiguratsiyamiz Amazon DNS-ga ishora qildi. Biz buni tabiiy deb qabul qildik va past TTLning xizmatlarimiz va Amazon xizmatlariga (masalan, DynamoDB) ta'siri deyarli sezilmadi.

Xizmatlarni Kubernetesga ko‘chirganimizda DNS soniyasiga 250 ming so‘rovni qayta ishlayotganini aniqladik. Natijada, ilovalar DNS so'rovlari uchun doimiy va jiddiy tanaffuslarni boshdan kechira boshladi. Bu DNS provayderini optimallashtirish va CoreDNS ga o'tkazish bo'yicha ajoyib sa'y-harakatlarga qaramay sodir bo'ldi (u eng yuqori yuklanishda 1000 yadroda ishlaydigan 120 ta podkaga yetdi).

Boshqa mumkin bo'lgan sabablar va echimlarni o'rganar ekanmiz, biz kashf qildik maqola, paketlarni filtrlash tizimiga ta'sir qiluvchi poyga sharoitlarini tavsiflash netfiltr Linuxda. Biz kuzatgan taym-autlar ortib borayotgan hisoblagich bilan birga insert_failed Flanel interfeysidagi ma'lumotlar maqolaning topilmalariga mos keldi.

Muammo manba va maqsad tarmoq manzilini tarjima qilish (SNAT va DNAT) va keyinchalik jadvalga kirish bosqichida yuzaga keladi. aloqa. Ichkarida muhokama qilingan va hamjamiyat tomonidan taklif qilingan vaqtinchalik echimlardan biri DNS-ni ishchi tugunning o'ziga ko'chirish edi. Ushbu holatda:

  • SNAT kerak emas, chunki trafik tugun ichida qoladi. Uni interfeys orqali yo'naltirish shart emas eth0.
  • DNAT kerak emas, chunki maqsad IP tugun uchun mahalliy bo'lib, qoidalarga ko'ra tasodifiy tanlangan pod emas. iptables.

Biz ushbu yondashuvni davom ettirishga qaror qildik. CoreDNS Kubernetes-da DaemonSet sifatida o'rnatildi va biz mahalliy tugun DNS serverini joriy qildik. hal qiluvchi.conf bayroqni o'rnatish orqali har bir pod --klaster-dns jamoalari kublet . Ushbu yechim DNS kutish vaqtlari uchun samarali bo'ldi.

Biroq, biz hali ham paketlarning yo'qolishini va hisoblagichning ko'payishini ko'rdik insert_failed Flanel interfeysida. Bu vaqtinchalik yechim amalga oshirilgandan keyin ham davom etdi, chunki biz faqat DNS-trafik uchun SNAT va/yoki DNAT-ni yo'q qila oldik. Boshqa transport turlari uchun poyga sharoitlari saqlanib qoldi. Yaxshiyamki, bizning paketlarimizning aksariyati TCP va agar muammo yuzaga kelsa, ular shunchaki qayta uzatiladi. Biz hali ham barcha turdagi trafik uchun mos echim topishga harakat qilmoqdamiz.

Yukni yaxshiroq muvozanatlash uchun elchidan foydalanish

Backend xizmatlarini Kubernetes-ga o'tkazganimizda, biz podalar orasidagi muvozanatsiz yukdan aziyat cheka boshladik. Biz HTTP Keepalive ELB ulanishlarini har bir tarqatishning birinchi tayyor podkastlariga osib qo'yishiga sabab bo'lganini aniqladik. Shunday qilib, trafikning asosiy qismi mavjud bo'lgan podsning kichik foizidan o'tdi. Biz sinovdan o'tkazgan birinchi yechim MaxSurge-ni eng yomon holatlar uchun yangi o'rnatishlarda 100% ga o'rnatish edi. Kattaroq joylashtirish nuqtai nazaridan ta'sir ahamiyatsiz va umidsiz bo'lib chiqdi.

Biz foydalangan yana bir yechim muhim xizmatlar uchun resurs so'rovlarini sun'iy ravishda oshirish edi. Bunday holda, boshqa og'ir podalar bilan solishtirganda, yaqin joyda joylashgan podalar manevr qilish uchun ko'proq joyga ega bo'ladi. Bu uzoq muddatda ham ishlamaydi, chunki bu resurslarni behuda sarflashga olib keladi. Bundan tashqari, bizning Node ilovalarimiz bitta ipli edi va shunga mos ravishda faqat bitta yadrodan foydalanishi mumkin edi. Yagona haqiqiy yechim yukni yaxshiroq muvozanatlashdan foydalanish edi.

Biz uzoq vaqtdan beri to'liq qadrlashni xohlaymiz elchisi. Mavjud vaziyat bizga uni juda cheklangan tarzda joylashtirishga va darhol natijalarga erishishga imkon berdi. Envoy - bu katta SOA ilovalari uchun mo'ljallangan yuqori samarali, ochiq manbali, qatlam-XNUMX proksi-server. U yukni muvozanatlashning ilg'or usullarini, shu jumladan avtomatik qayta urinishlarni, o'chirgichlarni va global tezlikni cheklashni amalga oshirishi mumkin. (Eslatma. tarjima.: Bu haqda ko'proq ma'lumotni o'qishingiz mumkin Ushbu maqola Elchiga asoslangan Istio haqida.)

Biz quyidagi konfiguratsiyani o'ylab topdik: har bir podkast va bitta marshrut uchun Envoy yonboshiga ega bo'ling va klasterni port orqali mahalliy konteynerga ulang. Potensial kaskadni kamaytirish va kichik zarba radiusini saqlab qolish uchun biz har bir xizmat uchun har bir Availability Zone (AZ) uchun bittadan Envoy old proksi podkastlaridan foydalandik. Ular bizning muhandislarimizdan biri tomonidan yozilgan oddiy xizmatni kashf qilish mexanizmiga tayandilar, u shunchaki berilgan xizmat uchun har bir AZ-da podalar ro'yxatini qaytardi.

Keyin xizmat ko'rsatish xodimlari ushbu xizmatni aniqlash mexanizmidan bitta yuqori oqim klasteri va marshruti bilan foydalanishdi. Yagona nosozliklarni bartaraf etish va uzluksiz oʻrnatishni taʼminlash uchun biz tegishli vaqtni oʻrnatdik, barcha oʻchirgich sozlamalarini oshirdik va minimal qayta urinish konfiguratsiyasini qoʻshdik. Biz ushbu xizmatning har bir oldingi elchilari oldiga TCP ELB ni joylashtirdik. Bizning asosiy proksi-server qatlamimizdagi saqlovchi ba'zi Envoy podslariga yopishtirilgan bo'lsa ham, ular yukni ancha yaxshi ko'tara olishdi va backenddagi minimum_request orqali muvozanatlash uchun sozlangan.

Joylashtirish uchun biz dastur podkastlari va yonbosh podkastlarida preStop kancasidan foydalandik. Ilgak yonbosh konteynerida joylashgan administrator so‘nggi nuqtasi holatini tekshirishda xatolikka yo‘l qo‘ydi va faol ulanishlarni tugatishga ruxsat berish uchun bir muddat uxlab qoldi.

Tez harakat qilishimizning sabablaridan biri, biz oddiy Prometey o'rnatilishiga osongina integratsiyalashgan batafsil o'lchovlar bilan bog'liq. Bu bizga konfiguratsiya parametrlarini moslash va trafikni qayta taqsimlashda nima sodir bo'layotganini aniq ko'rish imkonini berdi.

Natijalar darhol va aniq edi. Biz eng muvozanatsiz xizmatlardan boshladik va hozirda u klasterdagi 12 ta eng muhim xizmatlar oldida ishlaydi. Bu yil biz yanada ilg'or xizmat kashfiyoti, kontaktlarning zanglashiga olib kirishi, chegarani aniqlash, tezlikni cheklash va kuzatish bilan to'liq xizmat ko'rsatish tarmog'iga o'tishni rejalashtirmoqdamiz.

Tinderning Kubernetesga o'tishi
3-1-rasm. Elchiga o'tish paytida bitta xizmatning CPU konvergentsiyasi

Tinderning Kubernetesga o'tishi

Tinderning Kubernetesga o'tishi

Yakuniy natija

Ushbu tajriba va qo'shimcha tadqiqotlar orqali biz katta Kubernetes klasterlarini loyihalash, joylashtirish va ishlatish bo'yicha kuchli ko'nikmalarga ega kuchli infratuzilma jamoasini yaratdik. Endi barcha Tinder muhandislari konteynerlarni paketlash va Kubernetes-ga ilovalarni joylashtirish bo'yicha bilim va tajribaga ega.

Eski infratuzilmada qo'shimcha quvvatga ehtiyoj paydo bo'lganda, biz yangi EC2 nusxalarini ishga tushirish uchun bir necha daqiqa kutishimiz kerak edi. Endi konteynerlar ishlay boshlaydi va trafikni daqiqalar o'rniga soniyalar ichida qayta ishlashni boshlaydi. Bitta EC2 misolida bir nechta konteynerlarni rejalashtirish ham yaxshilangan gorizontal konsentratsiyani ta'minlaydi. Natijada, biz 2019 yilda EC2 xarajatlarini o'tgan yilga nisbatan sezilarli darajada kamaytirishni prognoz qilamiz.

Migratsiya deyarli ikki yil davom etdi, ammo biz uni 2019 yil mart oyida yakunladik. Hozirda Tinder platformasi faqat 200 ta xizmat, 1000 ta tugun, 15 000 ta pods va 48 000 ta ishlaydigan konteynerdan iborat Kubernetes klasterida ishlaydi. Infratuzilma endi operatsion guruhlarning yagona sohasi emas. Bizning barcha muhandislarimiz ushbu mas'uliyatni o'rtoqlashadi va faqat kod yordamida o'z ilovalarini yaratish va joylashtirish jarayonini nazorat qiladi.

Tarjimondan PS

Shuningdek, bizning blogimizdagi bir qator maqolalarni o'qing:

Manba: www.habr.com

a Izoh qo'shish