ProHoster > Blog > Ma'muriyat > Kubernetes-da uzoq muddatli ulanishlarni yuklash balansi va masshtablash
Kubernetes-da uzoq muddatli ulanishlarni yuklash balansi va masshtablash
Ushbu maqola sizga Kubernetes-da yuk balansi qanday ishlashini, uzoq muddatli ulanishlarni masshtablashda nima sodir bo'lishini va HTTP/2, gRPC, RSockets, AMQP yoki boshqa uzoq muddatli protokollardan foydalansangiz, nima uchun mijoz tomoni balansini hisobga olishingiz kerakligini tushunishga yordam beradi. .
Kubernetesda trafik qanday qayta taqsimlanishi haqida bir oz
Kubernetes ilovalarni joylashtirish uchun ikkita qulay abstraktsiyani taqdim etadi: Xizmatlar va O'rnatish.
O'rnatish ilovangizning istalgan vaqtda qanday va qancha nusxada ishlashi kerakligini tasvirlaydi. Har bir dastur Pod sifatida joylashtirilgan va IP manzili tayinlangan.
Xizmatlar funksiyasi jihatidan yuk balanslagichiga o'xshaydi. Ular trafikni bir nechta pods bo'ylab taqsimlash uchun mo'ljallangan.
Keling, qanday ko'rinishini ko'rib chiqaylik.
Quyidagi diagrammada siz bir xil dasturning uchta nusxasini va yuk balansini ko'rishingiz mumkin:
Yuk balanslagichi Xizmat deb ataladi va unga IP manzili beriladi. Har qanday kiruvchi so'rov podlardan biriga yo'naltiriladi:
Joylashtirish stsenariysi ilova nusxalari sonini aniqlaydi. Siz deyarli hech qachon to'g'ridan-to'g'ri kengayishingiz shart emas:
Har bir podkastga o'z IP manzili tayinlangan:
Xizmatlarni IP manzillar to'plami sifatida ko'rish foydalidir. Xizmatga har safar kirganingizda IP manzillardan biri roʻyxatdan tanlanadi va maqsad manzil sifatida ishlatiladi.
Bu shunday ko'rinadi.
Xizmatga curl 10.96.45.152 so'rovi keldi:
Xizmat maqsad sifatida uchta pod manzilidan birini tanlaydi:
Trafik ma'lum bir podga yo'naltiriladi:
Agar ilovangiz frontend va backenddan iborat bo'lsa, sizda har biri uchun ham xizmat, ham tarqatish bo'ladi.
Frontend backendga so'rov yuborganda, backend qancha pods xizmat ko'rsatishini aniq bilish shart emas: ular bitta, o'n yoki yuzta bo'lishi mumkin.
Bundan tashqari, frontend orqa qismga xizmat ko'rsatadigan pods manzillari haqida hech narsa bilmaydi.
Frontend backendga so'rov yuborganda, u o'zgarmas serverning IP manzilidan foydalanadi.
Bu shunday ko'rinadi.
1 ostida ichki backend komponentini so'raydi. Backend uchun ma'lum birini tanlash o'rniga, u xizmatga so'rov yuboradi:
Xizmat maqsad manzil sifatida backend podkastlaridan birini tanlaydi:
Trafik xizmat tomonidan tanlangan 1-poddan 5-podga o'tadi:
1 dan past bo'lganlar xizmat orqasida 5 dan kichik kabi qancha podalar yashiringanligini aniq bilmaydi:
Ammo xizmat so'rovlarni qanday taqsimlaydi? Aftidan, round-robin balanslash qo'llaniladimi? Keling, buni aniqlaylik.
Kubernetes xizmatlarida balanslash
Kubernetes xizmatlari mavjud emas. IP manzili va porti tayinlangan xizmat uchun hech qanday jarayon yo'q.
Buni klasterdagi istalgan tugunga kirish va netstat -ntlp buyrug'ini ishga tushirish orqali tekshirishingiz mumkin.
Siz hatto xizmatga ajratilgan IP-manzilni ham topa olmaysiz.
Xizmatning IP-manzili boshqaruv qatlamida, kontrollerda joylashgan va ma'lumotlar bazasida qayd etilgan - va hokazo. Xuddi shu manzil boshqa komponent tomonidan ishlatiladi - kube-proksi.
Kube-proksi barcha xizmatlar uchun IP manzillar ro'yxatini oladi va klasterdagi har bir tugunda iptables qoidalari to'plamini yaratadi.
Ushbu qoidalar: "Agar biz xizmatning IP manzilini ko'rsak, so'rovning maqsad manzilini o'zgartirishimiz va uni podkastlardan biriga yuborishimiz kerak."
Xizmat IP manzili faqat kirish nuqtasi sifatida ishlatiladi va u IP manzili va portni tinglovchi hech qanday jarayon tomonidan xizmat qilmaydi.
Keling, buni ko'rib chiqaylik.
Uchta tugunli klasterni ko'rib chiqing. Har bir tugunning podkastlari bor:
Bej rangga bo'yalgan bog'langan podalar xizmatning bir qismidir. Xizmat jarayon sifatida mavjud emasligi sababli u kulrang rangda ko'rsatilgan:
Birinchi pod xizmatni so'raydi va u bog'langan podslardan biriga o'tishi kerak:
Lekin xizmat mavjud emas, jarayon mavjud emas. Bu qanday ishlaydi?
So'rov tugunni tark etishdan oldin iptables qoidalaridan o'tadi:
Iptables qoidalari xizmat mavjud emasligini biladi va uning IP-manzilini ushbu xizmat bilan bog'langan pods IP manzillaridan biri bilan almashtiradi:
So'rov maqsad manzil sifatida to'g'ri IP manzilni oladi va odatdagidek qayta ishlanadi:
Tarmoq topologiyasiga qarab, so'rov oxir-oqibat podkaga etib boradi:
Iptables balansni yuklay oladimi?
Yo'q, iptables filtrlash uchun ishlatiladi va balanslash uchun mo'ljallanmagan.
Biroq, shunga o'xshash ishlaydigan qoidalar to'plamini yozish mumkin psevdobalansator.
Va bu aynan Kubernetesda amalga oshirilgan narsa.
Agar sizda uchta pods bo'lsa, kube-proksi quyidagi qoidalarni yozadi:
33% ehtimollik bilan birinchi subni tanlang, aks holda keyingi qoidaga o'ting.
50% ehtimollik bilan ikkinchisini tanlang, aks holda keyingi qoidaga o'ting.
ostidagi uchinchisini tanlang.
Bu tizim har bir podani 33% ehtimollik bilan tanlashga olib keladi.
Va Pod 2 1-dan keyin tanlanishiga kafolat yo'q.
nota: iptables tasodifiy taqsimotga ega statistik moduldan foydalanadi. Shunday qilib, muvozanatlash algoritmi tasodifiy tanlashga asoslangan.
Endi siz xizmatlar qanday ishlashini tushunganingizdan so'ng, keling, yanada qiziqarli xizmat stsenariylarini ko'rib chiqaylik.
Kubernetes-dagi uzoq muddatli ulanishlar sukut bo'yicha o'lchamga ega emas
Frontenddan backendgacha bo'lgan har bir HTTP so'roviga alohida TCP ulanishi xizmat ko'rsatadi, u ochiladi va yopiladi.
Agar frontend orqa qismga soniyada 100 ta so'rov yuborsa, u holda 100 xil TCP ulanishlari ochiladi va yopiladi.
Bitta TCP ulanishini ochish va undan keyingi barcha HTTP so'rovlari uchun foydalanish orqali so'rovni qayta ishlash vaqtini va yuklashni qisqartirishingiz mumkin.
HTTP protokolida HTTP saqlab qolish yoki ulanishni qayta ishlatish deb nomlangan xususiyat mavjud. Bunday holda, bitta TCP ulanishi bir nechta HTTP so'rovlari va javoblarini yuborish va qabul qilish uchun ishlatiladi:
Bu xususiyat sukut bo'yicha yoqilmagan: server ham, mijoz ham mos ravishda sozlanishi kerak.
O'rnatishning o'zi oddiy va ko'pgina dasturlash tillari va muhitlari uchun mavjud.
Kubernetes xizmatida saqlab qolishdan foydalansak nima bo'ladi?
Faraz qilaylik, frontend ham, backend ham tirik qolishni qo'llab-quvvatlaydi.
Bizda old qismning bitta nusxasi va orqa qismning uchta nusxasi mavjud. Frontend birinchi so'rovni amalga oshiradi va orqa qismga TCP ulanishini ochadi. So‘rov xizmatga yetib boradi, maqsad manzil sifatida backend podslardan biri tanlanadi. Backend javob yuboradi va frontend uni qabul qiladi.
Javob olgandan keyin TCP ulanishi yopilgan odatiy holatdan farqli o'laroq, u endi HTTP so'rovlari uchun ochiq qoladi.
Agar frontend orqa qismga ko'proq so'rov yuborsa nima bo'ladi?
Ushbu so'rovlarni yuborish uchun ochiq TCP ulanishidan foydalaniladi, barcha so'rovlar birinchi so'rov yuborilgan bir xil serverga o'tadi.
Iptables trafikni qayta taqsimlashi kerak emasmi?
Bu holatda emas.
TCP ulanishi yaratilganda, u trafik ketadigan ma'lum bir backendni tanlaydigan iptables qoidalaridan o'tadi.
Barcha keyingi so'rovlar allaqachon ochiq TCP ulanishida bo'lgani uchun iptables qoidalari endi chaqirilmaydi.
Keling, qanday ko'rinishini ko'rib chiqaylik.
Birinchi podkast xizmatga so'rov yuboradi:
Keyinchalik nima bo'lishini allaqachon bilasiz. Xizmat mavjud emas, lekin so'rovni qayta ishlaydigan iptables qoidalari mavjud:
Maqsad manzili sifatida orqa panellardan biri tanlanadi:
So'rov podkaga yetib boradi. Ushbu nuqtada ikkita pods o'rtasida doimiy TCP ulanishi o'rnatiladi:
Birinchi poddan har qanday keyingi so'rov allaqachon o'rnatilgan ulanish orqali o'tadi:
Natijada tezroq javob vaqti va yuqori o'tkazish qobiliyati bo'ladi, lekin siz backendni o'lchash qobiliyatini yo'qotasiz.
Agar sizda doimiy ulanishga ega ikkita podkastingiz bo'lsa ham, trafik har doim ulardan biriga o'tadi.
Buni tuzatish mumkinmi?
Kubernetes doimiy ulanishlarni qanday muvozanatlashni bilmagani uchun bu vazifa sizga tushadi.
Xizmatlar IP manzillar va so'nggi nuqtalar deb ataladigan portlar to'plamidir.
Sizning ilovangiz xizmatdan so'nggi nuqtalar ro'yxatini olishi va ular o'rtasida so'rovlarni qanday taqsimlashni hal qilishi mumkin. Siz har bir podkastga doimiy ulanishni ochishingiz va bu ulanishlar orasidagi so'rovlarni round-robin yordamida muvozanatlashingiz mumkin.
Balanslash uchun mas'ul bo'lgan mijoz kodi quyidagi mantiqqa amal qilishi kerak:
Xizmatdan so'nggi nuqtalar ro'yxatini oling.
Har bir so'nggi nuqta uchun doimiy ulanishni oching.
So'rov qilish kerak bo'lganda, ochiq ulanishlardan birini ishlating.
Agar ro'yxat o'zgarsa, oxirgi nuqtalar ro'yxatini muntazam yangilang, yangilarini yarating yoki eski doimiy ulanishlarni yoping.
Bu shunday bo'ladi.
Xizmatga so'rov yuboradigan birinchi podkast o'rniga siz mijoz tomonidagi so'rovlarni muvozanatlashingiz mumkin:
Qaysi podlar xizmatning bir qismi ekanligini so'rab kod yozishingiz kerak:
Roʻyxatni olganingizdan soʻng uni mijoz tomonida saqlang va undan podkastlarga ulanish uchun foydalaning:
Siz yukni muvozanatlash algoritmi uchun javobgarsiz:
Endi savol tug'iladi: bu muammo faqat HTTP saqlab qolish uchun amal qiladimi?
Mijoz tomonidan yukni muvozanatlash
HTTP doimiy TCP ulanishlaridan foydalanishi mumkin bo'lgan yagona protokol emas.
Agar ilovangiz ma'lumotlar bazasidan foydalansa, TCP ulanishi har safar so'rov yuborishingiz yoki ma'lumotlar bazasidan hujjat olishingiz kerak bo'lganda ochilmaydi.
Buning o'rniga ma'lumotlar bazasiga doimiy TCP ulanishi ochiladi va ishlatiladi.
Agar sizning ma'lumotlar bazasi Kubernetes-da joylashtirilgan bo'lsa va kirish xizmat sifatida taqdim etilsa, siz avvalgi bo'limda tasvirlangan bir xil muammolarga duch kelasiz.
Bitta ma'lumotlar bazasi nusxasi boshqalarga qaraganda ko'proq yuklanadi. Kube-proksi va Kubernetes ulanishlarni muvozanatlashda yordam bermaydi. So'rovlarni ma'lumotlar bazasi bilan muvozanatlash uchun ehtiyot bo'lishingiz kerak.
Ma'lumotlar bazasiga ulanish uchun qaysi kutubxonadan foydalanganingizga qarab, sizda ushbu muammoni hal qilish uchun turli xil variantlar bo'lishi mumkin.
Quyida Node.js’dan MySQL ma’lumotlar bazasi klasteriga kirish misoli keltirilgan:
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
Doimiy TCP ulanishlaridan foydalanadigan ko'plab boshqa protokollar mavjud:
WebSockets va himoyalangan WebSockets
HTTP / 2
gRPC
RSockets
AMQP
Siz ushbu protokollarning aksariyati bilan allaqachon tanish bo'lishingiz kerak.
Ammo agar bu protokollar juda mashhur bo'lsa, nega standartlashtirilgan balanslash echimi mavjud emas? Nima uchun mijoz mantig'ini o'zgartirish kerak? Mahalliy Kubernetes yechimi bormi?
Kube-proksi va iptables Kubernetes-ga joylashtirishda eng keng tarqalgan foydalanish holatlarini qoplash uchun mo'ljallangan. Bu qulaylik uchun.
Agar siz REST API-ni ochadigan veb-xizmatdan foydalanayotgan bo'lsangiz, omadingiz bor - bu holda doimiy TCP ulanishlari ishlatilmaydi, istalgan Kubernetes xizmatidan foydalanishingiz mumkin.
Doimiy TCP ulanishlaridan foydalanishni boshlaganingizdan so'ng, yukni orqa tomonlar bo'ylab qanday qilib teng taqsimlashni aniqlashingiz kerak bo'ladi. Kubernetesda bu holat uchun tayyor echimlar mavjud emas.
Biroq, albatta, yordam beradigan variantlar mavjud.
Kubernetesda uzoq muddatli ulanishlarni muvozanatlash
Kubernetes-da to'rt turdagi xizmatlar mavjud:
ClusterIP
NodePort
LoadBalancer
Boshsiz
Birinchi uchta xizmat kube-proksi tomonidan iptables qoidalarini yaratish uchun foydalaniladigan virtual IP-manzil asosida ishlaydi. Ammo barcha xizmatlarning asosiy asosi boshsiz xizmatdir.
Boshsiz xizmat u bilan bog'langan hech qanday IP-manzilga ega emas va faqat IP-manzillar ro'yxatini va u bilan bog'langan pods (so'nggi nuqtalar) portlarini olish mexanizmini taqdim etadi.
Barcha xizmatlar boshsiz xizmatga asoslangan.
ClusterIP xizmati ba'zi qo'shimchalar bilan boshsiz xizmatdir:
Boshqaruv qatlami unga IP manzilini tayinlaydi.
Kube-proksi kerakli iptables qoidalarini yaratadi.
Shu tarzda siz kube-proksini e'tiborsiz qoldirishingiz va ilovangizni yuklash muvozanatini saqlash uchun boshsiz xizmatdan olingan so'nggi nuqtalar ro'yxatidan bevosita foydalanishingiz mumkin.
Ammo klasterda o'rnatilgan barcha ilovalarga o'xshash mantiqni qanday qo'shishimiz mumkin?
Agar ilovangiz allaqachon o'rnatilgan bo'lsa, bu vazifa imkonsiz bo'lib tuyulishi mumkin. Biroq, muqobil variant mavjud.
Xizmat Mesh sizga yordam beradi
Mijoz tomonidan yukni muvozanatlash strategiyasi juda standart ekanligini allaqachon payqagan bo'lsangiz kerak.
Ilova boshlanganda, u:
Xizmatdan IP manzillar ro'yxatini oladi.
Ulanish hovuzini ochadi va saqlaydi.
Vaqti-vaqti bilan oxirgi nuqtalarni qo'shish yoki olib tashlash orqali hovuzni yangilab turadi.
Ilova so'rov yubormoqchi bo'lgach, u:
Ba'zi bir mantiq (masalan, round-robin) yordamida mavjud ulanishni tanlaydi.
So'rovni bajaradi.
Ushbu qadamlar ikkala WebSockets, gRPC va AMQP ulanishlari uchun ishlaydi.
Siz ushbu mantiqni alohida kutubxonaga ajratishingiz va uni ilovalaringizda ishlatishingiz mumkin.
Biroq, buning o'rniga Istio yoki Linkerd kabi xizmat ko'rsatish tarmoqlaridan foydalanishingiz mumkin.
Service Mesh ilovangizni quyidagi jarayon bilan kengaytiradi:
Xizmat IP manzillarini avtomatik ravishda qidiradi.
WebSockets va gRPC kabi ulanishlarni sinovdan o'tkazadi.
To'g'ri protokol yordamida so'rovlarni muvozanatlashtiradi.
Service Mesh klaster ichidagi trafikni boshqarishga yordam beradi, lekin u juda ko'p resurs talab qiladi. Boshqa variantlar Netflix Ribbon kabi uchinchi tomon kutubxonalaridan yoki Envoy kabi dasturlashtiriladigan proksi-serverlardan foydalanishdir.
Agar muvozanat muammolarini e'tiborsiz qoldirsangiz nima bo'ladi?
Siz yuk balansini ishlatmaslikni tanlashingiz mumkin va hali ham hech qanday o'zgarishlarni sezmaysiz. Keling, bir nechta ish stsenariylarini ko'rib chiqaylik.
Agar sizda serverlardan ko'proq mijozlar bo'lsa, bu unchalik katta muammo emas.
Aytaylik, ikkita serverga ulanadigan beshta mijoz bor. Balanslash bo'lmasa ham, ikkala server ham ishlatiladi:
Ulanishlar teng taqsimlanmagan bo'lishi mumkin: bir xil serverga to'rtta mijoz ulangan bo'lishi mumkin, ammo ikkala serverdan ham foydalanish ehtimoli yaxshi.
Eng muammoli narsa bu qarama-qarshi stsenariy.
Agar sizda kamroq mijozlar va ko'proq serverlar bo'lsa, resurslaringiz to'liq foydalanilmagan bo'lishi mumkin va potentsial to'siq paydo bo'ladi.
Aytaylik, ikkita mijoz va beshta server mavjud. Eng yaxshi holatda, beshdan ikkita serverga ikkita doimiy ulanish bo'ladi.
Qolgan serverlar ishlamaydi:
Agar ushbu ikkita server mijoz so'rovlarini bajara olmasa, gorizontal o'lchov yordam bermaydi.
xulosa
Kubernetes xizmatlari ko'pgina standart veb-ilovalar stsenariylarida ishlash uchun mo'ljallangan.
Biroq, ma'lumotlar bazalari, gRPC yoki WebSockets kabi doimiy TCP ulanishlaridan foydalanadigan dastur protokollari bilan ishlashni boshlaganingizdan so'ng, xizmatlar endi mos kelmaydi. Kubernetes doimiy TCP ulanishlarini muvozanatlash uchun ichki mexanizmlarni taqdim etmaydi.
Bu shuni anglatadiki, siz ilovalarni mijoz tomonidan muvozanatni hisobga olgan holda yozishingiz kerak.