"Kubernetes ningkat latency ku 10 kali": saha nu kudu ngalepatkeun ieu?

Catetan. narjamahkeun.: Artikel ieu, ditulis ku Galo Navarro, anu nyepeng posisi Insinyur Software Principal di parusahaan Éropa Adevinta, mangrupakeun "investigasi" matak na instructive dina widang operasi infrastruktur. Judul aslina ieu rada dimekarkeun dina tarjamahan pikeun alesan yén pangarang ngajelaskeun di pisan awal.

"Kubernetes ningkat latency ku 10 kali": saha nu kudu ngalepatkeun ieu?

Catetan ti pangarang: Sigana mah tulisan ieu katarik leuwih perhatian ti ekspektasi. Kuring masih meunang komentar ambek yén judul artikel téh nyasabkeun sarta yén sababaraha pamiarsa saddened. Kuring ngarti alesan naon anu lumangsung, ku kituna, sanajan resiko ruining sakabeh intrik, abdi hoyong langsung ngabejaan Anjeun naon artikel ieu. Hiji hal panasaran kuring geus katempo salaku tim migrasi ka Kubernetes nyaeta iraha wae masalah timbul (saperti ngaronjat latency sanggeus migrasi a), hal kahiji anu bakal disalahkeun nyaéta Kubernetes, tapi lajeng tétéla yén orchestrator teu bener. nyalahkeun. Tulisan ieu nyarioskeun ngeunaan hiji kasus sapertos kitu. Ngaranna ngulang panyeluk salah sahiji pamekar kami (engké anjeun bakal ningali yén Kubernetes teu aya hubunganana sareng éta). Anjeun moal mendakan wahyu anu héran ngeunaan Kubernetes di dieu, tapi anjeun tiasa ngarepkeun sababaraha pelajaran anu saé ngeunaan sistem kompleks.

Sababaraha minggu ka tukang, tim kuring migrasi hiji microservice ka platform inti anu kalebet CI / CD, runtime basis Kubernetes, métrik, sareng barang-barang sanés. Mindahkeun éta mangrupikeun uji coba: kami ngarencanakeun janten dasar sareng nransferkeun sakitar 150 langkung jasa dina sasih bulan. Sadayana tanggung jawab pikeun operasi sababaraha platform online panggedéna di Spanyol (Infojobs, Fotocasa, jsb.).

Saatos kami nyebarkeun aplikasi ka Kubernetes sareng dialihkeun sababaraha lalu lintas ka dinya, kejutan anu pikasieuneun ngantosan kami. Reureuh (latency) requests di Kubernetes éta 10 kali leuwih luhur ti di EC2. Sacara umum, perlu pikeun manggihan solusi pikeun masalah ieu, atawa abandon migrasi microservice (jeung, meureun, sakabéh proyék).

Naha latency langkung luhur di Kubernetes tibatan di EC2?

Pikeun mendakan bottleneck, kami ngumpulkeun métrik sapanjang jalur pamundut. Arsitéktur urang basajan: hiji gateway API (Zuul) proxies requests ka instansi microservice di EC2 atanapi Kubernetes. Dina Kubernetes kami nganggo NGINX Ingress Controller, sareng backends mangrupikeun objék biasa sapertos deployment kalawan aplikasi JVM dina platform Spring.

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

Masalahna sigana aya hubunganana sareng latency awal dina backend (Kuring nandaan daérah masalah dina grafik salaku "xx"). Dina EC2, réspon aplikasi nyandak sakitar 20ms. Dina Kubernetes, latency naek ka 100-200 mdet.

Urang gancang mecat kamungkinan tersangka patali parobahan runtime. Versi JVM tetep sami. Masalah kontainerisasi ogé teu aya hubunganana sareng éta: aplikasi parantos suksés dijalankeun dina wadah dina EC2. Ngamuat? Tapi kami niténan latency tinggi sanajan dina 1 pamundut per detik. Jeda pikeun ngumpulkeun sampah ogé tiasa diabaikan.

Salah sahiji admin Kubernetes kami heran naha aplikasina ngagaduhan katergantungan éksternal sabab patarosan DNS parantos nyababkeun masalah anu sami dina jaman baheula.

Hipotesis 1: resolusi ngaran DNS

Pikeun unggal pamundut, aplikasi kami ngaksés hiji conto AWS Elasticsearch hiji nepi ka tilu kali dina domain kawas elastic.spain.adevinta.com. Di jero wadah urang aya cangkang, sangkan bisa mariksa lamun neangan domain sabenerna butuh waktu lila.

Pertanyaan DNS tina wadahna:

[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

Paménta anu sami ti salah sahiji instansi EC2 dimana aplikasina dijalankeun:

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

Nganggap yén pamariksaan nyandak sakitar 30ms, janten écés yén résolusi DNS nalika ngaksés Elasticsearch memang nyumbang kana paningkatan latency.

Nanging, ieu anéh kusabab dua alesan:

  1. Kami parantos ngagaduhan seueur aplikasi Kubernetes anu berinteraksi sareng sumber AWS tanpa kakurangan tina latency tinggi. Naon waé alesanana, khususna aya hubunganana sareng hal ieu.
  2. Urang terang yén JVM ngalakukeun cache DNS dina mémori. Dina gambar urang, nilai TTL ditulis dina $JAVA_HOME/jre/lib/security/java.security tur disetel ka 10 detik: networkaddress.cache.ttl = 10. Dina basa sejen, JVM kedah cache sadaya queries DNS pikeun 10 detik.

Pikeun ngonfirmasi hipotésis anu munggaran, urang mutuskeun pikeun ngeureunkeun nelepon DNS sakedap sareng ningali upami masalahna ngaleungit. Mimiti, urang mutuskeun pikeun ngonpigurasikeun deui aplikasi supados komunikasi langsung sareng Elasticsearch ku alamat IP, tinimbang ngalangkungan nami domain. Ieu bakal meryogikeun parobihan kode sareng panyebaran énggal, janten urang ngan saukur dipetakeun domain ka alamat IP na /etc/hosts:

34.55.5.111 elastic.spain.adevinta.com

Ayeuna wadahna nampi IP ampir langsung. Ieu nyababkeun sababaraha perbaikan, tapi kami ngan rada caket kana tingkat latency anu dipiharep. Sanajan resolusi DNS nyandak lila, alesan nyata masih eluded kami.

Diagnostik via jaringan

Urang mutuskeun pikeun nganalisis lalulintas tina wadahna ngagunakeun tcpdumppikeun ningali naon anu lumangsung dina jaringan:

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

Kami teras ngintunkeun sababaraha pamenta sareng ngaunduh panangkepana (kubectl cp my-service:/capture.pcap capture.pcap) pikeun analisis salajengna dina Wireshark.

Aya nanaon curiga ngeunaan queries DNS (iwal hiji hal saeutik nu bakal ngobrol ngeunaan engké). Tapi aya sababaraha kaanehan dina cara jasa kami nanganan unggal pamundut. Di handap ieu mangrupakeun screenshot of newak némbongkeun pamundut nu ditarima saméméh respon dimimitian:

"Kubernetes ningkat latency ku 10 kali": saha nu kudu ngalepatkeun ieu?

Nomer pakét dipidangkeun dina kolom kahiji. Pikeun kajelasan, Kuring geus warna-disandi aliran TCP béda.

The stream héjo dimimitian ku pakét 328 nembongkeun kumaha klien (172.17.22.150) ngadegkeun sambungan TCP kana wadahna (172.17.36.147). Saatos sasalaman awal (328-330), pakét 331 dibawa HTTP GET /v1/.. - pamundut asup kana jasa kami. Sakabéh prosés nyandak 1 mdet.

Aliran abu (tina pakét 339) nunjukkeun yén jasa kami ngirimkeun pamundut HTTP ka conto Elasticsearch (teu aya sasalaman TCP sabab nganggo sambungan anu tos aya). Ieu nyandak 18ms.

Sajauh sadayana henteu kunanaon, sareng waktosna kira-kira pakait sareng telat anu dipiharep (20-30 mdet nalika diukur tina klien).

Tapi, bagian biru butuh 86ms. Naon anu lumangsung di dinya? Kalayan pakét 333, jasa kami ngirimkeun pamundut HTTP GET ka /latest/meta-data/iam/security-credentials, sarta langsung saatos eta, ngaliwatan sambungan TCP sarua, pamundut GET sejen ka /latest/meta-data/iam/security-credentials/arn:...

Urang kapanggih yén ieu terus-terusan kalawan unggal pamundut sapanjang ngambah. Résolusi DNS memang rada laun dina wadah kami (panjelasan pikeun fenomena ieu rada pikaresepeun, tapi kuring bakal ngahémat éta pikeun tulisan anu misah). Tétéla yén anu ngabalukarkeun reureuh panjang nyaéta panggero kana jasa AWS Instance Metadata dina unggal pamundut.

Hipotesis 2: nelepon teu perlu ka AWS

Duanana titik tungtung milik AWS Instance Metadata API. Microservice kami nganggo jasa ieu nalika ngajalankeun Elasticsearch. Duanana sauran mangrupikeun bagian tina prosés otorisasi dasar. Titik tungtung anu diakses dina pamundut kahiji ngaluarkeun peran IAM pakait sareng instance.

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

Paménta kadua naroskeun titik akhir kadua pikeun idin samentawis pikeun conto ieu:

/ # 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"
}

Klién tiasa nganggo aranjeunna kanggo waktos anu pondok sareng kedah périodik kéngingkeun sertipikat énggal (saméméh aranjeunna Expiration). Modélna basajan: AWS sering muterkeun konci samentara pikeun alesan kaamanan, tapi klien tiasa cache aranjeunna pikeun sababaraha menit pikeun ngimbangan pinalti kinerja pakait sareng meunangkeun sertipikat anyar.

AWS Java SDK kedah nyandak alih tanggung jawab pikeun ngatur prosés ieu, tapi pikeun sababaraha alesan ieu teu lumangsung.

Saatos milarian masalah dina GitHub, kami mendakan masalah #1921. Manehna mantuan kami nangtukeun arah nu "ngagali" salajengna.

AWS SDK ngamutahirkeun sertipikat nalika salah sahiji kaayaan di handap ieu lumangsung:

  • Tanggal kadaluarsa (Expiration) Ragrag kana EXPIRATION_THRESHOLD, hardcoded kana 15 menit.
  • Beuki lila geus kaliwat saprak usaha panungtungan pikeun renew sertipikat ti REFRESH_THRESHOLD, hardcoded salila 60 menit.

Pikeun ningali tanggal béakna aktual sertipikat anu kami tampi, kami ngajalankeun paréntah cURL di luhur tina wadahna sareng conto EC2. Mangsa validitas sertipikat anu ditampi tina wadahna tétéla langkung pondok: persis 15 menit.

Ayeuna sadayana parantos jelas: pikeun pamenta munggaran, jasa kami nampi sertipikat samentawis. Kusabab aranjeunna henteu valid langkung ti 15 menit, AWS SDK bakal mutuskeun pikeun ngapdet aranjeunna dina pamundut salajengna. Sarta ieu lumangsung kalawan unggal pamundut.

Naha periode validitas sertipikat janten langkung pondok?

AWS Instance Metadata dirancang pikeun dianggo sareng instansi EC2, sanés Kubernetes. Di sisi anu sanésna, kami henteu hoyong ngarobih antarmuka aplikasi. Pikeun ieu kami nganggo KIAM - alat anu, ngagunakeun agén dina unggal titik Kubernetes, ngamungkinkeun pamaké (insinyur nyebarkeun aplikasi ka klaster a) napelkeun peran IAM kana peti di pods saolah-olah éta instansi EC2. KIAM nyegat telepon kana jasa AWS Instance Metadata sareng ngolahna tina cache-na, saatos nampi ti AWS. Tina sudut pandang aplikasi, teu aya anu robih.

KIAM nyadiakeun sertipikat jangka pondok pikeun pods. Ieu masuk akal mertimbangkeun yén umur rata-rata pod langkung pondok tibatan conto EC2. Periode validitas standar pikeun sertipikat sarua jeung sarua 15 menit.

Hasilna, lamun overlay duanana nilai standar dina luhureun unggal lianna, masalah timbul. Unggal sertipikat anu disayogikeun ka aplikasi bakal kadaluwarsa saatos 15 menit. Tapi, AWS Java SDK maksakeun pembaharuan sertipikat naon waé anu tinggaleun kirang ti 15 menit sateuacan tanggal béakna.

Hasilna, sertipikat samentawis kapaksa di-renew unggal pamundut, nu merlukeun sababaraha telepon ka API AWS sarta ngabalukarkeun kanaékan signifikan dina latency. Dina AWS Java SDK kami kapanggih pamundut fitur, nu nyebutkeun masalah sarupa.

Leyuran tétéla basajan. Kami ngan saukur ngonpigurasikeun KIAM pikeun nyuhunkeun sertipikat kalayan periode validitas anu langkung panjang. Sakali ieu kajantenan, requests mimiti ngalir tanpa partisipasi layanan AWS Metadata, sarta latency turun ka tingkat malah leuwih handap di EC2.

papanggihan

Dumasar pangalaman urang sareng migrasi, salah sahiji sumber masalah anu paling umum nyaéta sanés bug dina Kubernetes atanapi elemen platform anu sanés. Éta ogé henteu ngabéréskeun cacad dasar dina jasa mikro anu kami porting. Masalah sering timbul ngan kusabab urang ngahijikeun elemen anu béda.

Urang nyampur babarengan sistem kompléks nu geus pernah berinteraksi saling sateuacan, expecting yén babarengan maranéhna bakal ngabentuk hiji, sistem nu leuwih gede. Alas, beuki elemen, beuki rohangan pikeun kasalahan, nu leuwih luhur éntropi.

Dina kasus kami, latency anu luhur sanés hasil tina bug atanapi kaputusan anu goréng dina Kubernetes, KIAM, AWS Java SDK, atanapi microservice kami. Ieu mangrupikeun hasil tina ngagabungkeun dua setélan standar anu mandiri: hiji di KIAM, anu sanés dina AWS Java SDK. Dicokot misah, duanana parameter make akal pikiran: kawijakan pembaharuan sertipikat aktip dina AWS Java SDK, sarta periode validitas pondok tina sertipikat di KAIM. Tapi mun anjeun nempatkeun aranjeunna babarengan, hasilna jadi unpredictable. Dua solusi anu mandiri sareng logis henteu kedah asup akal nalika digabungkeun.

PS ti penerjemah

Anjeun tiasa diajar langkung seueur ngeunaan arsitektur utilitas KIAM pikeun ngahijikeun AWS IAM sareng Kubernetes di artikel ieu ti panyipta na.

Baca ogé dina blog urang:

sumber: www.habr.com

Tambahkeun komentar