"Kubernetes kechikish vaqtini 10 baravar oshirdi": bunga kim aybdor?

Eslatma. tarjima.: Evropaning Adevinta kompaniyasida dasturiy ta'minot bo'yicha bosh muhandis lavozimini egallagan Galo Navarro tomonidan yozilgan ushbu maqola infratuzilma operatsiyalari sohasidagi qiziqarli va ibratli "tekshiruv" dir. Uning asl sarlavhasi muallif boshida tushuntirgan sababga ko'ra tarjimada biroz kengaytirilgan.

"Kubernetes kechikish vaqtini 10 baravar oshirdi": bunga kim aybdor?

Muallifdan eslatma: Bu postga o'xshaydi jalb qilingan kutilganidan ko'ra ko'proq e'tibor. Maqola sarlavhasi noto'g'ri ekanligi va ba'zi o'quvchilarning xafa bo'lganligi haqida haligacha g'azablangan sharhlarni olaman. Men sodir bo'layotgan voqealarning sabablarini tushunaman, shuning uchun butun fitnani buzish xavfiga qaramay, men sizga ushbu maqola nima haqida ekanligini darhol aytmoqchiman. Jamoalar Kubernetesga ko‘chib o‘tayotganda men ko‘rgan qiziq narsa shundaki, har doim muammo yuzaga kelganda (migratsiyadan keyin kechikishning oshishi kabi) birinchi navbatda Kubernetes ayblanadi, ammo keyin orkestr haqiqatan ham shunday emasligi ma’lum bo‘ldi. ayblash. Ushbu maqolada shunday holatlardan biri haqida so'z boradi. Uning nomi ishlab chiquvchilarimizdan birining nidosini takrorlaydi (keyinroq siz Kubernetesning bunga aloqasi yo'qligini ko'rasiz). Bu yerda siz Kubernetes haqida hayratlanarli vahiylarni topa olmaysiz, ammo murakkab tizimlar haqida bir nechta yaxshi saboqlarni kutishingiz mumkin.

Bir necha hafta oldin mening jamoam bitta mikroxizmatni CI/CD, Kubernetes-ga asoslangan ish vaqti, ko'rsatkichlar va boshqa foydali narsalarni o'z ichiga olgan asosiy platformaga ko'chirayotgan edi. Ko'chirish sinov xarakteriga ega edi: biz uni asos qilib olishni va yaqin oylarda yana 150 ga yaqin xizmatlarni o'tkazishni rejalashtirgan edik. Ularning barchasi Ispaniyadagi eng yirik onlayn platformalarning (Infojobs, Fotocasa va boshqalar) ishlashi uchun javobgardir.

Ilovani Kubernetes-ga joylashtirganimizdan va ba'zi trafikni unga yo'naltirganimizdan so'ng, bizni hayajonli ajablantiradigan narsa kutdi. Kechikish (kechikish) Kubernetesdagi so'rovlar EC10-ga qaraganda 2 baravar yuqori edi. Umuman olganda, bu muammoning echimini topish yoki mikroservisning (va, ehtimol, butun loyiha) migratsiyasidan voz kechish kerak edi.

Nima uchun Kubernetesda kechikish EC2 ga qaraganda ancha yuqori?

To'siqni topish uchun biz butun so'rov yo'li bo'ylab ko'rsatkichlarni to'pladik. Bizning arxitekturamiz oddiy: API shlyuzi (Zuul) EC2 yoki Kubernetes’dagi mikroservis misollariga so‘rovlarni yuboradi. Kubernetes-da biz NGINX Ingress Controller-dan foydalanamiz va orqa tomonlar oddiy ob'ektlardir. Tarqatish Spring platformasida JVM ilovasi bilan.

                                  EC2
                            +---------------+
                            |  +---------+  |
                            |  |         |  |
                       +-------> BACKEND |  |
                       |    |  |         |  |
                       |    |  +---------+  |                   
                       |    +---------------+
             +------+  |
Public       |      |  |
      -------> ZUUL +--+
traffic      |      |  |              Kubernetes
             +------+  |    +-----------------------------+
                       |    |  +-------+      +---------+ |
                       |    |  |       |  xx  |         | |
                       +-------> NGINX +------> BACKEND | |
                            |  |       |  xx  |         | |
                            |  +-------+      +---------+ |
                            +-----------------------------+

Muammo orqa qismdagi dastlabki kechikish bilan bog'liq bo'lib tuyuldi (men grafikdagi muammo maydonini "xx" deb belgiladim). EC2 da ilovaning javobi taxminan 20ms davom etdi. Kubernetesda kechikish 100-200 ms gacha ko'tarildi.

Ish vaqti oʻzgarishi bilan bogʻliq ehtimolli gumondorlarni tezda rad etdik. JVM versiyasi bir xil bo'lib qoladi. Konteynerlash muammolari ham bunga hech qanday aloqasi yo'q edi: dastur allaqachon EC2 konteynerlarida muvaffaqiyatli ishlayotgan edi. Yuklanmoqdami? Ammo biz soniyada 1 ta so'rovda ham yuqori kechikishlarni kuzatdik. Axlat yig'ish uchun pauzalarni ham e'tiborsiz qoldirish mumkin.

Kubernetes ma'murlarimizdan biri ilovada tashqi bog'liqliklar bormi, deb hayron bo'ldi, chunki DNS so'rovlari o'tmishda shunga o'xshash muammolarni keltirib chiqargan.

Gipoteza 1: DNS nomini aniqlash

Har bir so'rov uchun bizning ilovamiz AWS Elasticsearch misoliga bir yoki uch marta kabi domenda kiradi elastic.spain.adevinta.com. Bizning konteynerlarimiz ichida qobiq bor, shuning uchun biz domenni qidirish haqiqatan ham uzoq vaqt talab qiladimi yoki yo'qligini tekshirishimiz mumkin.

Konteynerdan DNS so'rovlari:

[root@be-851c76f696-alf8z /]# while true; do dig "elastic.spain.adevinta.com" | grep time; sleep 2; done
;; Query time: 22 msec
;; Query time: 22 msec
;; Query time: 29 msec
;; Query time: 21 msec
;; Query time: 28 msec
;; Query time: 43 msec
;; Query time: 39 msec

Ilova ishlayotgan EC2 misollaridan birining o'xshash so'rovlari:

bash-4.4# while true; do dig "elastic.spain.adevinta.com" | grep time; sleep 2; done
;; Query time: 77 msec
;; Query time: 0 msec
;; Query time: 0 msec
;; Query time: 0 msec
;; Query time: 0 msec

Qidiruv taxminan 30 ms davom etganini hisobga olsak, Elasticsearch-ga kirishda DNS ruxsati haqiqatan ham kechikishning oshishiga yordam bergani aniq bo'ldi.

Biroq, bu ikki sababga ko'ra g'alati edi:

  1. Bizda allaqachon yuqori kechikishlarsiz AWS resurslari bilan o'zaro aloqada bo'lgan ko'plab Kubernetes ilovalari mavjud. Sababi nima bo'lishidan qat'iy nazar, u aynan shu holatga tegishli.
  2. Biz JVM xotirada DNS keshlashni amalga oshirishini bilamiz. Bizning rasmlarimizda TTL qiymati yozilgan $JAVA_HOME/jre/lib/security/java.security va 10 soniyaga o'rnating: networkaddress.cache.ttl = 10. Boshqacha qilib aytganda, JVM barcha DNS so'rovlarini 10 soniya davomida keshlashi kerak.

Birinchi gipotezani tasdiqlash uchun biz bir muddat DNS-ga qo'ng'iroq qilishni to'xtatishga qaror qildik va muammo yo'qoldimi yoki yo'qmi. Birinchidan, biz dasturni domen nomi orqali emas, balki IP-manzil bo'yicha to'g'ridan-to'g'ri Elasticsearch bilan bog'lanishi uchun qayta sozlashga qaror qildik. Bu kodni o'zgartirishni va yangi joylashtirishni talab qiladi, shuning uchun biz domenni uning IP manzili bilan taqqosladik /etc/hosts:

34.55.5.111 elastic.spain.adevinta.com

Endi konteyner deyarli bir zumda IP oldi. Bu biroz yaxshilanishga olib keldi, lekin biz kutilgan kechikish darajasiga biroz yaqinroq bo'ldik. DNS rezolyutsiyasi uzoq vaqt talab qilgan bo'lsa-da, haqiqiy sabab hali ham bizni chetlab o'tdi.

Tarmoq orqali diagnostika

Biz konteynerdan trafikni tahlil qilishga qaror qildik tcpdumptarmoqda nima sodir bo'layotganini ko'rish uchun:

[root@be-851c76f696-alf8z /]# tcpdump -leni any -w capture.pcap

Keyin biz bir nechta so'rovlarni yubordik va ularning suratini yuklab oldik (kubectl cp my-service:/capture.pcap capture.pcap) qo'shimcha tahlil qilish uchun Wireshark.

DNS so'rovlarida shubhali hech narsa yo'q edi (keyinroq gaplashadigan kichik narsadan tashqari). Ammo bizning xizmatimiz har bir so'rovni ko'rib chiqishda qandaydir g'alatiliklar bor edi. Quyida javob boshlanishidan oldin so'rov qabul qilinganligi ko'rsatilgan suratga olishning skrinshoti keltirilgan:

"Kubernetes kechikish vaqtini 10 baravar oshirdi": bunga kim aybdor?

Paket raqamlari birinchi ustunda ko'rsatilgan. Aniqlik uchun men turli xil TCP oqimlarini rang bilan kodladim.

328-paketdan boshlanadigan yashil oqim mijoz (172.17.22.150) konteynerga (172.17.36.147) TCP ulanishini qanday o'rnatganligini ko'rsatadi. Dastlabki qo'l siqishdan keyin (328-330), 331-paket keltirildi HTTP GET /v1/.. — bizning xizmatimizga kiruvchi so'rov. Butun jarayon 1 ms davom etdi.

Kulrang oqim (339-paketdan) bizning xizmatimiz Elasticsearch misoliga HTTP so'rovini yuborganligini ko'rsatadi (mavjud ulanishdan foydalanayotgani uchun TCP almashish yo'q). Bu 18 ms davom etdi.

Hozircha hamma narsa yaxshi va vaqtlar taxminan kutilgan kechikishlarga to'g'ri keladi (mijozdan o'lchanganida 20-30 ms).

Biroq, ko'k qism 86 ms oladi. Unda nima bo'lyapti? 333-paket bilan bizning xizmatimiz HTTP GET so'rovini yubordi /latest/meta-data/iam/security-credentials, va undan so'ng darhol xuddi shu TCP ulanishi orqali boshqa GET so'rovi yuboriladi /latest/meta-data/iam/security-credentials/arn:...

Biz bu iz davomida har bir so'rov bilan takrorlanishini aniqladik. DNS ruxsati bizning konteynerlarimizda biroz sekinroq (bu hodisaning tushuntirishi juda qiziq, lekin men uni alohida maqola uchun saqlayman). Aniqlanishicha, uzoq kechikishlarga har bir so‘rov bo‘yicha AWS Instance Metadata xizmatiga qilingan qo‘ng‘iroqlar sabab bo‘lgan.

Gipoteza 2: AWSga keraksiz qo'ng'iroqlar

Ikkala oxirgi nuqta ham tegishli AWS Instance metadata API. Mikroxizmatimiz Elasticsearch dasturini ishga tushirganda ushbu xizmatdan foydalanadi. Ikkala qo'ng'iroq ham asosiy avtorizatsiya jarayonining bir qismidir. Birinchi so'rovda foydalaniladigan so'nggi nuqta misol bilan bog'langan IAM rolini chiqaradi.

/ # curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
arn:aws:iam::<account_id>:role/some_role

Ikkinchi so'rov ikkinchi so'nggi nuqtadan ushbu misol uchun vaqtinchalik ruxsatlarni so'raydi:

/ # curl http://169.254.169.254/latest/meta-data/iam/security-credentials/arn:aws:iam::<account_id>:role/some_role`
{
    "Code" : "Success",
    "LastUpdated" : "2012-04-26T16:39:16Z",
    "Type" : "AWS-HMAC",
    "AccessKeyId" : "ASIAIOSFODNN7EXAMPLE",
    "SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "Token" : "token",
    "Expiration" : "2017-05-17T15:09:54Z"
}

Mijoz ulardan qisqa vaqt davomida foydalanishi mumkin va vaqti-vaqti bilan yangi sertifikatlarni olishi kerak (ulardan oldin Expiration). Model oddiy: AWS xavfsizlik nuqtai nazaridan vaqtinchalik kalitlarni tez-tez aylantiradi, biroq mijozlar yangi sertifikatlar olish bilan bog‘liq ishlash jazosini qoplash uchun ularni bir necha daqiqaga keshlashlari mumkin.

AWS Java SDK ushbu jarayonni tashkil qilish uchun mas'uliyatni o'z zimmasiga olishi kerak, ammo negadir bu sodir bo'lmaydi.

GitHub-da muammolarni qidirganimizdan so'ng, biz muammoga duch keldik #1921. U bizga "qazish" yo'nalishini aniqlashga yordam berdi.

AWS SDK sertifikatlarni quyidagi shartlardan biri yuzaga kelganda yangilaydi:

  • Tugash muddati (Expiration) ichiga tushish EXPIRATION_THRESHOLD, 15 daqiqagacha qattiq kodlangan.
  • Sertifikatlarni yangilashga oxirgi urinishdan beri ko'proq vaqt o'tdi REFRESH_THRESHOLD, 60 daqiqa davomida qattiq kodlangan.

Biz olgan sertifikatlarning amaldagi amal qilish muddatini ko'rish uchun biz konteynerdan ham, EC2 nusxasidan ham yuqoridagi cURL buyruqlarini bajardik. Konteynerdan olingan sertifikatning amal qilish muddati ancha qisqa bo'lib chiqdi: roppa-rosa 15 daqiqa.

Endi hamma narsa aniq bo'ldi: birinchi so'rov uchun bizning xizmatimiz vaqtinchalik sertifikatlarni oldi. Ular 15 daqiqadan ko'proq vaqt davomida amal qilmaganligi sababli, AWS SDK keyingi so'rovda ularni yangilashga qaror qiladi. Va bu har bir so'rov bilan sodir bo'ldi.

Nega sertifikatlarning amal qilish muddati qisqardi?

AWS Instance metadata Kubernetes emas, balki EC2 nusxalari bilan ishlash uchun moʻljallangan. Boshqa tomondan, biz dastur interfeysini o'zgartirishni xohlamadik. Buning uchun biz foydalandik KIAM - har bir Kubernetes tugunida agentlardan foydalangan holda foydalanuvchilarga (klasterga ilovalarni joylashtirayotgan muhandislar) IAM rollarini podkastlardagi konteynerlarga xuddi EC2 namunalari kabi belgilash imkonini beruvchi vosita. KIAM AWS Instance Metadata xizmatiga qo'ng'iroqlarni ushlab turadi va ularni oldindan AWSdan olgan holda keshdan qayta ishlaydi. Ilova nuqtai nazaridan, hech narsa o'zgarmaydi.

KIAM podlarga qisqa muddatli sertifikatlar beradi. Podning o'rtacha ishlash muddati EC2 namunasidan qisqaroq ekanligini hisobga olsak, bu mantiqiy. Sertifikatlarning standart amal qilish muddati bir xil 15 daqiqaga teng.

Natijada, agar siz ikkala standart qiymatni bir-birining ustiga qo'ysangiz, muammo yuzaga keladi. Arizaga taqdim etilgan har bir sertifikat 15 daqiqadan so'ng tugaydi. Biroq, AWS Java SDK amal qilish muddati tugashiga 15 daqiqadan kamroq vaqt qolgan har qanday sertifikatni yangilashga majbur qiladi.

Natijada, vaqtinchalik sertifikat har bir so'rov bilan yangilanishiga majbur bo'ladi, bu AWS API-ga bir nechta qo'ng'iroqlarni talab qiladi va kechikishning sezilarli darajada oshishiga olib keladi. AWS Java SDK da biz topdik xususiyat so'rovi, bu shunga o'xshash muammo haqida gapiradi.

Yechim oddiy bo'lib chiqdi. Biz KIAM-ni amal qilish muddati uzoqroq bo'lgan sertifikatlarni so'rash uchun qaytadan sozladik. Bu sodir bo'lgach, so'rovlar AWS Metadata xizmati ishtirokisiz kela boshladi va kechikish EC2 ga qaraganda pastroq darajaga tushdi.

topilmalar

Migratsiya bilan bog'liq tajribamizga asoslanib, muammolarning eng keng tarqalgan manbalaridan biri Kubernetes yoki platformaning boshqa elementlaridagi xatolar emas. Shuningdek, u biz o'tkazayotgan mikroservislardagi asosiy kamchiliklarni bartaraf etmaydi. Muammolar ko'pincha turli elementlarni birlashtirganimiz sababli paydo bo'ladi.

Biz hech qachon bir-biri bilan o'zaro aloqada bo'lmagan murakkab tizimlarni birlashtiramiz va ular birgalikda yagona, kattaroq tizimni tashkil qilishini kutamiz. Afsuski, elementlar qancha ko'p bo'lsa, xatolar uchun joy qancha ko'p bo'lsa, entropiya shunchalik yuqori bo'ladi.

Bizning holatlarimizda, yuqori kechikish Kubernetes, KIAM, AWS Java SDK yoki mikroservisdagi xatolar yoki noto'g'ri qarorlar natijasi emas edi. Bu ikkita mustaqil standart sozlamalarni birlashtirish natijasi edi: biri KIAM-da, ikkinchisi AWS Java SDK-da. Alohida olinganda, ikkala parametr ham mantiqiy: AWS Java SDK-da sertifikatni yangilashning faol siyosati va KAIM-da sertifikatlarning amal qilish muddati qisqa. Ammo ularni birlashtirganda, natijalar oldindan aytib bo'lmaydi. Ikki mustaqil va mantiqiy echimlar birlashtirilganda mantiqiy bo'lishi shart emas.

Tarjimondan PS

AWS IAMni Kubernetes bilan integratsiyalash uchun KIAM yordam dasturining arxitekturasi haqida koʻproq maʼlumot olishingiz mumkin. Ushbu maqola yaratuvchilardan.

Shuningdek, bizning blogimizda o'qing:

Manba: www.habr.com

a Izoh qo'shish