Tip & trik Kubernetes: fitur mareuman anggun di NGINX sareng PHP-FPM

Kaayaan umum nalika nerapkeun CI/CD di Kubernetes: aplikasina kedah tiasa nampi pamundut klien énggal sateuacan lirén lengkep, sareng anu paling penting, suksés ngalengkepan anu parantos aya.

Tip & trik Kubernetes: fitur mareuman anggun di NGINX sareng PHP-FPM

Patuh kana kaayaan ieu ngamungkinkeun anjeun pikeun ngahontal enol downtime salami panyebaran. Sanajan kitu, sanajan ngagunakeun bundles pisan populér (sapertos NGINX na PHP-FPM), anjeun tiasa sapatemon kasusah nu bakal ngakibatkeun surge kasalahan kalawan unggal deployment ...

Téori. Kumaha pod hirup

Kami parantos nyebarkeun sacara rinci ngeunaan siklus kahirupan pod artikel ieu. Dina kontéks topik anu ditalungtik, urang museurkeun ieu di handap: di momen nalika pod asup ka nagara Terminating, pamundut anyar eureun dikirim ka dinya (pod dipiceun tina daptar titik tungtung pikeun jasa). Ku kituna, pikeun ngahindarkeun downtime salila deployment, éta cukup pikeun urang pikeun ngajawab masalah stopping aplikasi nu bener.

Anjeun ogé kedah émut yén waktos tenggang standar nyaéta 30 detik: sanggeus ieu, pod bakal terminated sarta aplikasi kudu boga waktu pikeun ngolah sagala requests saméméh periode ieu. nyarios: sanaos pamundut anu peryogi langkung ti 5-10 detik parantos aya masalah, sareng mareuman anggun moal ngabantosan deui...

Pikeun langkung ngartos naon anu lumangsung nalika pod ditungtungan, tingali diagram ieu:

Tip & trik Kubernetes: fitur mareuman anggun di NGINX sareng PHP-FPM

A1, B1 - Narima parobahan ngeunaan kaayaan hearth nu
A2 - miang SIGTERM
B2 - Nyoplokkeun pod tina titik tungtung
B3 - Narima parobahan (daptar titik tungtung geus robah)
B4 - Ngamutahirkeun aturan iptables

Perhatikeun: ngahapus pod titik tungtung sareng ngirim SIGTERM henteu lumangsung sacara berurutan, tapi paralel. Sareng kusabab kanyataan yén Ingress henteu langsung nampi daptar Endpoints anu diropéa, pamundut énggal ti klien bakal dikirim ka pod, anu bakal nyababkeun kasalahan 500 nalika terminasi pod. (Pikeun bahan anu langkung rinci ngeunaan masalah ieu, urang ditarjamahkeun). Masalah ieu kedah direngsekeun ku cara-cara ieu:

  • Kirim Sambungan: nutup di headers respon (lamun ieu masalah hiji aplikasi HTTP).
  • Upami teu mungkin pikeun ngarobih kodeu, maka tulisan di handap ieu ngajelaskeun solusi anu bakal ngamungkinkeun anjeun ngolah pamundut dugi ka ahir jaman anggun.

Téori. Kumaha NGINX sareng PHP-FPM ngeureunkeun prosésna

NGINX

Hayu urang mimitian ku NGINX, sabab sadayana langkung atra sareng éta. Nyilem kana téori, urang diajar yén NGINX ngagaduhan hiji prosés master sareng sababaraha "pagawe" - ieu mangrupikeun prosés anak anu ngolah pamundut klien. Hiji pilihan merenah disadiakeun: ngagunakeun paréntah nginx -s <SIGNAL> nungtungan prosés boh dina shutdown gancang atawa mode shutdown anggun. Jelas, éta mangrupikeun pilihan anu terakhir anu dipikaresep ku urang.

Teras sadayana saderhana: anjeun kedah nambihan preStop-hook paréntah anu bakal ngirim sinyal shutdown anggun. Ieu tiasa dilakukeun dina Deployment, dina blok wadahna:

       lifecycle:
          preStop:
            exec:
              command:
              - /usr/sbin/nginx
              - -s
              - quit

Ayeuna, nalika pod pareum, urang bakal ningali ieu dina log wadah NGINX:

2018/01/25 13:58:31 [notice] 1#1: signal 3 (SIGQUIT) received, shutting down
2018/01/25 13:58:31 [notice] 11#11: gracefully shutting down

Sareng ieu bakal hartosna naon anu urang peryogikeun: NGINX ngantosan pamundut pikeun réngsé, teras maéhan prosésna. Nanging, di handap ieu urang ogé bakal nganggap masalah umum kusabab éta, sanaos paréntahna nginx -s quit prosés terminates lepat.

Sareng dina tahap ieu kami parantos dilakukeun sareng NGINX: sahenteuna tina log anjeun tiasa ngartos yén sadayana berpungsi sakumaha sakuduna.

Naon masalahna sareng PHP-FPM? Kumaha carana ngatur shutdown anggun? Hayu urang angka eta kaluar.

PHP-FPM

Dina kasus PHP-FPM, aya sakedik inpormasi. Lamun fokus kana manual resmi numutkeun PHP-FPM, éta bakal nyarios yén sinyal POSIX ieu ditampi:

  1. SIGINT, SIGTERM - shutdown gancang;
  2. SIGQUIT - shutdown anggun (naon urang kudu).

Sinyal sésana henteu diperyogikeun dina tugas ieu, ku kituna urang bakal ngaleungitkeun analisaana. Pikeun ngeureunkeun prosés anu leres, anjeun kedah nyerat hook preStop ieu:

        lifecycle:
          preStop:
            exec:
              command:
              - /bin/kill
              - -SIGQUIT
              - "1"

Dina glance kahiji, ieu sadayana anu diperlukeun pikeun ngalakukeun shutdown anggun dina duanana peti. Nanging, tugasna langkung sesah tibatan sigana. Di handap ieu aya dua kasus dimana shutdown anggun teu jalan sarta ngabalukarkeun unavailability jangka pondok tina proyék salila deployment.

Prakték. Mungkin masalah sareng shutdown anggun

NGINX

Munggaran sadaya, éta mangpaat pikeun nginget: sajaba ti executing paréntah nginx -s quit Aya hiji deui tahap anu patut diperhatikeun. Kami mendakan masalah dimana NGINX masih bakal ngirim SIGTERM tibatan sinyal SIGQUIT, nyababkeun pamenta henteu lengkep leres. Kasus anu sami tiasa dipendakan, contona, di dieu. Hanjakal, urang teu bisa nangtukeun alesan husus pikeun kabiasaan ieu: aya kacurigaan ngeunaan versi NGINX, tapi teu dikonfirmasi. Gejalana nyaéta pesen anu dititénan dina log wadah NGINX: "buka stop kontak #10 ditinggalkeun dina sambungan 5", sanggeus éta pod dieureunkeun.

Urang tiasa ningali masalah sapertos kitu, contona, tina réspon dina Ingress anu urang peryogikeun:

Tip & trik Kubernetes: fitur mareuman anggun di NGINX sareng PHP-FPM
Indikator kode status dina waktu deployment

Dina hal ieu, urang nampi ngan 503 kode kasalahan ti Ingress sorangan: eta teu bisa ngakses wadahna NGINX, sabab geus euweuh diaksés. Upami anjeun ningali log wadahna sareng NGINX, aranjeunna ngandung ieu:

[alert] 13939#0: *154 open socket #3 left in connection 16
[alert] 13939#0: *168 open socket #6 left in connection 13

Saatos ngarobih sinyal eureun, wadahna mimiti lirén leres: ieu dikonfirmasi ku kanyataan yén kasalahan 503 henteu ditingali deui.

Upami anjeun mendakan masalah anu sami, masuk akal pikeun terang mana sinyal eureun anu dianggo dina wadahna sareng kumaha persisna hook preStop. Ieu rada mungkin yén alesan perenahna persis dina ieu.

PHP-FPM... sareng seueur deui

Masalah sareng PHP-FPM dijelaskeun dina cara anu teu pati penting: éta henteu ngantosan parantosan prosés anak, éta ngeureunkeunana, naha éta 502 kasalahan lumangsung nalika panyebaran sareng operasi anu sanés. Aya sababaraha laporan bug dina bugs.php.net saprak 2005 (misalna di dieu и di dieu), anu ngajelaskeun masalah ieu. Tapi anjeun paling dipikaresep moal ningali nanaon dina log: PHP-FPM bakal ngumumkeun parantosan prosésna tanpa aya kasalahan atanapi bewara pihak katilu.

Perlu dijelaskeun yén masalahna sorangan tiasa gumantung kana sakedik atanapi langkung ageung kana aplikasi éta sorangan sareng tiasa waé henteu muncul, contona, dina ngawaskeun. Upami Sadérék sapatemon eta, hiji workaround basajan datang ka pikiran munggaran: nambahkeun hook preStop kalawan sleep(30). Ieu bakal ngidinan Anjeun pikeun ngarengsekeun sagala requests nu saméméhna (jeung kami teu nampa nu anyar, saprak pod enggeus sanggup Terminating), sarta sanggeus 30 detik pod sorangan bakal ditungtungan ku sinyal SIGTERM.

Tétéla éta lifecycle pikeun wadahna bakal siga kieu:

    lifecycle:
      preStop:
        exec:
          command:
          - /bin/sleep
          - "30"

Sanajan kitu, alatan 30 detik sleep urang niatna urang bakal nambahan waktu deployment, saprak unggal pod bakal terminated minimum 30 detik, anu goréng. Naon anu tiasa dilakukeun ngeunaan ieu?

Hayu urang giliran pihak nu tanggung jawab palaksanaan langsung tina aplikasi. Dina hal urang éta PHP-FPMyen sacara standar teu ngawas palaksanaan prosés anak na: Prosés master ieu terminated langsung. Anjeun tiasa ngarobih kabiasaan ieu nganggo diréktif process_control_timeout, nu nangtukeun wates waktu pikeun prosés anak ngadagoan sinyal ti master. Upami anjeun nyetél nilai ka 20 detik, ieu bakal nutupan seueur patarosan anu dijalankeun dina wadahna sareng bakal ngeureunkeun prosés master saatos réngsé.

Kalayan pangaweruh ieu, hayu urang balik deui ka masalah panungtungan urang. Sakumaha anu disebatkeun, Kubernetes sanés platform monolithic: komunikasi antara komponén anu béda butuh sababaraha waktos. Ieu hususna leres nalika urang nganggap operasi Ingresses sareng komponenana anu aya hubunganana, sabab kusabab telat sapertos kitu dina waktos panyebaran éta gampang pikeun kéngingkeun 500 kasalahan. Contona, kasalahan bisa lumangsung dina tahap ngirim pamundut ka hulu, tapi "waktu lag" interaksi antara komponén cukup pondok - kirang ti sadetik.

Ku alatan éta, Sakabehna kalawan diréktif geus disebutkeun process_control_timeout anjeun tiasa nganggo konstruksi handap pikeun lifecycle:

lifecycle:
  preStop:
    exec:
      command: ["/bin/bash","-c","/bin/sleep 1; kill -QUIT 1"]

Dina hal ieu, urang bakal ngimbangan reureuh ku paréntah sleep sarta ulah greatly ngaronjatkeun waktu deployment: aya béda noticeable antara 30 detik jeung hiji? .. Kanyataanna, éta process_control_timeoutjeung lifecycle ngan dipaké salaku "jaring kaamanan" bisi lag.

Umumna nyarios paripolah anu dijelaskeun sareng workaround anu cocog henteu ngan ukur pikeun PHP-FPM. Kaayaan anu sami tiasa waé timbul nalika ngagunakeun basa/kerangka anu sanés. Lamun teu bisa ngalereskeun shutdown anggun ku cara nu sejen - contona, ku nulis balik kode supados aplikasi neuleu ngolah sinyal terminasi - anjeun tiasa nganggo metodeu nu dijelaskeun. Ieu bisa jadi teu paling geulis, tapi gawéna.

Prakték. Uji beban pikeun mariksa operasi pod

Uji beban mangrupikeun salah sahiji cara pikeun mariksa kumaha wadahna jalan, sabab prosedur ieu ngadeukeutkeun kaayaan tempur nyata nalika pangguna nganjang ka situs. Pikeun nguji saran di luhur, anjeun tiasa nganggo Yandex.Tankom: Ieu nyertakeun sakabéh kaperluan urang sampurna. Ieu mangrupikeun tip sareng saran pikeun ngalaksanakeun tés kalayan conto anu jelas tina pangalaman kami berkat grafik Grafana sareng Yandex.Tank sorangan.

Hal pangpentingna didieu nyaeta pariksa parobahan step by step. Saatos nambahkeun fix anyar, ngajalankeun test tur tingal lamun hasilna geus robah dibandingkeun ngajalankeun panungtungan. Upami teu kitu, éta bakal hésé pikeun ngaidentipikasi solusi teu epektip, sarta dina jangka panjang eta ngan bisa ngarugikeun (contona, nambahan waktu deployment).

Nuansa sanésna nyaéta ningali log wadahna nalika terminasi. Naha inpormasi ngeunaan shutdown anggun kacatet di dinya? Naha aya kasalahan dina log nalika ngaksés sumber daya sanés (contona, kana wadah PHP-FPM tatangga)? Kasalahan dina aplikasi sorangan (sapertos dina kasus NGINX ditétélakeun di luhur)? Abdi ngarepkeun inpormasi bubuka tina tulisan ieu bakal ngabantosan anjeun langkung ngartos naon anu lumangsung dina wadahna nalika terminasi.

Janten, uji coba munggaran dilaksanakeun tanpa lifecycle sareng tanpa arahan tambahan pikeun server aplikasi (process_control_timeout dina PHP-FPM). Tujuan tina tés ieu nyaéta pikeun ngaidentipikasi perkiraan jumlah kasalahan (sareng naha aya). Ogé, tina inpormasi tambahan, anjeun kedah terang yén waktos panyebaran rata-rata pikeun unggal pod éta sakitar 5-10 detik dugi ka parantos siap. Hasilna nyaéta:

Tip & trik Kubernetes: fitur mareuman anggun di NGINX sareng PHP-FPM

Panel inpormasi Yandex.Tank nunjukkeun spike 502 kasalahan, anu lumangsung dina waktos panyebaran sareng tahan rata-rata dugi ka 5 detik. Panginten ieu kusabab pamenta anu tos aya ka pod lami ditungtungan nalika diputus. Saatos ieu, 503 kasalahan némbongan, anu mangrupikeun hasil tina wadah NGINX anu dieureunkeun, anu ogé ngirangan sambungan kusabab backend (anu ngahalangan Ingress nyambung ka dinya).

Hayu urang tingali kumaha process_control_timeout dina PHP-FPM bakal nulungan urang ngadagoan parantosan prosés anak, i.e. ngabenerkeun kasalahan sapertos kitu. Pasang deui nganggo diréktif ieu:

Tip & trik Kubernetes: fitur mareuman anggun di NGINX sareng PHP-FPM

Henteu aya deui kasalahan salami panyebaran ka-500! deployment suksés, shutdown anggun jalan.

Nanging, éta kedah émut kana masalah sareng wadah Ingress, perséntase leutik kasalahan dimana urang tiasa nampi kusabab lag waktos. Pikeun ngahindarkeun aranjeunna, sadaya anu tetep nyaéta pikeun nambihan struktur sleep jeung ngulang deployment. Nanging, dina kasus khusus urang, teu aya parobihan anu katingali (deui, teu aya kasalahan).

kacindekan

Pikeun nungtungan prosés anggun, kami ngarepkeun paripolah ieu tina aplikasi:

  1. Antosan sababaraha detik lajeng eureun narima sambungan anyar.
  2. Ngadagoan sagala requests ngalengkepan sarta nutup sakabeh sambungan keepalive nu teu executing requests.
  3. Mungkas prosés anjeun.

Nanging, henteu sadayana aplikasi tiasa jalan ku cara ieu. Hiji solusi pikeun masalah dina kanyataanana Kubernetes nyaéta:

  • nambahkeun hook pre-stop anu bakal antosan sababaraha detik;
  • diajar file konfigurasi backend urang pikeun parameter luyu.

Conto sareng NGINX ngajelaskeun yén sanajan aplikasi anu mimitina kedah ngolah sinyal terminasi kalayan leres tiasa henteu ngalakukeunana, janten penting pikeun pariksa 500 kasalahan nalika panyebaran aplikasi. Ieu ogé ngidinan Anjeun pikeun nempo masalah leuwih lega tur teu difokuskeun hiji pod tunggal atawa wadahna, tapi kasampak di sakabéh infrastruktur sakabéhna.

Salaku alat uji, anjeun tiasa nganggo Yandex.Tank ditéang sareng sistem ngawaskeun naon waé (dina hal kami, data dicandak tina Grafana nganggo backend Prometheus pikeun tés). Masalah sareng shutdown anggun jelas katingali dina beban beurat anu tiasa dibangkitkeun ku patokan, sareng ngawaskeun ngabantosan nganalisa kaayaan sacara langkung rinci nalika atanapi saatos ujian.

Dina respon kana eupan balik dina artikel: eta sia mentioning yén masalah jeung solusi dijelaskeun di dieu dina hubungan jeung NGINX Ingress. Pikeun kasus anu sanés, aya solusi anu sanés, anu tiasa urang pertimbangkeun dina bahan séri di handap ieu.

PS

Séjén ti séri tip & trik K8s:

sumber: www.habr.com

Tambahkeun komentar