Serişte û hîleyên Kubernetes: taybetmendiyên girtina dilşewat di NGINX û PHP-FPM de

Mercek tîpîk dema ku CI/CD li Kubernetes bicîh tîne: pêdivî ye ku serîlêdan berî ku bi tevahî raweste daxwazên xerîdar ên nû qebûl neke, û ya herî girîng jî, yên heyî bi serfirazî temam bike.

Serişte û hîleyên Kubernetes: taybetmendiyên girtina dilşewat di NGINX û PHP-FPM de

Lihevhatina bi vê şertê re dihêle ku hûn di dema veqetandinê de demdirêjiya sifir bi dest bixin. Lêbelê, tewra dema ku pakêtên pir populer (mîna NGINX û PHP-FPM) bikar bînin, hûn dikarin bi zehmetiyan re rû bi rû bimînin ku dê bi her sazkirinê re bibe sedema zêdebûna xeletiyan…

Dîtinî. Pod çawa dijî

Me berê bi hûrgulî li ser çerxa jiyanê ya podek weşandiye vê gotarê. Di çarçeweya mijara ku li ber çavan tê girtin de, em bi vê yekê re eleqedar dibin: dema ku pod dikeve nav dewletê Terminating, daxwazên nû ji wê re nayên şandin (pod derxistin ji navnîşa xalên dawî yên ji bo karûbarê). Ji ber vê yekê, ji bo ku di dema danînê de ji demdirêjiyê dûr nekevin, bes e ku em pirsgirêka rawestandina serîlêdanê rast çareser bikin.

Her weha divê hûn ji bîr mekin ku heyama keremê ya xwerû ye 30 seconds: piştî vê yekê, pod dê were qedandin û pêdivî ye ku serîlêdan berî vê heyamê dem hebe ku hemî daxwazan bişopîne. bingotin: her çend her daxwazek ku ji 5-10 saniyeyan zêdetir digire jixwe pirsgirêk e, û girtina dilşewat dê êdî alîkariya wê neke…

Ji bo baştir fêm bikin ka çi diqewime dema ku pod biqede, tenê li şemaya jêrîn binêrin:

Serişte û hîleyên Kubernetes: taybetmendiyên girtina dilşewat di NGINX û PHP-FPM de

A1, B1 - Guhertinên di derbarê rewşa ocax de werdigirin
A2 - Çûna SIGTERM
B2 - Rakirina podek ji xalên dawiyê
B3 - Guherandinên wergirtin (lîsteya xalên dawiyê guherî)
B4 - Rêgezên iptables nûve bikin

Ji kerema xwe not: jêbirina pod xala dawîn û şandina SIGTERM ne li pey hev, lê bi paralel pêk tê. Û ji ber ku Ingress tavilê navnîşa nûvekirî ya Endpoints wernagire, dê daxwazên nû yên xerîdar ji podê re werin şandin, ku dê di dema bidawîbûna pod de bibe sedema xeletiyek 500. (ji bo materyalên berfirehtir li ser vê mijarê, em wergerandin). Pêdivî ye ku ev pirsgirêk bi awayên jêrîn were çareser kirin:

  • Girêdanê bişîne: Sernavên bersivê bigire (heke ev serîlêdanek HTTP têkildar e).
  • Ger ne gengaz be ku hûn kodê guheztinan bikin, wê hingê gotara jêrîn çareseriyek diyar dike ku dê bihêle hûn heya dawiya heyama dilşewat serlêdanan bikin.

Dîtinî. Çawa NGINX û PHP-FPM pêvajoyên xwe bi dawî dikin

NGINX

Ka em bi NGINX-ê dest pê bikin, ji ber ku her tişt bi wê re kêm-zêde eşkere ye. Di teoriyê de, em fêr dibin ku NGINX xwedan pêvajoyek master û çend "karker" e - ev pêvajoyên zarok in ku daxwazên xerîdar dişoxilînin. Vebijarkek hêsan tê peyda kirin: karanîna fermanê nginx -s <SIGNAL> pêvajoyên di girtina bilez an jî di moda girtina xweş de biqedînin. Eşkere ye ku ev vebijarka paşîn e ku me eleqedar dike.

Wê hingê her tişt hêsan e: hûn hewce ne ku lê zêde bikin preStop-hook fermanek ku dê îşaretek girtina xweş bişîne. Ev dikare di Deployment de, di bloka konteynerê de were kirin:

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

Naha, gava ku pod biqede, em ê di têketinên konteynerê NGINX de jêrîn bibînin:

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

Û ev ê wateya ku em hewce dike: NGINX li benda temamkirina daxwazan e, û paşê pêvajoyê dikuje. Lêbelê, li jêr em ê pirsgirêkek hevpar jî binirxînin ku ji ber vê yekê, tewra bi fermanê re nginx -s quit pêvajo bi xeletî bi dawî dibe.

Û di vê qonaxê de em bi NGINX-ê re qediyan: bi kêmanî ji têketin hûn dikarin fêm bikin ku her tişt wekî ku divê dixebite.

Peymana bi PHP-FPM re çi ye? Meriv çawa bi girtina dilovan re mijûl dibe? Werin em wê bihesibînin.

PHP-FPM

Di doza PHP-FPM de, agahdariyek piçûktir heye. Ger hûn li ser bisekinin manual fermî li gorî PHP-FPM, ew ê bêje ku nîşanên POSIX yên jêrîn têne pejirandin:

  1. SIGINT, SIGTERM - girtina bilez;
  2. SIGQUIT - girtina dilşewat (ya ku em hewce ne).

Nîşaneyên mayî di vê peywirê de ne hewce ne, ji ber vê yekê em ê analîza wan berdin. Ji bo ku pêvajo bi rengek rast biqede, hûn ê hewce bikin ku hookê preStop jêrîn binivîsin:

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

Di nihêrîna pêşîn de, ev her tiştê ku hewce ye ku meriv di her du konteyneran de qutkirinek dilşewat pêk bîne. Lêbelê, kar ji ku xuya dike dijwartir e. Li jêr du halet hene ku tê de girtina dilşewat nexebitî û bû sedema nebûna kurt a projeyê di dema bicîhkirinê de.

Bikaranînî. Pirsgirêkên muhtemel ên bi girtina xweş

NGINX

Berî her tiştî, kêrhatî ye ku ji bîr mekin: ji bilî pêkanîna fermanê nginx -s quit Qonaxek din jî heye ku hêjayî balkişandinê ye. Me rastî pirsgirêkek hat ku NGINX dê dîsa jî li şûna sînyala SIGQUIT SIGTERM bişîne, dibe sedema ku daxwaz bi rêkûpêk neqede. Bûyerên bi vî rengî dikarin werin dîtin, bo nimûne, vir. Mixabin, me nekarî sedema taybetî ya vê tevgerê diyar bikin: gumanek li ser guhertoya NGINX hebû, lê ew nehat pejirandin. Nîşan ev bû ku peyam di têketinên konteynerê NGINX de hatin dîtin: "Socket #10 veke di girêdana 5 de maye", piştî ku pod rawestandin.

Em dikarin pirsgirêkek wusa bişopînin, mînakî, ji bersivên li ser Ingress ku em hewce ne:

Serişte û hîleyên Kubernetes: taybetmendiyên girtina dilşewat di NGINX û PHP-FPM de
Nîşaneyên kodên statûyê di dema bicîhkirinê de

Di vê rewşê de, em tenê kodek xeletiyek 503 ji Ingress bixwe distînin: ew nikare xwe bigihîne konteynera NGINX, ji ber ku ew êdî nayê gihîştin. Ger hûn li têketinên konteynerê bi NGINX re mêze bikin, ew jêrîn hene:

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

Piştî guheztina nîşana rawestandinê, konteynir dest pê dike ku rast bisekine: ev ji hêla rastiyê ve tê pejirandin ku xeletiya 503 êdî nayê dîtin.

Ger hûn bi pirsgirêkek wusa re rû bi rû bimînin, maqûl e ku hûn fêhm bikin ka çi sînyala rawestanê di konteynerê de tê bikar anîn û bi rastî çengê preStop çawa xuya dike. Pir mimkun e ku sedem tam di vê yekê de be.

PHP-FPM ... û bêtir

Pirsgirêka PHP-FPM bi rengek piçûk tête diyar kirin: ew li benda qedandina pêvajoyên zarokê namîne, ew wan biqedîne, ji ber vê yekê 502 xeletî di dema danîn û operasyonên din de çêdibin. Li ser bugs.php.net ji 2005-an vir ve gelek raporên xeletiyê hene (mînak vir и vir), ku vê pirsgirêkê diyar dike. Lê bi îhtîmalek mezin hûn ê di têketinê de tiştek nebînin: PHP-FPM dê bidawîbûna pêvajoya xwe bêyî xeletî an agahdariya partiya sêyemîn ragihîne.

Hêjayî ronîkirinê ye ku pirsgirêk bixwe dibe ku kêm an zêde bi serîlêdanê bixwe ve girêdayî be û dibe ku xwe, mînakî, di şopandinê de diyar neke. Ger hûn pê re rû bi rû bimînin, pêşî çareseriyek hêsan tê bîra we: pêvekek preStop pê re zêde bikin sleep(30). Ew ê bihêle ku hûn hemî daxwazên ku berê bûn temam bikin (û em yên nû qebûl nakin, ji ber ku pod êdî karîn ji Terminating), û piştî 30 çirkeyan dê pod bixwe bi îşaretekê biqede SIGTERM.

Ew dizane ku lifecycle ji bo konteynir dê wiha xuya bike:

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

Lêbelê, ji ber 30-duyemîn sleep em in pir em ê dema bicîhkirinê zêde bikin, ji ber ku her pod dê were qedandin herî kêm 30 seconds, ku xerab e. Di derbarê vê de çi dikare were kirin?

Werin em berê xwe bidin partiya ku ji pêkanîna rasterast a serlêdanê berpirsiyar e. Di rewşa me de ew e PHP-FPM, kîjan ji hêla xwerû ve pêkanîna pêvajoyên zaroka xwe neşopîne: Pêvajoya master tavilê bi dawî dibe. Hûn dikarin vê tevgerê bi karanîna rêbernameyê biguherînin process_control_timeout, ku sînorên demê diyar dike ji bo pêvajoyên zarokan ku li benda îşaretên ji masterê bisekinin. Ger hûn nirxê li ser 20 çirkeyan destnîşan bikin, ev ê piraniya lêpirsînên ku di konteynerê de têne xebitandin vegire û piştî ku ew qediyan dê pêvajoya masterê rawestîne.

Bi vê zanînê, em vegerin ser pirsgirêka xwe ya dawî. Wekî ku hate gotin, Kubernetes ne platformek yekparêz e: ragihandina di navbera pêkhateyên wê yên cihêreng de hin dem digire. Ev bi taybetî rast e dema ku em operasyona Ingresses û pêkhateyên din ên têkildar dihesibînin, ji ber ku ji ber derengiyek wusa di dema bicîhkirinê de ew hêsan e ku meriv 500 xeletî bi dest bixe. Mînakî, dibe ku di qonaxa şandina daxwazek ji jorîn re xeletiyek çêbibe, lê "derengiya dem" ya danûstendina di navbera pêkhateyan de pir kurt e - ji saniyeyekê kêmtir e.

Ji ber vê yekê, Bi tevayî bi dîrektîfa ku berê hatî behs kirin process_control_timeout hûn dikarin ji bo avakirina jêrîn bikar bînin lifecycle:

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

Di vê rewşê de em ê derengmayînê bi fermanê telafî bikin sleep û dema veqetandinê pir zêde nekin: gelo ferqek berbiçav di navbera 30 çirke û yekê de heye?.. Bi rastî, ew e process_control_timeoutû lifecycle Di dema derengiyê de tenê wekî "tora ewlehiyê" tê bikar anîn.

Bi gelemperî behreya diyarkirî û çareya têkildar ne tenê ji PHP-FPM re derbas dibe. Di dema bikaranîna ziman/çarçoveyên din de dibe ku rewşek bi vî rengî derkeve holê. Ger hûn nikaribin girtina dilşewat bi awayên din rast bikin - mînakî, bi ji nû ve nivîsandina kodê da ku serîlêdan bi rast nîşanên bidawîbûnê bişopîne - hûn dikarin rêbaza diyarkirî bikar bînin. Dibe ku ew ne ya herî xweşik be, lê ew dixebite.

Bikaranînî. Testkirina barkirinê ji bo kontrolkirina operasyona pod

Testkirina barkirinê yek ji wan awayan e ku meriv kontrol bike ka konteynir çawa dixebite, ji ber ku ev prosedur dema ku bikarhêner serdana malperê dikin wê nêzîkê şert û mercên şer ên rastîn dike. Ji bo ceribandina pêşniyarên jorîn, hûn dikarin bikar bînin Yandex.Tankom: Ew hemî hewcedariyên me bi tevahî pêk tîne. Li jêr serişte û pêşnîyarên ji bo ceribandina bi mînakek zelal ji ezmûna me bi saya grafikên Grafana û Yandex.Tank bixwe ne.

Ya herî girîng li vir e gav bi gav guhertinên kontrol bikin. Piştî lêzêdekirina rastkirinek nû, ceribandinê bimeşînin û bibînin ka encam li gorî gera paşîn hatine guhertin. Wekî din, dê dijwar be ku meriv çareseriyên bêbandor nas bike, û di demek dirêj de ew tenê dikare zirarê bide (mînak, dema bicîhkirinê zêde bike).

Nîşanek din ev e ku meriv di dema bidawîbûna wê de li têketinên konteynerê binêre. Agahdariya li ser girtina xweş li wir hatî tomar kirin? Dema ku meriv bigihîje çavkaniyên din (mînak, konteynirek cîranê PHP-FPM) di têketinan de xeletî hene? Çewtiyên di serîlêdanê bixwe de (wekî di doza NGINX de ku li jor hatî destnîşan kirin)? Ez hêvî dikim ku agahdariya destpêkê ya ji vê gotarê dê ji we re bibe alîkar ku hûn çêtir fam bikin ka di dema bidawîbûna wê de çi diqewime.

Ji ber vê yekê, yekem ceribandina ceribandinê bêyî pêk hat lifecycle û bêyî rêwerzên zêde ji bo servera serîlêdanê (process_control_timeout di PHP-FPM de). Armanca vê testê ew bû ku hejmara xeletiyên texmînî (û hebin) nas bike. Di heman demê de, ji agahdariya pêvek, divê hûn zanibin ku dema navînî ya bicîhkirinê ji bo her podek nêzî 5-10 saniyeyan bû heya ku ew bi tevahî amade bû. Encam ev in:

Serişte û hîleyên Kubernetes: taybetmendiyên girtina dilşewat di NGINX û PHP-FPM de

Panela agahdariyê ya Yandex.Tank 502 xeletiyan nîşan dide, ku di dema bicîhkirinê de çêbûne û bi navînî heya 5 çirkeyan dom kir. Tê texmîn kirin ku ev ji ber ku daxwazên heyî yên ji podê kevn re dema ku ew bi dawî bû dihatin betal kirin. Piştî vê yekê, 503 xeletî xuya bûn, ku encama konteynirek NGINX ya rawestandî bû, ku di heman demê de ji ber paşvekêşanê (ya ku nehişt ku Ingress bi wê ve girêbide) pêwendiyan davêje.

Ka em çawa bibînin process_control_timeout di PHP-FPM de dê ji me re bibe alîkar ku li benda qedandina pêvajoyên zarokan bisekinin, ango. xeletiyên weha rast bikin. Bi karanîna vê rêwerzê ji nû ve bicîh bikin:

Serişte û hîleyên Kubernetes: taybetmendiyên girtina dilşewat di NGINX û PHP-FPM de

Di dema şandina 500-an de bêtir xeletî tune! Dabeşkirin serketî ye, karên girtina dilşewat e.

Lêbelê, hêja ye ku kêliya bi konteynerên Ingress-ê, rêjeyek piçûk a xeletiyên ku tê de em dikarin ji ber derengiya demê werbigirin bi bîr bînin. Ji bo ku ji wan dûr nekevin, ya ku dimîne ev e ku meriv avahiyek pê re lê zêde bike sleep û veguhestinê dubare bikin. Lêbelê, di doza meya taybetî de, ti guhertin xuya nebûn (dîsa, bê xeletî).

encamê

Ji bo ku pêvajo bi dilovanî biqede, em ji serîlêdanê behreya jêrîn hêvî dikin:

  1. Çend saniyan bisekinin û dûv re pejirandina girêdanên nû rawestînin.
  2. Li bendê bin ku hemî daxwazname temam bibin û hemî girêdanên parastinê yên ku daxwazan pêk naynin bigirin.
  3. Pêvajoya xwe bi dawî bikin.

Lêbelê, ne hemî serîlêdan dikarin bi vî rengî bixebitin. Yek çareseriya pirsgirêkê di rastiyên Kubernetes de ev e:

  • lêzêdekirina hookek pêş-rawestanê ku dê çend saniyan li bendê bimîne;
  • ji bo pîvanên guncan pelê veavakirinê ya paşîna me dixwînin.

Mînaka bi NGINX re eşkere dike ku tewra serîlêdanek ku divê di destpêkê de îşaretên bidawîbûnê rast bişopîne jî dibe ku wiya neke, ji ber vê yekê girîng e ku hûn di dema bicîhkirina serîlêdanê de 500 xeletiyan kontrol bikin. Ev di heman demê de dihêle hûn li pirsgirêkê bi berfirehî binihêrin û li ser yek pod an konteynerek nesekinin, lê li tevahî binesaziyê bi tevahî binihêrin.

Wekî amûrek ceribandinê, hûn dikarin Yandex.Tank bi her pergalek çavdêriyê re têkildar bikar bînin (di rewşa me de, daneya ji Grafana bi pişta Prometheus ji bo ceribandinê hate girtin). Pirsgirêkên bi girtina dilşewat di bin barên giran ên ku pîvan dikare çêbike de bi zelalî têne xuyang kirin, û çavdêrî ji bo analîzkirina rewşê bi hûrgulî di dema ceribandinê de an piştî ceribandinê dibe alîkar.

Di bersiva bersivdayînê de li ser gotarê: Hêjayî gotinê ye ku pirsgirêk û çareserî li vir bi NGINX Ingress ve têne diyar kirin. Ji bo rewşên din, çareseriyên din hene, ku em dikarin di materyalên jêrîn ên rêzê de bifikirin.

PS

Din ji rêzikên serişte û hîleyên K8s:

Source: www.habr.com

Add a comment