Маслиҳатҳо ва ҳилаҳои Kubernetes: хусусиятҳои қатъи зебо дар NGINX ва PHP-FPM

Ҳолати маъмулӣ ҳангоми татбиқи CI/CD дар Kubernetes: барнома бояд қодир бошад, ки дархостҳои нави муштариёнро пеш аз қатъи пурра қабул накунад ва муҳимтар аз ҳама, дархостҳои мавҷударо бомуваффақият анҷом диҳад.

Маслиҳатҳо ва ҳилаҳои Kubernetes: хусусиятҳои қатъи зебо дар NGINX ва PHP-FPM

Риоя кардани ин шарт ба шумо имкон медиҳад, ки ҳангоми ҷойгиркунӣ ба сифр вақти бекорӣ ноил шавед. Бо вуҷуди ин, ҳатто ҳангоми истифодаи бастаҳои хеле маъмул (ба монанди NGINX ва PHP-FPM), шумо метавонед бо мушкилоте рӯ ба рӯ шавед, ки ҳангоми ҳар як ҷойгиркунӣ боиси афзоиши хатогиҳо мегардад...

Назария. Под чӣ тавр зиндагӣ мекунад

Мо аллакай ба таври муфассал дар бораи давраи зиндагии як pod нашр кардаем Ин мақола. Дар заминаи мавзӯи баррасишаванда, мо ба инҳо таваҷҷӯҳ дорем: дар айни замон, ки под ба давлат ворид мешавад. Хотима, фиристодани дархостҳои нав ба он қатъ карда мешавад (под хориҷ карда шуд аз рӯйхати нуқтаҳои ниҳоӣ барои хидмат). Ҳамин тариқ, барои пешгирӣ кардани бекорӣ ҳангоми ҷойгиркунӣ, барои мо кофӣ аст, ки масъалаи қатъи барномаро дуруст ҳал кунем.

Шумо инчунин бояд дар хотир доред, ки давраи имтиёзи пешфарз аст 30 сония: пас аз ин, pod қатъ карда мешавад ва барнома бояд барои коркарди ҳама дархостҳо пеш аз ин мӯҳлат вақт дошта бошад. эрод гирифтан: гарчанде ки ҳама дархосте, ки беш аз 5-10 сонияро мегирад, аллакай мушкил аст ва хомӯшии зебо дигар ба он кӯмак намекунад...

Барои беҳтар фаҳмидани он, ки ҳангоми қатъ шудани pod чӣ рӯй медиҳад, танҳо ба диаграммаи зерин нигаред:

Маслиҳатҳо ва ҳилаҳои Kubernetes: хусусиятҳои қатъи зебо дар NGINX ва PHP-FPM

A1, B1 - Гирифтани тағйирот дар бораи ҳолати оташдон
A2 - SIGTERM рафтан
B2 - Хориҷ кардани як паҳлӯ аз нуқтаҳои ниҳоӣ
B3 - Гирифтани тағирот (рӯйхати нуқтаҳо тағир ёфтааст)
B4 - Навсозии қоидаҳои iptables

Лутфан таваҷҷӯҳ намоед: нест кардани пойгоҳи ниҳоӣ ва фиристодани SIGTERM на пай дар пай, балки дар баробари он сурат мегирад. Ва аз сабаби он, ки Ingress рӯйхати навшудаи Endpoints -ро фавран қабул намекунад, дархостҳои нав аз муштариён ба подк фиристода мешаванд, ки ҳангоми қатъ кардани подк 500 хатогиро ба вуҷуд меорад. (барои маълумоти муфассалтар оид ба ин масъала, мо тарҷума шудааст). Ин масъаларо бо роҳҳои зерин ҳал кардан лозим аст:

  • Ирсоли Пайваст: дар сарлавҳаҳои посух пӯшед (агар ин ба барномаи HTTP дахл дошта бошад).
  • Агар имконнопазирии ворид кардани тағирот ба код, пас мақолаи зерин ҳалли онро тавсиф мекунад, ки ба шумо имкон медиҳад дархостҳоро то охири давраи имтиёзнок коркард кунед.

Назария. Чӣ тавр NGINX ва PHP-FPM равандҳои худро қатъ мекунанд

NGINX

Биёед бо NGINX оғоз кунем, зеро бо он ҳама чиз бештар ё камтар аён аст. Ба назария ворид шуда, мо мефаҳмем, ки NGINX як раванди асосӣ ва якчанд "коргарон" дорад - ин равандҳои кӯдакона мебошанд, ки дархостҳои муштариёнро коркард мекунанд. Варианти мувофиқ пешниҳод карда мешавад: бо истифода аз фармон nginx -s <SIGNAL> равандҳоро дар ҳолати қатъи зуд ё ҳолати зебо қатъ кунед. Аён аст, ки ин варианти охирин моро ба худ ҷалб мекунад.

Он гоҳ ҳама чиз оддӣ аст: шумо бояд илова кунед preStop-қалмоқ фармоне, ки як сигнали хомӯш фиристад. Инро метавон дар Deployment, дар блоки контейнер анҷом дод:

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

Ҳоло, вақте ки подкаст хомӯш мешавад, мо дар гузоришҳои контейнерии 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

Ва ин маънои онро дорад, ки ба мо лозим аст: NGINX интизори анҷоми дархостҳо аст ва сипас ин равандро мекушад. Бо вуҷуди ин, дар зер мо инчунин як мушкилоти умумиро баррасӣ хоҳем кард, ки бинобар он ҳатто бо фармон nginx -s quit процесс нодуруст ба охир мерасад.

Ва дар ин марҳила мо бо NGINX анҷом ёфтем: ҳадди аққал аз гузоришҳо шумо метавонед фаҳмед, ки ҳама чиз тавре ки лозим аст, кор мекунад.

Муомила бо PHP-FPM чист? Он чӣ гуна қатъшавии зеборо идора мекунад? Биёед инро фаҳмем.

PHP-FPM

Дар мавриди PHP-FPM, маълумоти каме камтар аст. Агар шумо ба он диққат диҳед дастури расмӣ мувофиқи PHP-FPM, он мегӯяд, ки сигналҳои зерини POSIX қабул карда мешаванд:

  1. SIGINT, SIGTERM — зуд хомӯш шудан;
  2. SIGQUIT - хомӯшии зебо (он чизе ки ба мо лозим аст).

Сигналҳои боқимонда дар ин вазифа талаб карда намешаванд, бинобар ин мо таҳлили онҳоро сарфи назар мекунем. Барои дуруст қатъ кардани раванд, ба шумо лозим меояд, ки қуттии зерини preStop -ро нависед:

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

Дар назари аввал, ин ҳама чизест, ки барои хомӯш кардани зебо дар ҳарду контейнер лозим аст. Бо вуҷуди ин, вазифа аз он ки ба назар мерасад, душвортар аст. Дар зер ду ҳолате оварда шудааст, ки дар он қатъкунии зебо кор накард ва боиси дастрасии кӯтоҳмуддати лоиҳа дар вақти ҷойгиркунӣ гардид.

Амал кунед. Мушкилоти эҳтимолӣ бо бастани зебо

NGINX

Пеш аз хама, дар хотир доштан муфид аст: гайр аз ичрои фармон nginx -s quit Боз як марҳалаи дигар вуҷуд дорад, ки ба он таваҷҷӯҳ кардан лозим аст. Мо бо мушкилоте рӯ ба рӯ шудем, ки NGINX ҳоло ҳам ба ҷои сигнали SIGQUIT SIGTERM мефиристад ва ин боиси дуруст анҷом наёфтани дархостҳо мегардад. Чунин ҳолатҳоро метавон ёфт, масалан, дар ин ҷо. Мутаассифона, мо сабаби мушаххаси ин рафторро муайян карда натавонистем: дар бораи версияи NGINX шубҳа вуҷуд дошт, аммо он тасдиқ нашудааст. Аломат ин буд, ки паёмҳо дар гузоришҳои контейнерии NGINX мушоҳида мешуданд "розеткаи кушоди №10 дар пайвасти 5 мондааст", ки баъд аз он подразделения катъ гардид.

Мо метавонем чунин мушкилотро мушоҳида кунем, масалан, аз посухҳо ба Ingress ба мо лозим аст:

Маслиҳатҳо ва ҳилаҳои Kubernetes: хусусиятҳои қатъи зебо дар NGINX ва PHP-FPM
Нишондиҳандаҳои рамзҳои вазъият дар вақти ҷойгиркунӣ

Дар ин ҳолат, мо аз худи Ingress танҳо як рамзи хатои 503 мегирем: он наметавонад ба контейнери NGINX дастрасӣ пайдо кунад, зеро он дигар дастрас нест. Агар шумо ба гузоришҳои контейнерӣ бо NGINX нигаред, онҳо дорои инҳоянд:

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

Пас аз тағир додани сигнали қатъ, контейнер дуруст қатъ мешавад: ин бо он тасдиқ карда мешавад, ки хатогии 503 дигар мушоҳида намешавад.

Агар шумо бо мушкилоти шабеҳ дучор шавед, фаҳмидани он, ки дар контейнер кадом сигнали таваққуф истифода мешавад ва қалмоқчаи preStop чӣ гуна аст, маъно дорад. Комилан мумкин аст, ки сабаб махз дар хамин бошад.

PHP-FPM... ва ғайра

Мушкилоти PHP-FPM ба таври ночиз тасвир шудааст: он мунтазири анҷоми равандҳои кӯдакона нест, онҳоро қатъ мекунад, бинобар ин ҳангоми ҷойгиркунӣ ва дигар амалиётҳо 502 хатогӣ рух медиҳад. Аз соли 2005 дар bugs.php.net якчанд гузоришҳо оид ба хатогиҳо мавҷуданд (масалан дар ин ҷо и дар ин ҷо), ки ин мушкилотро тавсиф мекунад. Аммо шумо эҳтимолан дар гузоришҳо чизе нахоҳед дид: PHP-FPM анҷоми раванди худро бидуни ягон хатогӣ ё огоҳиҳои тарафи сеюм эълон мекунад.

Бояд фаҳмонем, ки худи мушкилот метавонад ба андозаи камтар ё бештар аз худи барнома вобаста бошад ва метавонад, масалан, дар мониторинг зоҳир нашавад. Агар шумо бо он рӯ ба рӯ шавед, аввал як роҳи ҳалли оддӣ ба хотир меояд: қалмоқчаи preStop -ро илова кунед sleep(30). Он ба шумо имкон медиҳад, ки ҳама дархостҳоеро, ки қаблан буданд, иҷро кунед (ва мо дархостҳои навро қабул намекунем, зеро pod аллакай қодир аст Хотима), ва пас аз 30 сония худаш бо сигнал тамом мешавад SIGTERM.

Ин рӯй медиҳад lifecycle зеро контейнер чунин хоҳад буд:

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

Бо вуҷуди ин, аз сабаби 30-сония sleep мо ҳастем қавӣ мо вақти ҷойгиркуниро зиёд хоҳем кард, зеро ҳар як pod қатъ карда мешавад ҳадди аққал 30 сония, ки бад аст. Дар ин бора чй кор кардан мумкин аст?

Ба тарафи масъули ичрои бевоситаи ариза мурочиат мекунем. Дар мавриди мо чунин аст PHP-FPM, ки ба таври нобаёнӣ иҷрои равандҳои кӯдаки худро назорат намекунад: Раванди асосӣ фавран қатъ карда мешавад. Шумо метавонед ин рафторро бо истифода аз дастур тағир диҳед process_control_timeout, ки маҳдудиятҳои вақтро барои равандҳои кӯдакон барои интизории сигналҳо аз устод муайян мекунад. Агар шумо арзишро ба 20 сония муқаррар кунед, ин аксари дархостҳои дар контейнер иҷрошавандаро фаро мегирад ва пас аз анҷоми онҳо раванди асосӣро қатъ мекунад.

Бо ин дониш бармегардем ба масъалаи охирини худ. Тавре зикр гардид, Кубернетес платформаи монолитӣ нест: иртибот байни ҷузъҳои гуногуни он каме вақт мегирад. Ин махсусан вақте дуруст аст, ки мо кори Ingresses ва дигар ҷузъҳои ба он алоқамандро баррасӣ мекунем, зеро аз сабаби чунин таъхир дар вақти ҷойгиркунӣ афзоиши 500 хатогиҳо осон аст. Масалан, дар марҳилаи фиристодани дархост ба болооб метавонад хатогӣ рух диҳад, аммо "қафомонии вақт"-и ҳамкории байни ҷузъҳо хеле кӯтоҳ аст - камтар аз як сония.

Аз ин рӯ, Дар маҷмӯъ бо дастури зикршуда process_control_timeout шумо метавонед барои сохтмони зерин истифода баред lifecycle:

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

Дар ин сурат мо бо фармондо-рй таъхирро чуброн мекунем sleep ва вақти ҷойгиркуниро хеле зиёд накунед: оё байни 30 сония ва як сония фарқияти назаррас вуҷуд дорад?.. Дар асл, ин аст process_control_timeoutва lifecycle дар сурати акибмонй танхо хамчун «сети бехатарй» истифода мешавад.

Одатан сухан мегӯянд рафтори тавсифшуда ва ҳалли мувофиқ на танҳо ба PHP-FPM дахл дорад. Вазъияти шабеҳ метавонад бо ин ё он роҳ ҳангоми истифодаи забонҳои/чаҳорчӯбаҳои дигар ба миён ояд. Агар шумо хомӯшии зеборо бо роҳҳои дигар ислоҳ карда натавонед - масалан, аз нав навиштани код, то барнома сигналҳои қатъиро дуруст коркард кунад - шумо метавонед усули тавсифшударо истифода баред. Шояд он зеботарин набошад, аммо он кор мекунад.

Амал кунед. Санҷишро бор кунед, то кори онро тафтиш кунед

Санҷиши боркунӣ яке аз роҳҳои тафтиши кори контейнер мебошад, зеро ин тартиб ҳангоми дидани корбарон ба сайт онро ба шароити воқеии ҷанг наздиктар мекунад. Барои санҷидани тавсияҳои дар боло зикршуда, шумо метавонед истифода баред Яндекс.Танком: Вай тамоми эхтиёчоти моро комилан конеъ мегардонад. Дар зер маслиҳатҳо ва тавсияҳо оид ба гузаронидани санҷиш бо мисоли равшан аз таҷрибаи мо ба шарофати графикҳои худи Grafana ва Yandex.Tank оварда шудаанд.

Муҳимтарин чиз дар ин ҷо аст тағйиротро зина ба зина тафтиш кунед. Пас аз илова кардани ислоҳи нав, санҷишро иҷро кунед ва бубинед, ки натиҷаҳо дар муқоиса бо даври охирин тағир ёфтаанд. Дар акси ҳол, муайян кардани ҳалли бесамар душвор хоҳад буд ва дар дарозмуддат он метавонад танҳо зарар расонад (масалан, вақти ҷойгиркуниро зиёд кунад).

Як нюанси дигар ин аст, ки ҳангоми қатъ кардани он ба гузоришҳои контейнер назар кунед. Оё дар он ҷо маълумот дар бораи қатъи зебо сабт шудааст? Оё дар гузоришҳо ҳангоми дастрасӣ ба захираҳои дигар (масалан, контейнери ҳамсояи PHP-FPM) ягон хатогӣ вуҷуд дорад? Хатогиҳо дар худи барнома (чунон ки дар ҳолати дар боло бо NGINX тавсифшуда)? Ман умедворам, ки маълумоти муқаддимавии ин мақола ба шумо кӯмак мекунад, ки беҳтар фаҳмед, ки бо контейнер ҳангоми қатъ кардани он чӣ рӯй медиҳад.

Инак, озмоиши аввалин бе он сурат гирифт lifecycle ва бидуни дастурҳои иловагӣ барои сервери барнома (process_control_timeout дар PHP-FPM). Мақсади ин санҷиш муайян кардани шумораи тахминии хатогиҳо (ва мавҷудияти онҳо) буд. Инчунин, аз маълумоти иловагӣ, шумо бояд бидонед, ки вақти миёнаи ҷойгиркунӣ барои ҳар як подкӯҳ тақрибан 5-10 сонияро ташкил дод, то он даме, ки он пурра омода шуд. Натиҷаҳо инҳоянд:

Маслиҳатҳо ва ҳилаҳои Kubernetes: хусусиятҳои қатъи зебо дар NGINX ва PHP-FPM

Панели иттилоотии Яндекс.Танк суръати 502 хатогиро нишон медиҳад, ки ҳангоми ҷойгиркунӣ рух дода, ба ҳисоби миёна то 5 сония давом мекард. Эҳтимол, ин аз он сабаб буд, ки дархостҳои мавҷуда ба поди кӯҳна ҳангоми қатъ шудани он қатъ карда мешуданд. Пас аз ин, 503 хатогӣ пайдо шуд, ки дар натиҷаи як контейнери қатъшудаи NGINX буд, ки он низ аз сабаби пуштибонӣ пайвастҳоро қатъ кард (ки ба Ingress пайваст шудан ба он монеъ шуд).

Биёед бубинем, ки чӣ тавр process_control_timeout дар PHP-FPM ба мо кӯмак мекунад, ки интизории анҷоми равандҳои кӯдакона, яъне. чунин хатогихоро ислох. Бо истифода аз ин дастур дубора ҷойгир кунед:

Маслиҳатҳо ва ҳилаҳои Kubernetes: хусусиятҳои қатъи зебо дар NGINX ва PHP-FPM

Ҳангоми ҷойгиркунии 500-ум дигар хатогӣ вуҷуд надорад! Ҷойгиркунӣ бомуваффақият аст, кори қатъии зебо.

Бо вуҷуди ин, зарур аст, ки масъаларо бо контейнерҳои Ingress, як фоизи ками хатогиҳое, ки мо бо сабаби таъхири вақт гирифта метавонем, ба ёд орем. Барои пешгирӣ кардани онҳо, танҳо илова кардани сохтор бо он боқӣ мемонад sleep ва ҷойгиркуниро такрор кунед. Аммо, дар ҳолати мушаххаси мо, ҳеҷ гуна тағирот ба назар намерасид (боз хатогиҳо).

хулоса

Барои ба таври зебо қатъ кардани раванд, мо аз барнома рафтори зеринро интизорем:

  1. Чанд сония интизор шавед ва сипас қабули пайвастҳои навро қатъ кунед.
  2. Мунтазир шавед, ки ҳама дархостҳо анҷом ёбанд ва ҳама пайвастҳои нигоҳдорӣ, ки дархостҳоро иҷро намекунанд.
  3. Раванди худро хотима диҳед.

Аммо, на ҳама барномаҳо метавонанд ин тавр кор кунанд. Як роҳи ҳалли мушкилот дар воқеияти Кубернетес ин аст:

  • илова кардани қалмоқе, ки чанд сония интизор мешавад;
  • омӯхтани файли конфигуратсияи пуштибонии мо барои параметрҳои мувофиқ.

Намунаи NGINX равшан нишон медиҳад, ки ҳатто барномае, ки бояд дар аввал сигналҳои қатъкуниро дуруст коркард кунад, ин корро карда наметавонад, аз ин рӯ тафтиш кардани 500 хато ҳангоми ҷойгиркунии барнома муҳим аст. Ин инчунин ба шумо имкон медиҳад, ки мушкилотро васеътар бубинед ва на ба як қуттӣ ё контейнер тамаркуз кунед, балки ба тамоми инфрасохтор дар маҷмӯъ назар кунед.

Ҳамчун воситаи санҷиш, шумо метавонед Yandex.Tank-ро дар якҷоягӣ бо ҳама гуна системаи мониторинг истифода баред (дар ҳолати мо, маълумот аз Grafana бо пуштибонии Prometheus барои санҷиш гирифта шудааст). Мушкилот бо бастани зебо дар зери бори вазнин, ки меъёр метавонад тавлид кунад, ба таври возеҳ намоён аст ва мониторинг барои таҳлили муфассали вазъ дар давоми ё пас аз санҷиш кӯмак мекунад.

Дар посух ба фикру мулоҳизаҳо дар бораи мақола: бояд қайд кард, ки мушкилот ва роҳҳои ҳалли ин ҷо дар робита бо NGINX Ingress тавсиф карда шудаанд. Барои ҳолатҳои дигар, ҳалли дигар вуҷуд дорад, ки мо метавонем онҳоро дар маводи зерини силсила баррасӣ кунем.

PS

Дигар аз силсилаи маслиҳатҳо ва ҳилаҳои K8s:

Манбаъ: will.com

Илова Эзоҳ