Tip & trik Kubernetes: fitur mateni anggun ing NGINX lan PHP-FPM

Kawontenan khas nalika ngleksanakake CI/CD ing Kubernetes: aplikasi kudu ora bisa nampa panjalukan klien anyar sadurunge mandheg rampung, lan sing paling penting, kasil ngrampungake sing wis ana.

Tip & trik Kubernetes: fitur mateni anggun ing NGINX lan PHP-FPM

Selaras karo kondisi iki ngidini sampeyan entuk nol downtime sajrone panyebaran. Nanging, sanajan nggunakake bundel sing populer banget (kayata NGINX lan PHP-FPM), sampeyan bisa nemoni kesulitan sing bakal nyebabake akeh kesalahan ing saben panyebaran ...

Teori. Carane pod urip

Kita wis nerbitake kanthi rinci babagan siklus urip pod artikel iki. Ing konteks topik sing dipikirake, kita kasengsem ing ngisor iki: nalika polong mlebu negara Terminating, panjalukan anyar mandheg dikirim menyang (pod dicopot saka dhaptar titik pungkasan kanggo layanan). Mangkono, kanggo ngindhari downtime sajrone panyebaran, cukup kanggo ngatasi masalah kanggo mungkasi aplikasi kanthi bener.

Sampeyan uga kudu elinga yen wektu tenggang standar yaiku 30 detik: sawise iki, pod bakal mungkasi lan aplikasi kudu duwe wektu kanggo proses kabeh panjalukan sadurunge periode iki. komentar: sanajan panyuwunan sing luwih saka 5-10 detik wis ana masalah, lan mateni sing apik ora bakal mbantu maneh ...

Kanggo luwih ngerti apa sing kedadeyan nalika pod mandheg, deleng diagram ing ngisor iki:

Tip & trik Kubernetes: fitur mateni anggun ing NGINX lan PHP-FPM

A1, B1 - Nampa owah-owahan bab negara hearth
A2 - Departure SIGTERM
B2 - Mbusak pod saka endpoints
B3 - Nampa owah-owahan (dhaptar titik pungkasan wis diganti)
B4 - Nganyari aturan iptables

Wigati dimangerteni: mbusak pod endpoint lan ngirim SIGTERM ora kedadeyan kanthi urutan, nanging bebarengan. Lan amarga kasunyatane Ingress ora langsung nampa dhaptar Endpoints sing dianyari, panjalukan anyar saka klien bakal dikirim menyang pod, sing bakal nyebabake kesalahan 500 nalika mandheg pod. (kanggo materi sing luwih rinci babagan masalah iki, kita dijarwakake). Masalah iki kudu ditanggulangi kanthi cara ing ngisor iki:

  • Kirim Sambungan: nutup header respon (yen iki gegayutan karo aplikasi HTTP).
  • Yen ora bisa ngowahi kode kasebut, banjur artikel ing ngisor iki nerangake solusi sing bakal ngidini sampeyan ngolah panjaluk nganti pungkasan periode anggun.

Teori. Kepiye NGINX lan PHP-FPM mungkasi prosese

NGINX

Ayo dadi miwiti karo NGINX, amarga kabeh iku luwih utawa kurang ketok karo. Nyilem menyang teori, kita sinau manawa NGINX duwe siji proses master lan sawetara "pekerja" - iki minangka proses bocah sing ngolah panjaluk klien. Opsi sing trep diwenehake: nggunakake printah nginx -s <SIGNAL> siksa proses salah siji ing shutdown cepet utawa mode mati anggun. Temenan, pilihan terakhir sing narik minat kita.

Banjur kabeh iku prasaja: sampeyan kudu nambah preStop-pancing printah sing bakal ngirim sinyal mati anggun. Iki bisa ditindakake ing Deployment, ing blok wadhah:

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

Saiki, nalika pod mati, kita bakal weruh ing ngisor iki ing log wadhah 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

Lan iki tegese apa sing kita butuhake: NGINX ngenteni panjaluk rampung, banjur mateni proses kasebut. Nanging, ing ngisor iki kita uga bakal nimbang masalah umum amarga, sanajan karo printah nginx -s quit proses terminates salah.

Lan ing tahap iki, kita wis rampung karo NGINX: paling ora saka log sampeyan bisa ngerti manawa kabeh bisa digunakake.

Apa hubungane karo PHP-FPM? Kepiye cara nangani shutdown sing apik? Ayo dipikirake.

PHP-FPM

Ing kasus PHP-FPM, ana informasi sing kurang. Yen sampeyan fokus ing manual resmi miturut PHP-FPM, bakal ujar manawa sinyal POSIX ing ngisor iki ditampa:

  1. SIGINT, SIGTERM - mati cepet;
  2. SIGQUIT - shutdown anggun (apa sing kita butuhake).

Sinyal sing isih ana ora dibutuhake ing tugas iki, mula kita bakal ngilangi analisa kasebut. Kanggo mungkasi proses kanthi bener, sampeyan kudu nulis pancing preStop ing ngisor iki:

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

Ing kawitan marketing, iki kabeh sing dibutuhake kanggo nindakake mati anggun ing loro kontaner. Nanging, tugas luwih angel tinimbang sing katon. Ing ngisor iki ana rong kasus nalika mateni anggun ora bisa digunakake lan nyebabake proyek ora kasedhiya kanggo jangka pendek sajrone penyebaran.

Laku. Kemungkinan masalah karo mati anggun

NGINX

Kaping pisanan, migunani kanggo ngelingi: saliyane kanggo nglakokake prentah nginx -s quit Ana siji tahap maneh sing kudu digatekake. Kita nemoni masalah nalika NGINX isih ngirim SIGTERM tinimbang sinyal SIGQUIT, nyebabake panjalukan ora rampung kanthi bener. Kasus sing padha bisa ditemokake, contone, kene. Sayange, kita ora bisa nemtokake alasan tartamtu kanggo prilaku iki: ana anggepan babagan versi NGINX, nanging ora dikonfirmasi. Gejala kasebut yaiku pesen diamati ing log wadhah NGINX "soket mbukak #10 isih ana sambungan 5", sawise polong mandheg.

Kita bisa mirsani masalah kasebut, contone, saka respon ing Ingress sing kita butuhake:

Tip & trik Kubernetes: fitur mateni anggun ing NGINX lan PHP-FPM
Indikator kode status ing wektu panyebaran

Ing kasus iki, kita mung nampa kode kesalahan 503 saka Ingress dhewe: ora bisa ngakses wadhah NGINX, amarga ora bisa diakses maneh. Yen sampeyan ndeleng log wadhah nganggo NGINX, ngemot ing ngisor iki:

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

Sawise ngganti sinyal mandeg, wadhah wiwit mandheg kanthi bener: iki dikonfirmasi kanthi kasunyatan manawa kesalahan 503 ora diamati maneh.

Yen sampeyan nemokke masalah sing padha, iku ndadekake pangertèn kanggo ngerti apa sinyal mandeg digunakake ing wadhah lan apa persis pancing preStop. Iku cukup kamungkinan sing alesan dumunung sabenere ing iki.

PHP-FPM... lan liya-liyane

Masalah karo PHP-FPM diterangake kanthi cara sing ora pati penting: ora ngenteni rampung proses anak, mula mungkasi, mula kesalahan 502 kedadeyan sajrone penyebaran lan operasi liyane. Ana sawetara laporan bug ing bugs.php.net wiwit 2005 (contone kene и kene), sing nerangake masalah iki. Nanging sampeyan ora bakal bisa ndeleng apa-apa ing log: PHP-FPM bakal ngumumake proses rampung tanpa kesalahan utawa kabar pihak katelu.

Sampeyan kudu njlentrehake manawa masalah kasebut bisa uga gumantung ing aplikasi kasebut dhewe lan bisa uga ora katon, contone, ing ngawasi. Yen sampeyan nemoni, solusi sing gampang dipikirake dhisik: tambahake pancing preStop karo sleep(30). Iki bakal ngidini sampeyan ngrampungake kabeh panjaluk sadurunge (lan kita ora nampa sing anyar, amarga pod wis saged Terminating), lan sawise 30 detik, pod dhewe bakal mungkasi karo sinyal SIGTERM.

Ternyata sing lifecycle kanggo wadhah bakal katon kaya iki:

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

Nanging, amarga 30 detik sleep kita akeh kita bakal nambah wektu penyebaran prajurit, wiwit saben pod bakal mungkasi minimal 30 detik, sing ala. Apa sing bisa ditindakake babagan iki?

Ayo dadi menyang pihak sing tanggung jawab kanggo eksekusi langsung aplikasi kasebut. Ing kasus kita iku PHP-FPM, sing kanthi gawan ora ngawasi eksekusi pangolahan anak sawijining: Proses master langsung mandheg. Sampeyan bisa ngganti prilaku iki nggunakake arahan process_control_timeout, sing nemtokake watesan wektu kanggo proses anak ngenteni sinyal saka master. Yen sampeyan nyetel nilai dadi 20 detik, iki bakal nutupi sebagian besar pitakon sing mlaku ing wadhah lan bakal mungkasi proses master yen wis rampung.

Kanthi kawruh iki, ayo bali menyang masalah pungkasan. Kaya sing wis kasebut, Kubernetes dudu platform monolitik: komunikasi antarane komponen sing beda-beda mbutuhake sawetara wektu. Iki pancen bener nalika kita nimbang operasi Ingresses lan komponen liyane sing gegandhengan, amarga amarga wektu tundha kasebut ing wektu panyebaran, gampang kena mundhak 500 kesalahan. Contone, kesalahan bisa kedadeyan ing tataran ngirim panjalukan menyang hulu, nanging "wektu lag" interaksi antarane komponen cukup cendhak - kurang saka detik.

Pramila Gunggunge karo arahan sing wis kasebut process_control_timeout sampeyan bisa nggunakake construction ing ngisor iki kanggo lifecycle:

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

Ing kasus iki, kita bakal menehi ganti rugi kanggo wektu tundha karo printah sleep lan ora nemen nambah wektu panyebaran: ana prabédan ngelingke antarane 30 detik lan siji? .. Nyatane, iku process_control_timeoutlan lifecycle digunakake mung minangka "jaring pengaman" yen ana lag.

Umumé ngandika prilaku diterangake lan workaround cocog ora mung ditrapake kanggo PHP-FPM. Kahanan sing padha bisa uga kedadeyan nalika nggunakake basa / kerangka liyane. Yen sampeyan ora bisa ndandani mati kanthi cara liyane - contone, kanthi nulis ulang kode kasebut supaya aplikasi ngolah sinyal mandap kanthi bener - sampeyan bisa nggunakake cara sing diterangake. Sampeyan bisa uga ora paling ayu, nanging bisa.

Laku. Pengujian beban kanggo mriksa operasi pod

Pengujian beban minangka salah sawijining cara kanggo mriksa cara kontaner, amarga prosedur iki nyedhaki kahanan pertempuran nyata nalika pangguna ngunjungi situs kasebut. Kanggo nyoba rekomendasi ing ndhuwur, sampeyan bisa nggunakake Yandex.Tankom: Iku nutupi kabeh kabutuhan kita sampurna. Ing ngisor iki minangka tips lan rekomendasi kanggo nganakake tes kanthi conto sing jelas saka pengalaman kita amarga grafik Grafana lan Yandex.Tank dhewe.

Sing paling penting ing kene yaiku mriksa owah-owahan langkah demi langkah. Sawise nambah fix anyar, mbukak test lan ndeleng yen asil wis diganti dibandhingake roto pungkasan. Yen ora, bakal angel kanggo ngenali solusi sing ora efektif, lan ing jangka panjang mung bisa gawe piala (contone, nambah wektu penyebaran).

Nuansa liyane yaiku kanggo ndeleng log wadhah nalika mandheg. Apa informasi babagan mateni anggun dicathet ing kono? Apa ana kesalahan ing log nalika ngakses sumber daya liyane (contone, menyang wadhah PHP-FPM tetanggan)? Kesalahan ing aplikasi kasebut dhewe (kaya ing kasus NGINX sing diterangake ing ndhuwur)? Muga-muga informasi pambuka saka artikel iki bakal mbantu sampeyan luwih ngerti apa sing kedadeyan ing wadhah kasebut sajrone mungkasi.

Dadi, test run pisanan ditindakake tanpa lifecycle lan tanpa arahan tambahan kanggo server aplikasi (process_control_timeout ing PHP-FPM). Tujuan saka tes iki yaiku kanggo ngenali kira-kira jumlah kesalahan (lan apa ana). Uga, saka informasi tambahan, sampeyan kudu ngerti manawa wektu panyebaran rata-rata kanggo saben pod kira-kira 5-10 detik nganti siap. Hasile yaiku:

Tip & trik Kubernetes: fitur mateni anggun ing NGINX lan PHP-FPM

Panel informasi Yandex.Tank nuduhake lonjakan 502 kesalahan, sing kedadeyan nalika panyebaran lan tahan rata-rata nganti 5 detik. Dianggep iki amarga panjaluk sing wis ana kanggo pod lawas dihentikan nalika dihentikan. Sawise iki, 503 kesalahan muncul, sing minangka asil saka wadhah NGINX sing mandheg, sing uga ngeculake sambungan amarga backend (sing ngalangi Ingress ora nyambung).

Ayo ndeleng carane process_control_timeout ing PHP-FPM bakal bantuan kita ngenteni completion proses anak, i.e. mbenerake kesalahan kasebut. Pasang maneh nggunakake arahan iki:

Tip & trik Kubernetes: fitur mateni anggun ing NGINX lan PHP-FPM

Ora ana kesalahan maneh sajrone panyebaran kaping 500! Penyebaran kasebut sukses, mateni kanthi apik.

Nanging, iku worth ngelingi Jeksa Agung bisa ngetokake karo wadhah Ingress, persentasi cilik saka kasalahan sing bisa ditampa amarga wektu tundha. Kanggo supaya wong-wong mau, kabeh sing isih kanggo nambah struktur karo sleep lan mbaleni penyebaran. Nanging, ing kasus tartamtu, ora ana owah-owahan sing katon (maneh, ora ana kesalahan).

kesimpulan

Kanggo mungkasi proses kanthi apik, kita ngarepake prilaku ing ngisor iki saka aplikasi:

  1. Enteni sawetara detik banjur mandheg nampa sambungan anyar.
  2. Enteni kabeh panjalukan rampung lan nutup kabeh sambungan keepalive sing ora nglakokake panjalukan.
  3. Mungkasi proses sampeyan.

Nanging, ora kabeh aplikasi bisa mlaku kanthi cara iki. Salah sawijining solusi kanggo masalah ing kasunyatan Kubernetes yaiku:

  • nambahake pancing sing wis mandheg sing bakal ngenteni sawetara detik;
  • sinau file konfigurasi backend kita kanggo paramèter sing cocog.

Conto karo NGINX nerangake manawa aplikasi sing wiwitane kudu ngolah sinyal mandap kanthi bener bisa uga ora nindakake, mula penting kanggo mriksa kesalahan 500 sajrone panyebaran aplikasi. Iki uga ngidini sampeyan ndeleng masalah kanthi luwih wiyar lan ora fokus ing polong utawa wadhah siji, nanging ndeleng kabeh infrastruktur kanthi wutuh.

Minangka alat testing, sampeyan bisa nggunakake Yandex.Tank magepokan karo sembarang sistem ngawasi (ing kasus kita, data dijupuk saka Grafana karo backend Prometheus kanggo test). Masalah karo mati anggun katon cetha ing beban abot sing pathokan bisa generate, lan ngawasi mbantu kanggo njelasno kahanan ing liyane rinci sak utawa sawise test.

Nanggepi umpan balik babagan artikel kasebut: kudu dicathet yen masalah lan solusi diterangake ing kene babagan NGINX Ingress. Kanggo kasus liyane, ana solusi liyane, sing bisa ditimbang ing materi seri ing ngisor iki.

PS

Liyane saka seri tips & trik K8s:

Source: www.habr.com

Add a comment