Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

Ngayon plano kong pag-usapan kung paano magsulat ng mga aplikasyon at kung ano ang mga kinakailangan para gumana nang maayos ang iyong aplikasyon sa Kubernetes. Upang walang sakit sa ulo sa application, nang sa gayon ay hindi mo na kailangang mag-imbento at bumuo ng anumang "mga bitak" sa paligid nito - at lahat ay gumagana sa paraang nilayon mismo ng Kubernetes.

Ang lecture na ito ay bahagi ng "Slurm Night School sa Kubernetes" Maaari mong tingnan ang bukas na teoretikal na mga lektura ng Evening School sa Youtube, nakapangkat sa isang playlist. Para sa mga mas gusto ang teksto kaysa sa video, inihanda namin ang artikulong ito.

Ang pangalan ko ay Pavel Selivanov, sa kasalukuyan ako ang nangungunang DevOps engineer sa Mail.ru Cloud Solutions, gumagawa kami ng mga ulap, gumagawa kami ng management kubernetes at iba pa. Kasama na ngayon sa aking mga gawain ang tulong sa pagpapaunlad, paglulunsad ng mga ulap na ito, paglulunsad ng mga application na isinusulat namin at direktang pagbuo ng mga tool na ibinibigay namin para sa aming mga user.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

Gumagawa ako ng DevOps, sa tingin ko sa huling, marahil, tatlong taon. Ngunit, sa prinsipyo, ginagawa ko ang ginagawa ng DevOps sa loob ng halos limang taon na ngayon. Bago iyon, karamihan ay nasasangkot ako sa mga bagay na pang-admin. Nagsimula akong magtrabaho kasama ang Kubernetes matagal na ang nakalipas - marahil mga apat na taon na ang nakalipas mula noong nagsimula akong magtrabaho dito.

Sa pangkalahatan, nagsimula ako noong bersyon 1.3 ang Kubernetes, marahil, at maaaring 1.2 - noong ito ay nasa simula pa lamang. Ngayon ay wala na ito sa kanyang kamusmusan - at halatang may malaking pangangailangan sa merkado para sa mga inhinyero na gustong makapag Kubernetes. At ang mga kumpanya ay may napakataas na pangangailangan para sa gayong mga tao. Samakatuwid, sa katunayan, lumitaw ang panayam na ito.

Kung magsasalita tayo ayon sa plano ng pag-uusapan ko, parang ganito, sa brackets ang nakasulat (TL;DR) - β€œtoo long; wag mong basahin". Ang aking presentasyon ngayon ay bubuo ng walang katapusang mga listahan.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

Sa katunayan, ako mismo ay hindi gusto ang gayong mga pagtatanghal kapag ginawa ang mga ito, ngunit ito ay isang paksa na noong inihahanda ko ang pagtatanghal na ito, hindi ko talaga naisip kung paano ayusin ang impormasyong ito sa ibang paraan.

Dahil, sa pangkalahatan, ang impormasyong ito ay "ctrl+c, ctrl+v", mula sa, bukod sa iba pang mga bagay, sa aming Wiki sa seksyong DevOps, kung saan mayroon kaming nakasulat na mga kinakailangan para sa mga developer: "guys, para ilunsad namin ang iyong application sa Kubernetes, dapat ganito."

Iyon ang dahilan kung bakit ang pagtatanghal ay naging napakalaking listahan. Paumanhin. I will try to tell as much as possible para hindi boring kung pwede.

Ano ang titingnan natin ngayon:

  • ito ay, una, mga log (mga log ng aplikasyon?), kung ano ang gagawin sa mga ito sa Kubernetes, kung ano ang gagawin sa mga ito, kung ano ang dapat na mga ito;
  • kung ano ang gagawin sa mga configuration sa Kubernetes, ano ang mga pinakamahusay at pinakamasamang paraan upang i-configure ang isang application para sa Kubernetes;
  • Pag-usapan natin kung ano ang mga pagsusuri sa pagiging naa-access sa pangkalahatan, kung ano ang dapat na hitsura ng mga ito;
  • pag-usapan natin kung ano ang magandang pagsasara;
  • pag-usapan natin muli ang tungkol sa mga mapagkukunan;
  • Ating hawakan muli ang paksa ng data storage;
  • at sa huli ay sasabihin ko sa iyo kung ano ang katagang ito ng mahiwagang cloud-native na application. Cloudnativeness, bilang isang adjective ng terminong ito.

Mga log

Iminumungkahi kong magsimula sa mga log - kung saan kailangang i-shoved ang mga log na ito sa Kubernetes. Ngayon ay naglunsad ka ng isang application sa Kubernetes. Ayon sa mga klasiko, ang mga dating application ay palaging nagsulat ng mga log sa isang lugar sa isang file. Ang mga masamang application ay nagsulat ng mga log sa isang file sa home directory ng developer na naglunsad ng application. Ang magagandang application ay nagsulat ng mga log sa isang file sa isang lugar /var/log.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

Alinsunod dito, higit pa, ang mabubuting administrador ay may ilang bagay na na-configure sa kanilang mga imprastraktura na maaaring paikutin ng mga log na ito - ang parehong rsyslog, na tumitingin sa mga log na ito at kapag may nangyari sa kanila, marami sa kanila, lumilikha ito ng mga backup na kopya , naglalagay ng mga log doon , tinatanggal ang mga lumang file, higit sa isang linggo, anim na buwan at ilan pa. Sa teorya, dapat tayong magkaroon ng mga probisyon upang dahil lamang sa nagsusulat ng mga log ang application, ang espasyo sa mga server ng produksyon (mga server ng labanan?) ay hindi maubusan. At, nang naaayon, ang buong produksyon ay hindi huminto dahil sa mga log.

Kapag lumipat tayo sa mundo ng Kubernetes at nagpatakbo ng parehong bagay doon, ang unang bagay na maaari mong bigyang pansin ay ang katotohanan na ang mga tao, habang nagsusulat sila ng mga log sa isang file, ay patuloy na nagsusulat sa kanila.

Lumalabas na kung pag-uusapan natin ang tungkol sa Kubernetes, ang tamang lugar upang magsulat ng mga log sa isang lugar mula sa isang docker container ay isulat lamang ang mga ito mula sa application hanggang sa tinatawag na Stdout/Stderr, iyon ay, ang karaniwang mga stream ng output ng operating system, ang karaniwang output ng error. Ito ang pinakatama, pinakasimple at pinakalohikal na paraan upang ilagay ang mga log sa prinsipyo sa Docker at partikular sa Kubernetis. Dahil kung ang iyong application ay nagsusulat ng mga log sa Stdout/Stderr, nasa Docker at ang Kubernetes add-on na magpasya kung ano ang gagawin sa mga log na ito. Ang Docker ay sa pamamagitan ng default na bumuo ng mga espesyal na file nito sa JSON na format.

Dito lumalabas ang tanong, ano ang susunod mong gagawin sa mga log na ito? Ang pinakamadaling paraan ay malinaw, mayroon tayong kakayahang gawin kubectl logs at tingnan ang mga log na ito ng mga "pod" na ito. Ngunit, marahil, ito ay hindi isang napakahusay na pagpipilian - ibang bagay ang kailangang gawin sa mga log.

Sa ngayon, pag-usapan natin ang parehong oras, dahil hinawakan natin ang paksa ng mga log, tungkol sa isang bagay na dapat magmukhang mga log. Ibig sabihin, hindi ito direktang nalalapat sa Kubernetes, ngunit kapag sinimulan nating isipin kung ano ang gagawin sa mga log, makabubuting pag-isipan din ito.

Kailangan namin ng ilang uri ng tool, sa isang mapayapang paraan, na kukuha ng mga log na ito na inilalagay ng aming docker sa mga file nito at ipapadala ang mga ito sa kung saan. Sa pangkalahatan, karaniwang naglulunsad kami ng ilang uri ng ahente sa loob ng Kubernetes sa anyo ng isang DaemonSet - isang kolektor ng log, na sinasabi lang kung saan matatagpuan ang mga log na kinokolekta ng Docker. At ang collecting agent na ito ay dinadala lang sila, marahil kahit papaano ay na-parse ang mga ito sa daan, marahil ay nagpapayaman sa kanila ng ilang karagdagang meta-impormasyon at, sa huli, ipinapadala ang mga ito para sa imbakan sa isang lugar. Posible na ang mga pagkakaiba-iba doon. Ang pinakakaraniwan ay marahil ang Elasticsearch, kung saan maaari kang mag-imbak ng mga log at maginhawa mong makuha ang mga ito mula doon. Pagkatapos, gamit ang isang kahilingan, gamit ang Kibana, halimbawa, bumuo ng mga graph batay sa mga ito, bumuo ng mga alerto batay sa mga ito, at iba pa.

Ang pinakamahalagang ideya, gusto kong ulitin ito, ay sa loob ng Docker, partikular sa loob ng Kubernetes, ang pag-iimbak ng iyong mga log sa isang file ay isang napakasamang ideya.

Dahil una, mahirap makuha ang mga log sa loob ng container sa isang file. Kailangan mo munang pumunta sa lalagyan, exec doon, at pagkatapos ay tingnan ang mga log. Ang susunod na punto ay kung mayroon kang mga log sa isang file, kung gayon ang mga lalagyan ay karaniwang may minimalist na kapaligiran at walang mga kagamitan na karaniwang kinakailangan para sa normal na trabaho na may mga log. Ilibing sila, tingnan, buksan sa isang text editor. Ang susunod na sandali ay kapag mayroon kaming mga log sa isang file sa loob ng isang lalagyan, kung ang lalagyan na ito ay tinanggal, naiintindihan mo, ang mga log ay mamamatay kasama nito. Alinsunod dito, ang anumang pag-restart ng container ay nangangahulugan na wala nang mga log. Muli, masamang opsyon.

At ang huling punto ay na sa loob ng mga lalagyan ay karaniwang mayroon ka ng iyong aplikasyon at iyon lang - kadalasan ito ang tanging proseso na tumatakbo. Walang pinag-uusapan tungkol sa anumang proseso na magpapaikot ng mga file gamit ang iyong mga log. Sa sandaling magsimulang isulat ang mga log sa isang file, nangangahulugan ito na, ipagpaumanhin mo, magsisimula kaming mawala ang server ng produksyon. Dahil, una, mahirap silang hanapin, walang sumusubaybay sa kanila, at walang kumokontrol sa kanila - nang naaayon, ang file ay lumalaki nang walang hanggan hanggang sa maubusan na lamang ang espasyo sa server. Samakatuwid, muli kong sinasabi na ang pag-log in sa Docker, partikular sa Kubernetes, sa isang file ay isang masamang ideya.

Ang susunod na punto, narito, nais kong pag-usapan muli ang tungkol dito - dahil tinatalakay natin ang paksa ng mga log, makabubuting pag-usapan kung ano ang hitsura ng mga log upang maging maginhawa upang gumana sa kanila. Gaya ng sinabi ko, ang paksa ay hindi direktang nauugnay sa Kubernetes, ngunit ito ay napakahusay na nauugnay sa paksa ng DevOps. Sa paksa ng kultura ng pag-unlad at pagkakaibigan sa pagitan ng dalawang magkaibang departamentong ito - Dev at Ops, upang maging komportable ang lahat.

Nangangahulugan ito na ang perpektong, ngayon, ang mga log ay dapat na nakasulat sa JSON na format. Kung mayroon kang ilang hindi maintindihan na aplikasyon ng iyong sarili, na nagsusulat ng mga log sa hindi maintindihan na mga format dahil nagpasok ka ng ilang uri ng pag-print o isang bagay na tulad nito, pagkatapos ay oras na upang google ang ilang uri ng balangkas, isang uri ng wrapper na nagbibigay-daan sa iyo upang ipatupad ang normal na pag-log; paganahin ang mga parameter ng pag-log sa JSON doon, dahil ang JSON ay isang simpleng format, ang pag-parse nito ay simple.

Kung ang iyong JSON ay hindi gumagana ayon sa ilang pamantayan, walang nakakaalam kung ano, pagkatapos ay magsulat man lang ng mga log sa isang format na maaaring ma-parse. Dito, sa halip, ito ay nagkakahalaga ng pag-iisip tungkol sa katotohanan na, halimbawa, kung nagpapatakbo ka ng isang bungkos ng mga lalagyan o mga proseso lamang na may nginx, at bawat isa ay may sariling mga setting ng pag-log, kung gayon malamang na ito ay magiging lubhang abala para sa iyo na i-parse ang mga ito. Dahil para sa bawat bagong halimbawa ng nginx kailangan mong isulat ang iyong sariling parser, dahil iba ang pagsusulat nila ng mga log. Muli, ito ay malamang na nagkakahalaga ng pag-iisip tungkol sa pagtiyak na ang lahat ng mga nginx instance na ito ay may parehong pagsasaayos ng pag-log at isinulat ang lahat ng kanilang mga log nang pantay-pantay. Ang parehong naaangkop sa ganap na lahat ng mga application.

Sa huli, gusto ko ring magdagdag ng gasolina sa apoy na, sa isip, dapat na iwasan ang mga multi-line na format na log. Narito ang bagay, kung nagtrabaho ka na sa mga kolektor ng log, malamang na nakita mo ang ipinangako nila sa iyo, na maaari silang gumana sa mga multi-line na log, alam kung paano kolektahin ang mga ito, at iba pa. Sa katunayan, sa palagay ko, walang isang kolektor ngayon ang maaaring mangolekta ng mga multi-line na log nang normal, ganap at walang mga error. Sa paraang pantao, upang ito ay maginhawa at walang pagkakamali.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

Ngunit ang stack trace ay palaging mga multi-line na log at kung paano maiiwasan ang mga ito. Ang tanong dito ay ang isang log ay isang talaan ng isang kaganapan, at ang stactrace ay hindi talaga isang log. Kung mangolekta kami ng mga log at ilalagay ang mga ito sa isang lugar sa Elasticsearch at pagkatapos ay gumuhit ng mga graph mula sa mga ito, bumuo ng ilang ulat ng aktibidad ng user sa iyong site, pagkatapos ay kapag nakakuha ka ng stack trace, nangangahulugan ito na may nangyayaring hindi inaasahan. isang hindi mahawakang sitwasyon sa iyong aplikasyon. At makatuwirang awtomatikong mag-upload ng stack trace sa isang lugar sa isang system na maaaring sumubaybay sa kanila.

Ito ay software (ang parehong Sentry) na partikular na ginawa upang gumana sa stack trace. Maaari itong agad na lumikha ng mga awtomatikong gawain, italaga ang mga ito sa isang tao, alerto kapag naganap ang mga stacttrace, pagpangkatin ang mga stacttrace na ito ayon sa isang uri, at iba pa. Sa prinsipyo, hindi gaanong makatuwiran na pag-usapan ang tungkol sa mga stactraces kapag pinag-uusapan natin ang tungkol sa mga log, dahil ito ay, pagkatapos ng lahat, iba't ibang mga bagay na may iba't ibang layunin.

Configuration

Susunod na pag-uusapan natin ang tungkol sa configuration sa Kubernetes: kung ano ang gagawin dito at kung paano dapat i-configure ang mga application sa loob ng Kubernetes. Sa pangkalahatan, karaniwan kong sinasabi na ang Docker ay hindi tungkol sa mga lalagyan. Alam ng lahat na ang Docker ay tungkol sa mga lalagyan, kahit na ang mga hindi gaanong nagtrabaho sa Docker. Inuulit ko, ang Docker ay hindi tungkol sa mga lalagyan.

Ang Docker, sa palagay ko, ay tungkol sa mga pamantayan. At may mga pamantayan para sa halos lahat: mga pamantayan para sa pagbuo ng iyong aplikasyon, mga pamantayan para sa pag-install ng iyong aplikasyon.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

At ang bagay na ito - ginamit namin ito noon, naging tanyag ito lalo na sa pagdating ng mga lalagyan - ang bagay na ito ay tinatawag na mga variable ng ENV (environment), iyon ay, mga variable ng kapaligiran na nasa iyong operating system. Ito sa pangkalahatan ay isang mainam na paraan upang i-configure ang iyong aplikasyon, dahil kung mayroon kang mga aplikasyon sa JAVA, Python, Go, Perl, ipinagbabawal ng Diyos, at mababasa nilang lahat ang host ng database, gumagamit ng database, mga variable ng password ng database, kung gayon ito ay perpekto. Mayroon kang mga application sa apat na magkakaibang wika na naka-configure sa database plan sa parehong paraan. Wala nang iba't ibang mga config.

Lahat ay maaaring i-configure gamit ang mga variable ng ENV. Kapag pinag-uusapan natin ang tungkol sa Kubernetes, mayroong isang mahusay na paraan upang magdeklara ng mga variable ng ENV sa loob mismo ng Deployment. Alinsunod dito, kung pinag-uusapan natin ang tungkol sa lihim na data, pagkatapos ay maaari nating agad na itulak ang lihim na data mula sa mga variable ng ENV (mga password sa mga database, atbp.) sa isang lihim, lumikha ng isang lihim na kumpol at ipahiwatig sa paglalarawan ng ENV sa Deployment na hindi namin direktang idineklara ang halaga ng variable na ito, at ang halaga ng variable ng password ng database na ito ay mababasa mula sa lihim. Ito ay karaniwang pag-uugali ng Kubernetes. At ito ang pinakaperpektong opsyon para i-configure ang iyong mga application. Sa antas pa lang ng code, muli itong nalalapat sa mga developer. Kung ikaw ay DevOps, maaari kang magtanong: β€œGuys, mangyaring turuan ang iyong application na basahin ang mga variable ng kapaligiran. At magiging masaya tayong lahat."

Kung ang lahat sa kumpanya ay nagbabasa ng parehong pinangalanang mga variable ng kapaligiran, kung gayon iyon ay mahusay. Upang hindi mangyari na ang ilan ay naghihintay para sa database ng postgres, ang iba ay naghihintay para sa pangalan ng database, ang iba ay naghihintay para sa iba pa, ang iba ay naghihintay ng isang dbn ng ilang uri, upang, nang naaayon, mayroong pagkakapareho.

Dumarating ang problema kapag mayroon kang napakaraming mga variable ng kapaligiran na binuksan mo lang ang Deployment - at mayroong limang daang linya ng mga variable ng kapaligiran. Sa kasong ito, mayroon ka na lamang na mga pagbabago sa kapaligiran - at hindi mo na kailangang pahirapan ang iyong sarili. Sa kasong ito, makatuwiran na simulan ang paggamit ng mga config. Ibig sabihin, sanayin ang iyong application na gumamit ng mga config.

Ang tanging tanong ay ang mga config ay hindi kung ano ang iniisip mo. Ang Config.pi ay hindi isang config na madaling gamitin. Or some config in your own format, alternatively gifted - hindi rin ito ang config na ibig kong sabihin.

Ang tinutukoy ko ay pagsasaayos sa mga katanggap-tanggap na format, ibig sabihin, sa ngayon ang pinakasikat na pamantayan ay ang pamantayang .yaml. Ito ay malinaw kung paano basahin ito, ito ay nababasa ng tao, ito ay malinaw kung paano basahin ito mula sa application.

Alinsunod dito, bilang karagdagan sa YAML, maaari mo ring, halimbawa, gumamit ng JSON, ang pag-parse ay halos kasing ginhawa ng YAML sa mga tuntunin ng pagbabasa ng configuration ng application mula doon. Ito ay kapansin-pansing mas abala para sa mga tao na basahin. Maaari mong subukan ang format, a la ini. Medyo maginhawang basahin, mula sa pananaw ng tao, ngunit maaaring hindi maginhawang iproseso ito nang awtomatiko, sa diwa na kung gusto mong bumuo ng sarili mong mga config, ang format na ini ay maaaring hindi maginhawang buuin.

Ngunit sa anumang kaso, anuman ang format na pipiliin mo, ang punto ay na mula sa isang Kubernetes punto ng view ito ay napaka-maginhawa. Maaari mong ilagay ang iyong buong config sa loob ng Kubernetes, sa ConfigMap. At pagkatapos ay kunin ang configmap na ito at hilingin itong mai-mount sa loob ng iyong pod sa ilang partikular na direktoryo, kung saan babasahin ng iyong aplikasyon ang pagsasaayos mula sa configmap na ito na parang ito ay isang file lamang. Ito, sa katunayan, ay kung ano ang magandang gawin kapag mayroon kang maraming mga pagpipilian sa pagsasaayos sa iyong aplikasyon. O ito ay isang uri lamang ng kumplikadong istraktura, mayroong pugad.

Kung mayroon kang configmap, maaari mong ituro nang mahusay ang iyong aplikasyon, halimbawa, na awtomatikong subaybayan ang mga pagbabago sa file kung saan naka-mount ang configmap, at awtomatiko ring i-reload ang iyong aplikasyon kapag nagbago ang mga config. Ito ay karaniwang isang perpektong opsyon.

Muli, napag-usapan ko na ito - ang lihim na impormasyon ay wala sa configmap, ang lihim na impormasyon ay wala sa mga variable, ang lihim na impormasyon ay wala sa mga lihim. Mula doon, ikonekta ang lihim na impormasyong ito sa diplomasya. Kadalasan, iniimbak namin ang lahat ng paglalarawan ng mga bagay, deployment, configmap, serbisyo ng Kubernetes sa git. Alinsunod dito, ang paglalagay ng password sa database sa git, kahit na ito ang iyong git, na mayroon ka sa loob ng kumpanya, ay isang masamang ideya. Dahil, sa pinakamababa, naaalala ng git ang lahat at ang simpleng pag-alis ng mga password mula doon ay hindi ganoon kadali.

Pagsusuri sa kalusugan

Ang susunod na punto ay ang bagay na ito na tinatawag na Health check. Sa pangkalahatan, ang pagsusuri sa Kalusugan ay pagsuri lamang kung gumagana ang iyong aplikasyon. Kasabay nito, madalas nating pinag-uusapan ang ilang mga web application, kung saan, nang naaayon, mula sa punto ng view ng pagsusuri sa kalusugan (mas mahusay na huwag isalin dito at higit pa) ito ay magiging ilang espesyal na URL, na pinoproseso nila bilang isang pamantayan, karaniwan nilang ginagawa /health.

Kapag ina-access ang URL na ito, ayon dito, sinasabi ng aming application ang alinman sa "oo, okay, ayos lang ang lahat sa akin, 200" o "hindi, lahat ay hindi maayos sa akin, mga 500." Alinsunod dito, kung ang aming aplikasyon ay hindi http, hindi isang web application, pinag-uusapan natin ngayon ang tungkol sa ilang uri ng daemon, maaari nating malaman kung paano gumawa ng mga pagsusuri sa kalusugan. Iyon ay, hindi kinakailangan, kung ang application ay hindi http, kung gayon ang lahat ay gumagana nang walang pagsusuri sa kalusugan at hindi ito magagawa sa anumang paraan. Maaari mong pana-panahong i-update ang ilang impormasyon sa file, maaari kang makabuo ng ilang espesyal na utos para sa iyong daemon, tulad ng, daemon status, na magsasabing "oo, maayos ang lahat, gumagana ang daemon, buhay ito."

Para saan ito? Ang una at pinaka-halatang bagay ay marahil kung bakit kailangan ang isang pagsusuri sa kalusugan - upang maunawaan na gumagana ang application. I mean, katangahan lang, kapag nakataas ngayon, parang gumagana, para makasigurado kang gumagana. At lumalabas na tumatakbo ang application, tumatakbo ang lalagyan, gumagana ang instance, maayos ang lahat - at pagkatapos ay pinutol na ng mga user ang lahat ng numero ng telepono mula sa teknikal na suporta at sinabing "ano ka..., ikaw nakatulog, walang gumagana."

Ang pagsusuri sa kalusugan ay isang paraan lamang upang makita mula sa pananaw ng user kung gumagana ito. Isa sa mga pamamaraan. Ilagay natin ito sa ganitong paraan. Mula sa pananaw ng Kubernetes, isa rin itong paraan upang maunawaan kung kailan nagsimula ang application, dahil naiintindihan namin na may pagkakaiba sa pagitan ng kung kailan inilunsad, ginawa at nagsimula ang container, at kung kailan direktang inilunsad ang application sa container na ito. Dahil kung kukuha tayo ng ilang karaniwang java application at susubukan itong ilunsad sa pantalan, pagkatapos ay sa loob ng apatnapung segundo, o kahit isang minuto, o kahit sampu, maaari itong magsimula nang maayos. Sa kasong ito, maaari kang kumatok sa mga port nito, hindi ito sasagot doon, iyon ay, hindi pa ito handang tumanggap ng trapiko.

Muli, sa tulong ng isang pagsusuri sa kalusugan at sa tulong ng katotohanan na tayo ay lumiliko dito, maaari nating maunawaan sa Kubernetes na hindi lamang ang lalagyan ay tumaas sa aplikasyon, ngunit ang aplikasyon mismo ay nagsimula, ito ay tumutugon na sa health check, ibig sabihin pwede tayong magpadala ng traffic doon.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

Ang tinutukoy ko ngayon ay tinatawag na Readiness/Liveness tests sa loob ng Kubernetes; nang naaayon, ang aming mga pagsubok sa kahandaan ay responsable para sa pagkakaroon ng application sa pagbabalanse. Iyon ay, kung ang mga pagsubok sa kahandaan ay isinasagawa sa aplikasyon, kung gayon ang lahat ay ok, ang trapiko ng kliyente ay pupunta sa aplikasyon. Kung ang mga pagsusulit sa kahandaan ay hindi ginanap, kung gayon ang aplikasyon ay hindi nakikilahok, ang partikular na pagkakataong ito ay hindi nakikilahok sa pagbabalanse, ito ay tinanggal mula sa pagbabalanse, ang trapiko ng kliyente ay hindi dumadaloy. Alinsunod dito, ang mga pagsubok sa Liveness sa loob ng Kubernetes ay kailangan upang kung ang application ay natigil, maaari itong i-restart. Kung hindi gumana ang liveness test para sa isang application na idineklara sa Kubernetes, hindi lang aalisin ang application sa pagbabalanse, ito ay magre-restart.

At narito ang isang mahalagang punto na nais kong banggitin: mula sa praktikal na pananaw, ang pagsusulit sa kahandaan ay kadalasang ginagamit nang mas madalas at mas madalas na kailangan kaysa sa pagsubok sa kabuhayan. Ibig sabihin, ang walang pag-iisip na pagdedeklara ng parehong mga pagsubok sa kahandaan at kasiglahan, dahil magagawa iyon ng Kubernetes, at gamitin natin ang lahat ng magagawa nito, ay hindi isang napakagandang ideya. Ipapaliwanag ko kung bakit. Dahil ang point number two sa pagsusuri ay isang magandang ideya na suriin ang pinagbabatayan na serbisyo sa iyong mga pagsusuri sa kalusugan. Nangangahulugan ito na kung mayroon kang isang web application na nagbibigay ng ilang impormasyon, na kung saan, natural, dapat kumuha mula sa isang lugar. Sa isang database, halimbawa. Well, sine-save nito ang impormasyong dumarating sa REST API na ito sa parehong database. Pagkatapos, nang naaayon, kung ang iyong healthcheck ay tumugon lamang tulad ng nakontak na slashhealth, ang application ay nagsasabing "200, okay, lahat ay maayos," at sa parehong oras ang database ng iyong aplikasyon ay hindi naa-access, at ang healthcheck application ay nagsasabing "200, okay, lahat ay maayos. ” - Ito ay isang masamang pagsusuri sa kalusugan. Hindi ito dapat gumana.

Iyon ay, ang iyong aplikasyon, kapag ang isang kahilingan ay dumating dito /health, hindi lang ito tumutugon, "200, ok", ito ay unang pumunta, halimbawa, sa database, sinusubukang kumonekta dito, gumagawa ng isang bagay na napaka-basic doon, tulad ng pumili ng isa, tingnan lamang kung mayroong koneksyon sa database at maaari mong i-query ang database. Kung ang lahat ng ito ay matagumpay, ang sagot ay "200, ok." Kung ito ay hindi matagumpay, ito ay nagsasabi na mayroong isang error, ang database ay hindi magagamit.

Samakatuwid, sa bagay na ito, muli akong bumalik sa mga pagsusulit sa Readiness/Liveness - kung bakit malamang na kailangan mo ng isang pagsubok sa pagiging handa, ngunit isang liveness test ang pinag-uusapan. Dahil kung ilalarawan mo ang mga pagsusuri sa kalusugan nang eksakto tulad ng sinabi ko, lalabas na hindi ito magagamit sa bahagi ng halimbawa.Π² ΠΈΠ»ΠΈ со всСх instancesa isang database, halimbawa. Kapag nagdeklara ka ng isang pagsubok sa kahandaan, nagsimulang mabigo ang aming mga pagsusuri sa kalusugan, at naaayon sa lahat ng mga application kung saan hindi naa-access ang database, ang mga ito ay pinapatay lang mula sa pagbabalanse at sa katunayan ay "nag-hang" sa isang napapabayaang estado at naghihintay para sa kanilang mga database trabaho.

Kung nagdeklara kami ng liveness test, isipin mo, nasira ang aming database, at sa iyong Kubernetes kalahati ng lahat ay magsisimulang mag-restart dahil nabigo ang liveness test. Nangangahulugan ito na kailangan mong i-restart. Hindi ito ang gusto mo, mayroon pa akong personal na karanasan sa pagsasanay. Nagkaroon kami ng chat application na nakasulat sa JS at ipinasok sa isang database ng Mongo. At ang problema ay sa simula ng aking trabaho sa Kubernetes, inilarawan namin ang kahandaan, kasiglahan ng mga pagsubok sa prinsipyo na magagawa ito ng Kubernetes, kaya gagamitin namin ito. Alinsunod dito, sa ilang mga punto ang Mongo ay naging medyo "mapurol" at ang sample ay nagsimulang mabigo. Alinsunod dito, ayon sa pagsubok sa pag-ulan, nagsimulang "pumapatay" ang mga pod.

Tulad ng naiintindihan mo, kapag sila ay "pinatay", ito ay isang chat, iyon ay, mayroong maraming mga koneksyon mula sa mga kliyente na nakabitin dito. "Pinapatay" din sila - hindi, hindi mga kliyente, mga koneksyon lamang - hindi lahat nang sabay-sabay, at dahil sa katotohanan na hindi sila pinapatay nang sabay-sabay, ang ilan ay mas maaga, ang ilan mamaya, hindi sila nagsisimula sa parehong oras. oras. Dagdag pa sa karaniwang random, hindi namin mahulaan nang may millisecond na katumpakan ang oras ng pagsisimula ng application sa bawat oras, kaya ginagawa nila ito nang paisa-isa. Ang isang infospot ay tumataas, idinagdag sa pagbabalanse, lahat ng mga kliyente ay pumupunta doon, hindi ito makatiis ng ganoong pagkarga, dahil ito ay nag-iisa, at, halos nagsasalita, mayroong isang dosena sa kanila na nagtatrabaho doon, at ito ay bumagsak. Ang susunod na tumaas, ang buong kargada ay nasa kanya, siya rin ay nahuhulog. Buweno, ang mga talon na ito ay patuloy na umaagos. Sa huli, kung paano ito nalutas - kailangan lang naming mahigpit na ihinto ang trapiko ng user sa application na ito, hayaang tumaas ang lahat ng pagkakataon at pagkatapos ay simulan ang lahat ng trapiko ng user nang sabay-sabay upang maibahagi na ito sa lahat ng sampung pagkakataon.

Kung hindi dahil sa inihayag na liveness test na ito, na pipiliting mag-restart ang lahat, mahawakan sana ito ng application nang maayos. Ngunit ang lahat mula sa pagbabalanse ay hindi pinagana para sa amin, dahil ang mga database ay hindi naa-access at lahat ng mga gumagamit ay "nahulog". Pagkatapos, kapag naging available ang database na ito, ang lahat ay kasama sa pagbabalanse, ngunit hindi na kailangang magsimulang muli ang mga application, at hindi na kailangang mag-aksaya ng oras at mga mapagkukunan para dito. Nandito na silang lahat, handa na sila para sa trapiko, kaya ang trapiko ay nagbubukas, lahat ay maayos - ang aplikasyon ay nasa lugar, ang lahat ay patuloy na gumagana.

Samakatuwid, ang mga pagsusuri sa kahandaan at kasiglahan ay iba, higit pa rito, maaari kang gumawa ng iba't ibang pagsusuri sa kalusugan, isang uri ng radii, isang uri ng liv, halimbawa, at suriin ang iba't ibang mga bagay. Sa panahon ng mga pagsubok sa kahandaan, suriin ang iyong mga backend. At sa isang liveness test, halimbawa, hindi mo tinitingnan mula sa punto ng view na ang liveness test sa pangkalahatan ay isang application na tumutugon lamang, kung ito ay nakakatugon sa lahat.

Dahil ang liveness test, sa pangkalahatan, ay kapag tayo ay "natigil." Nagsimula ang isang walang katapusang loop o iba pa - at wala nang mga kahilingan ang naproseso. Samakatuwid, makatuwiran na paghiwalayin ang mga ito - at ipatupad ang iba't ibang lohika sa kanila.

Tungkol sa kung ano ang kailangan mong sagutin kapag mayroon kang pagsusulit, kapag gumawa ka ng mga pagsusuri sa kalusugan. Ang sakit lang talaga. Ang mga pamilyar dito ay malamang na matatawa - ngunit seryoso, nakakita ako ng mga serbisyo sa aking buhay na sumasagot ng "200" sa XNUMX% ng mga kaso. Ibig sabihin, sino ang matagumpay. Ngunit sa parehong oras sa katawan ng tugon ay isinulat nila ang "ganyan at ganoong pagkakamali."

Iyon ay, ang katayuan ng tugon ay dumating sa iyo - lahat ay matagumpay. Ngunit sa parehong oras, dapat mong i-parse ang katawan, dahil ang katawan ay nagsasabing "paumanhin, natapos ang kahilingan sa isang error" at ito ay katotohanan lamang. Nakita ko ito sa totoong buhay.

At upang ang ilang mga tao ay hindi ito nakakatawa, at ang iba ay napakasakit, ito ay nagkakahalaga pa rin na sumunod sa isang simpleng panuntunan. Sa mga pagsusuri sa kalusugan, at sa prinsipyo kapag nagtatrabaho sa mga web application.

Kung naging maayos ang lahat, pagkatapos ay tumugon sa ikadalawang daang sagot. Sa prinsipyo, ang anumang dalawang-daang sagot ay babagay sa iyo. Kung nagbabasa ka ng basang-basa at alam mo na ang ilang mga status ng tugon ay iba sa iba, sagutin ang mga naaangkop: 204, 5, 10, 15, anuman. Kung hindi ito masyadong maganda, "two zero zero" na lang. Kung ang lahat ay naging masama at ang pagsusuri sa kalusugan ay hindi tumugon, pagkatapos ay sagutin ang alinman sa limang daan. Muli, kung naiintindihan mo kung paano tumugon, kung paano naiiba ang iba't ibang mga status ng tugon sa bawat isa. Kung hindi mo naiintindihan, ang 502 ang iyong opsyon na tumugon sa mga pagsusuri sa kalusugan kung may nangyaring mali.

Ito ay isa pang punto, gusto kong bumalik ng kaunti tungkol sa pagsuri sa mga pinagbabatayan na serbisyo. Kung sisimulan mo, halimbawa, suriin ang lahat ng pinagbabatayan na serbisyo na nasa likod ng iyong aplikasyon - lahat sa pangkalahatan. Ang nakukuha namin mula sa punto ng view ng arkitektura ng microservice, mayroon kaming isang konsepto bilang "mababang pagkabit" - iyon ay, kapag ang iyong mga serbisyo ay kaunting umaasa sa isa't isa. Kung nabigo ang isa sa mga ito, ang lahat ng iba pa na walang ganitong functionality ay magpapatuloy na gagana. Ang ilan sa mga pag-andar ay hindi gumagana. Alinsunod dito, kung itali mo ang lahat ng mga pagsusuri sa kalusugan sa isa't isa, magkakaroon ka ng isang bagay na mabibigo sa imprastraktura, at dahil nahulog ito, ang lahat ng mga pagsusuri sa kalusugan ng lahat ng mga serbisyo ay nagsisimula ring mabigo - at mayroong higit pang imprastraktura sa pangkalahatan para sa buong arkitektura ng microservice No. Nagdilim ang lahat doon.

Samakatuwid, nais kong ulitin ito na kailangan mong suriin ang mga pinagbabatayan na serbisyo, ang mga kung wala ang iyong aplikasyon sa isang daang porsyento ng mga kaso ay hindi magagawa ang trabaho nito. Iyon ay, ito ay lohikal na kung mayroon kang isang REST API kung saan ang gumagamit ay nagse-save sa database o kinukuha mula sa database, kung gayon sa kawalan ng isang database, hindi mo magagarantiyahan ang trabaho sa iyong mga gumagamit.

Ngunit kung ang iyong mga user, kapag inilabas mo sila sa database, ay pinayaman din ng ilang iba pang metadata, mula sa isa pang backend, na ipinasok mo bago magpadala ng tugon sa frontend - at hindi available ang backend na ito, nangangahulugan ito na ibibigay mo ang iyong sagot nang walang anumang bahagi ng metadata.

Susunod, mayroon din kaming isa sa mga masakit na isyu kapag naglulunsad ng mga application.

Sa katunayan, hindi lang ito nalalapat sa mga Kubernetes sa pangkalahatan; nagkataon lang na nagsimulang kumalat ang kultura ng ilang uri ng mass development at ang mga DevOps sa partikular na kasabay ng Kubernetes. Samakatuwid, sa pangkalahatan, lumalabas na kailangan mong maayos na isara ang iyong aplikasyon nang walang Kubernetes. Bago pa man ang Kubernetes, ginawa na ito ng mga tao, ngunit sa pagdating ng Kubernetes, sinimulan na naming pag-usapan ito nang maramihan.

Magandang Pagsara

Sa pangkalahatan, ano ang Graceful Shutdown at bakit ito kailangan? Ito ay tungkol sa kapag nag-crash ang iyong application sa ilang kadahilanan, kailangan mong gawin app stop - o nakatanggap ka, halimbawa, ng senyales mula sa operating system, dapat itong maunawaan ng iyong aplikasyon at gumawa ng isang bagay tungkol dito. Ang pinakamasamang sitwasyon, siyempre, ay kapag ang iyong aplikasyon ay nakatanggap ng SIGTERM at tulad ng "SIGTERM, maghintay tayo, magtrabaho, huwag gawin." Isa itong talagang masamang opsyon.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

An almost equally bad option is when your application receives a SIGTERM and is like β€œsabi nila segterm, ibig sabihin matatapos na tayo, hindi ko nakita, wala akong alam na request ng user, hindi ko alam kung anong klaseng mga kahilingan na ginagawa ko ngayon, sabi nila SIGTERM, ibig sabihin magtatapos na tayo " Isa rin itong masamang opsyon.

Aling pagpipilian ang mabuti? Ang unang punto ay isaalang-alang ang pagkumpleto ng mga operasyon. Ang isang magandang opsyon ay para sa iyong server na isaalang-alang pa rin kung ano ang ginagawa nito kung ito ay nakatanggap ng SIGTERM.

Ang SIGTERM ay isang soft shutdown, ito ay espesyal na dinisenyo, maaari itong ma-intercept sa antas ng code, maaari itong iproseso, sabihin na ngayon, teka, tapusin muna natin ang trabaho na mayroon tayo, pagkatapos ay lalabas tayo.

Mula sa pananaw ng Kubernetes, ganito ang hitsura nito. Kapag sinabi namin sa isang pod na tumatakbo sa Kubernetes cluster, "mangyaring huminto ka, umalis ka," o tayo ay magre-restart, o magkakaroon ng update kapag muling ginawa ng Kubernetes ang mga pod, ang Kubernetes ay nagpapadala lamang ng parehong SIGTERM na mensahe sa pod, naghihintay para sa ilang oras, at , ito ang oras na naghihintay siya, ito ay na-configure din, mayroong isang espesyal na parameter sa mga diploma at ito ay tinatawag na Graceful ShutdownTimeout. Tulad ng naiintindihan mo, hindi ito tinatawag na para sa wala, at hindi para sa wala na pinag-uusapan natin ito ngayon.

Doon natin partikular na masasabi kung gaano katagal natin kailangang maghintay sa pagitan ng oras na ipinadala natin ang SIGTERM sa aplikasyon at kapag naunawaan natin na ang application ay tila nabaliw para sa isang bagay o "natigil" at hindi na magtatapos - at kailangan nating ipadala ito sa SIGKILL, iyon ay, mahirap kumpletuhin ang trabaho nito. Iyon ay, naaayon, mayroon kaming ilang uri ng daemon na tumatakbo, pinoproseso nito ang mga operasyon. Naiintindihan namin na sa karaniwan ang aming mga operasyon kung saan gumagana ang daemon ay hindi tumatagal ng higit sa 30 segundo sa isang pagkakataon. Alinsunod dito, kapag dumating ang SIGTERM, nauunawaan namin na ang aming daemon ay makakapagtapos ng 30 segundo pagkatapos ng SIGTERM. Isinulat namin ito, halimbawa, 45 segundo kung sakali at sabihin na SIGTERM. Pagkatapos nito, maghintay kami ng 45 segundo. Sa teorya, sa panahong ito dapat natapos ng demonyo ang gawain nito at tinapos ang sarili. Ngunit kung biglang hindi nito magawa, nangangahulugan ito na malamang na natigil itoβ€”hindi na nito normal na pinoproseso ang aming mga kahilingan. At sa loob ng 45 segundo maaari mong ligtas, sa katunayan, mapapako siya.

At dito, sa katunayan, kahit na 2 aspeto ay maaaring isaalang-alang. Una, unawain na kung nakatanggap ka ng isang kahilingan, nagsimula kang magtrabaho kasama ito kahit papaano at hindi nagbigay ng tugon sa gumagamit, ngunit nakatanggap ka ng SIGTERM, halimbawa. Makatuwirang pinuhin ito at magbigay ng sagot sa gumagamit. Ito ang numero unong punto sa bagay na ito. Ang point number two dito ay na kung isusulat mo ang iyong sariling application, sa pangkalahatan ay bubuo ng arkitektura sa paraang makakatanggap ka ng kahilingan para sa iyong aplikasyon, pagkatapos ay magsisimula ka ng ilang trabaho, magsimulang mag-download ng mga file mula sa kung saan, mag-download ng database, at kung ano pa. - yun. Sa pangkalahatan, ang iyong user, ang iyong kahilingan ay nakabitin ng kalahating oras at naghihintay na sagutin mo siya - pagkatapos, malamang, kailangan mong magtrabaho sa arkitektura. Iyon ay, isaalang-alang lamang kahit na ang sentido komun na kung ang iyong mga operasyon ay maikli, pagkatapos ay makatuwiran na huwag pansinin ang SIGTERM at baguhin ito. Kung mahaba ang iyong mga operasyon, walang saysay na balewalain ang SIGTERM sa kasong ito. Makatuwiran na muling idisenyo ang arkitektura upang maiwasan ang mga ganoong katagal na operasyon. Upang ang mga gumagamit ay hindi lamang tumambay at maghintay. Ewan ko, gumawa ka ng websocket diyan, gumawa ka ng mga reverse hook na ipapadala na ng server mo sa client, kahit ano pa, pero wag mo pilitin ang user na mag-hang ng kalahating oras at maghintay lang ng session hanggang sa ikaw. sagutin mo siya. Dahil ito ay hindi mahuhulaan kung saan ito maaaring masira.

Kapag natapos ang iyong aplikasyon, dapat kang magbigay ng ilang naaangkop na exit code. Iyon ay, kung ang iyong aplikasyon ay hiniling na isara, ihinto, at nagawa nitong ihinto ang sarili nito nang normal, hindi mo na kailangang ibalik ang ilang uri ng exit code 1,5,255 at iba pa. Anumang bagay na hindi zero code, hindi bababa sa mga sistema ng Linux, sigurado ako dito, ay itinuturing na hindi matagumpay. Iyon ay, itinuturing na ang iyong aplikasyon sa kasong ito ay natapos sa isang error. Alinsunod dito, sa isang mapayapang paraan, kung nakumpleto ang iyong aplikasyon nang walang error, sasabihin mong 0 sa output. Kung nabigo ang iyong aplikasyon sa ilang kadahilanan, sasabihin mong hindi 0 sa output. At maaari kang magtrabaho sa impormasyong ito.

At ang huling pagpipilian. Masama kapag nagpadala ang iyong user ng kahilingan at nag-hang ng kalahating oras habang pinoproseso mo ito. Ngunit sa pangkalahatan, gusto ko ring sabihin tungkol sa kung ano ang karaniwang sulit mula sa panig ng kliyente. Hindi mahalaga kung mayroon kang mobile application, front-end, atbp. Kinakailangang isaalang-alang na sa pangkalahatan ang session ng user ay maaaring wakasan, anumang bagay ay maaaring mangyari. Maaaring magpadala ng kahilingan, halimbawa, hindi naproseso at walang ibinalik na tugon. Ang iyong frontend o ang iyong mobile application - anumang frontend sa pangkalahatan, ilagay natin ito sa paraang iyon - dapat itong isaalang-alang. Kung nagtatrabaho ka sa mga websocket, sa pangkalahatan ito ang pinakamatinding sakit na naranasan ko.

Kapag hindi alam ng mga developer ng ilang regular na pakikipag-chat, lumalabas, maaaring masira ang websocket. Para sa kanila, kapag may nangyari sa proxy, binabago lang namin ang config, at nagre-reload. Naturally, ang lahat ng mahabang buhay na mga sesyon ay napunit sa kasong ito. Tumatakbo ang mga developer sa amin at nagsabing: β€œMga pare, ano ang ginagawa ninyo, nasira ang chat para sa lahat ng aming kliyente!” Sinasabi namin sa kanila: β€œAno ang ginagawa mo? Hindi ba makakonekta muli ang iyong mga kliyente? Sabi nila: "Hindi, kailangan namin ang mga sesyon na hindi mapunit." Sa madaling salita, ito ay talagang walang kapararakan. Ang panig ng kliyente ay kailangang isaalang-alang. Lalo na, tulad ng sinasabi ko, na may mahabang buhay na mga session tulad ng mga websocket, maaari itong masira at, nang hindi napapansin ng gumagamit, kailangan mong muling mai-install ang mga naturang session. At pagkatapos ang lahat ay perpekto.

Mga Mapagkukunan

Actually, dito ko lang sasabihin sa inyo ang isang straight story. Mula sa totoong buhay. Ang pinakamasakit na bagay na narinig ko tungkol sa mga mapagkukunan.

Mga mapagkukunan sa kasong ito, ang ibig kong sabihin, ilang uri ng mga kahilingan, mga limitasyon na maaari mong ilagay sa mga pod sa iyong mga Kubernetes cluster. Ang pinakanakakatawang bagay na narinig ko mula sa isang developer... Minsan ay sinabi ng isa sa aking mga kapwa developer sa isang dating lugar ng trabaho: "Hindi magsisimula ang aking application sa cluster." Tiningnan ko na hindi ito nagsisimula, ngunit hindi ito umaangkop sa mga mapagkukunan, o nagtakda sila ng napakaliit na limitasyon. Sa madaling salita, hindi maaaring magsimula ang application dahil sa mga mapagkukunan. Sinasabi ko: "Hindi ito magsisimula dahil sa mga mapagkukunan, magpapasya ka kung magkano ang kailangan mo at magtakda ng sapat na halaga." Sinabi niya: "Anong uri ng mga mapagkukunan?" I started explaining to him that Kubernetes, limits on requests and blah, blah, blah need to set. Ang lalaki ay nakinig sa loob ng limang minuto, tumango at nagsabi: "Pumunta ako dito upang magtrabaho bilang isang developer, ayaw kong malaman ang anumang bagay tungkol sa anumang mga mapagkukunan. Pumunta ako dito para magsulat ng code at iyon lang." Ito ay malungkot. Ito ay isang napakalungkot na konsepto mula sa pananaw ng isang developer. Lalo na sa modernong mundo, kung sabihin, ng mga progresibong devops.

Bakit kailangan ang mga mapagkukunan? Mayroong 2 uri ng mga mapagkukunan sa Kubernetes. Ang ilan ay tinatawag na mga kahilingan, ang iba ay tinatawag na mga limitasyon. Sa pamamagitan ng mga mapagkukunan, mauunawaan natin na palaging may dalawang pangunahing paghihigpit. Ibig sabihin, mga limitasyon sa oras ng CPU at mga limitasyon ng RAM para sa isang container na tumatakbo sa Kubernetes.

Ang isang limitasyon ay naglalagay ng pinakamataas na limitasyon sa kung paano magagamit ang isang mapagkukunan sa iyong aplikasyon. Iyon ay, nang naaayon, kung sasabihin mo ang 1GB ng RAM sa mga limitasyon, kung gayon ang iyong aplikasyon ay hindi makakagamit ng higit sa 1GB ng RAM. At kung bigla niyang gusto at susubukan na gawin ito, pagkatapos ay isang proseso na tinatawag na oom killer, wala sa memorya, iyon ay, darating at papatayin ang iyong aplikasyon - iyon ay, ito ay magsisimulang muli. Hindi magre-restart ang mga application batay sa CPU. Sa mga tuntunin ng CPU, kung ang isang application ay sumusubok na gumamit ng maraming, higit sa tinukoy sa mga limitasyon, ang CPU ay mahigpit na pipiliin. Hindi ito humahantong sa mga pag-restart. Ito ang limitasyon - ito ang pinakamataas na limitasyon.

At may hiling. Ang isang kahilingan ay kung paano nauunawaan ng mga Kubernetes kung paano napupuno ng mga application ang mga node sa iyong cluster ng Kubernetes. Ibig sabihin, ang kahilingan ay isang uri ng commit ng iyong aplikasyon. Sinasabi nito kung ano ang gusto kong gamitin: "Gusto kong magreserba ka ng ganito kalaking CPU at ganito karaming memorya para sa akin." Napakasimpleng pagkakatulad. Paano kung mayroon tayong node na, hindi ko alam, 8 CPU sa kabuuan. At isang pod ang dumating doon, na ang mga kahilingan ay nagsasabing 1 CPU, na nangangahulugang ang node ay may 7 CPU na natitira. Iyon ay, nang naaayon, sa sandaling dumating ang 8 pod sa node na ito, ang bawat isa ay mayroong 1 CPU sa kanilang mga kahilingan, ang node, na parang mula sa punto ng view ng Kubernetes, ay naubusan ng CPU at higit pang mga pod na may mga kahilingan ay hindi maaaring inilunsad sa node na ito. Kung naubusan ng CPU ang lahat ng node, magsisimulang sabihin ng Kubernetes na walang angkop na mga node sa cluster para patakbuhin ang iyong mga pod dahil ubos na ang CPU.

Bakit kailangan ang mga kahilingan at bakit kung walang mga kahilingan, sa tingin ko ay hindi na kailangang maglunsad ng anuman sa Kubernetes? Isipin natin ang isang hypothetical na sitwasyon. Inilunsad mo ang iyong aplikasyon nang walang mga kahilingan, hindi alam ng Kubernetes kung gaano karami ang mayroon ka, kung anong mga node ang maaari mong itulak ito. Buweno, tinutulak niya, tinutulak, tinutulak papunta sa mga node. Sa isang punto, magsisimula kang makakuha ng trapiko sa iyong aplikasyon. At ang isa sa mga application ay biglang nagsimulang gumamit ng mga mapagkukunan hanggang sa mga limitasyon na mayroon ito ayon sa mga limitasyon. Ito ay lumabas na may isa pang application sa malapit at nangangailangan din ito ng mga mapagkukunan. Ang node ay aktwal na nagsisimula sa pisikal na maubusan ng mga mapagkukunan, halimbawa, OP. Ang node ay aktwal na nagsisimulang pisikal na maubusan ng mga mapagkukunan, halimbawa, random access memory (RAM). Kapag ang isang node ay naubusan ng kapangyarihan, una sa lahat ang docker ay titigil sa pagtugon, pagkatapos ay ang cubelet, pagkatapos ay ang OS. Sila ay mawawalan ng malay at ang LAHAT ay tiyak na titigil sa pagtatrabaho para sa iyo. Iyon ay, hahantong ito sa iyong node na makaalis at kakailanganin mong i-restart ito. Sa madaling salita, hindi masyadong maganda ang sitwasyon.

At kapag mayroon kang mga kahilingan, ang mga limitasyon ay hindi masyadong naiiba, hindi bababa sa hindi maraming beses na higit sa mga limitasyon o mga kahilingan, pagkatapos ay maaari kang magkaroon ng tulad ng isang normal, makatuwirang pagpuno ng mga aplikasyon sa mga node ng mga kumpol ng Kubernetes. Kasabay nito, tinatayang alam ng Kubernetes kung gaano karami ang inilalagay nito kung saan, gaano karami ang ginagamit kung saan. Ibig sabihin, sandali lang ito. Mahalagang maunawaan ito. At mahalagang kontrolin na ito ay ipinahiwatig.

Imbakan ng data

Ang aming susunod na punto ay tungkol sa pag-iimbak ng data. Ano ang gagawin sa kanila at sa pangkalahatan, ano ang gagawin sa pagtitiyaga sa Kubernetes?

Sa tingin ko, muli, sa loob ng aming Paaralan ng Gabi, nagkaroon ng paksa tungkol sa database sa Kubernetes. At sa palagay ko, halos alam ko na kung ano ang sinabi sa iyo ng iyong mga kasamahan nang tanungin: "Posible bang magpatakbo ng isang database sa Kubernetes?" Para sa ilang kadahilanan, tila sa akin ay dapat na sinabi sa iyo ng iyong mga kasamahan na kung itatanong mo ang tanong kung posible bang magpatakbo ng isang database sa Kubernetes, kung gayon imposible.

Ang lohika dito ay simple. Kung sakali, ipapaliwanag ko muli, kung ikaw ay isang talagang cool na tao na maaaring bumuo ng isang medyo fault-tolerant na sistema ng distributed network storage, maunawaan kung paano magkasya ang isang database sa kasong ito, kung paano dapat gumana ang cloud native sa mga container sa isang database sa pangkalahatan. Malamang, wala kang tanong tungkol sa kung paano patakbuhin ito. Kung mayroon kang ganoong tanong, at nais mong tiyakin na ang lahat ng ito ay magbubukas at nakatayo hanggang kamatayan sa paggawa at hindi kailanman bumagsak, kung gayon hindi ito mangyayari. Ikaw ay garantisadong kukunan ang iyong sarili sa paa gamit ang diskarteng ito. Kaya mas mabuting huwag na lang.

Ano ang dapat naming gawin sa data na gustong i-store ng aming application, ilang larawan na ina-upload ng mga user, ilang bagay na nabuo ng aming application sa panahon ng operasyon nito, sa startup, halimbawa? Ano ang gagawin sa kanila sa Kubernetes?

Sa pangkalahatan, sa isip, oo, siyempre, ang Kubernetes ay napakahusay na idinisenyo at sa pangkalahatan ay naisip sa simula para sa mga application na walang estado. Iyon ay, para sa mga application na hindi nag-iimbak ng impormasyon sa lahat. Ito ay perpekto.

Ngunit, siyempre, ang perpektong opsyon ay hindi palaging umiiral. E ano ngayon? Ang una at pinakasimpleng punto ay ang kumuha ng ilang uri ng S3, hindi lang isang gawang bahay, na hindi rin malinaw kung paano ito gumagana, ngunit mula sa ilang provider. Isang mahusay, normal na provider - at turuan ang iyong aplikasyon na gumamit ng S3. Iyon ay, kapag gusto ng iyong user na mag-upload ng file, sabihin ang "dito, mangyaring, i-upload ito sa S3." Kapag gusto niyang matanggap ito, sabihin: "Narito ang isang link pabalik sa S3 at kunin ito mula rito." Ito ay perpekto.

Kung biglang sa ilang kadahilanan ang perpektong opsyon na ito ay hindi angkop, mayroon kang isang application na hindi mo isinulat, hindi ka bumuo, o ito ay isang uri ng kakila-kilabot na pamana, hindi nito magagamit ang S3 protocol, ngunit dapat gumana sa mga lokal na direktoryo sa mga lokal na folder. Kumuha ng mas simple o mas simple, i-deploy ang Kubernetes. Iyon ay, ang pag-fencing kaagad kay Ceph para sa ilang mga minimal na gawain, tila sa akin, ay isang masamang ideya. Dahil si Ceph, siyempre, magaling at uso. Ngunit kung hindi mo talaga naiintindihan kung ano ang iyong ginagawa, pagkatapos ay sa sandaling ilagay mo ang isang bagay kay Ceph, maaari mong napakadali at hindi na ito maaalis muli doon. Dahil, tulad ng alam mo, ang Ceph ay nag-iimbak ng data sa kumpol nito sa binary form, at hindi sa anyo ng mga simpleng file. Samakatuwid, kung biglang masira ang Ceph cluster, pagkatapos ay mayroong isang kumpleto at mataas na posibilidad na hindi mo na makukuha muli ang iyong data mula doon.

May course tayo kay Ceph, pwede pamilyar sa programa at magsumite ng aplikasyon.

Samakatuwid, mas mahusay na gumawa ng isang bagay na simple tulad ng isang NFS server. Ang mga Kubernetes ay maaaring gumana sa kanila, maaari kang mag-mount ng isang direktoryo sa ilalim ng isang NFS server - ang iyong aplikasyon ay tulad ng isang lokal na direktoryo. Kasabay nito, natural, kailangan mong maunawaan na, muli, kailangan mong gumawa ng isang bagay sa iyong NFS, kailangan mong maunawaan na kung minsan ay maaaring maging hindi naa-access at isaalang-alang ang tanong kung ano ang iyong gagawin sa kasong ito. Marahil ay dapat itong i-back up sa isang lugar sa isang hiwalay na makina.

Ang susunod na puntong pinag-usapan ko ay kung ano ang gagawin kung ang iyong application ay bumubuo ng ilang mga file sa panahon ng operasyon. Halimbawa, kapag nagsimula ito, bumubuo ito ng ilang static na file, na batay sa ilang impormasyon na natatanggap lamang ng application sa oras ng paglulunsad. Anong sandali. Kung walang ganoong data, hindi mo na kailangang mag-abala, i-install lamang ang application na ito para sa iyong sarili at magtrabaho. Ang tanong lang dito ay ano, tingnan mo. Kadalasan, lahat ng uri ng legacy system, tulad ng WordPress at iba pa, lalo na sa binagong ilang uri ng matatalinong plugin, matalinong mga developer ng PHP, madalas nilang alam kung paano ito gagawin upang makabuo sila ng ilang uri ng file para sa kanilang sarili. Alinsunod dito, ang isa ay bumubuo ng isang file, ang pangalawa ay bumubuo ng pangalawang file. Sila ay magkaiba. Nangyayari ang pagbabalanse sa cluster ng Kubernetes ng mga kliyente nang nagkataon lamang. Alinsunod dito, lumalabas na hindi nila alam kung paano magtulungan instance. Ang isa ay nagbibigay ng isang impormasyon, ang isa ay nagbibigay sa gumagamit ng isa pang impormasyon. Ito ay isang bagay na dapat mong iwasan. Ibig sabihin, sa Kubernetes, lahat ng ilulunsad mo ay garantisadong magagawang gumana sa maraming pagkakataon. Dahil ang Kubernetes ay isang bagay na gumagalaw. Alinsunod dito, maaari niyang ilipat ang anumang bagay, kahit kailan niya gusto, nang hindi nagtatanong kahit kanino. Samakatuwid, kailangan mong umasa dito. Lahat ng inilunsad sa isang pagkakataon ay malaon o huli ay mabibigo. Kung mas maraming reserbasyon ang mayroon ka, mas mabuti. Ngunit muli, sinasabi ko, kung mayroon kang ilang mga ganoong file, maaari mong ilagay ang mga ito sa ilalim mo, tumitimbang sila ng maliit na halaga. Kung may kaunti pa sa kanila, malamang na hindi mo dapat itulak ang mga ito sa loob ng lalagyan.

Ipapayo ko na mayroong napakagandang bagay sa Kubernetes, maaari mong gamitin ang volume. Sa partikular, mayroong isang dami ng uri ng walang laman na dir. Ibig sabihin, awtomatikong gagawa ang Kubernetes ng isang direktoryo sa mga direktoryo ng serbisyo nito sa server kung saan ka nagsimula. At bibigyan ka niya para magamit mo. Mayroon lamang isang mahalagang punto. Ibig sabihin, hindi maiimbak ang iyong data sa loob ng container, ngunit sa host kung saan ka tumatakbo. Bukod dito, makokontrol ng Kubernetes ang mga walang laman na dir sa ilalim ng normal na configuration at nagagawa nitong kontrolin ang kanilang maximum na laki at hindi pinapayagan itong lumampas. Ang tanging punto ay ang iyong isinulat sa walang laman na dir ay hindi mawawala sa panahon ng pod restart. Iyon ay, kung ang iyong pod ay nahulog nang hindi sinasadya at tumaas muli, ang impormasyon sa walang laman na dir ay hindi mapupunta kahit saan. Magagamit niya itong muli sa bagong simula - at mabuti iyon. Kung umalis ang iyong pod sa isang lugar, natural na aalis siya nang walang data. Iyon ay, sa sandaling mawala ang pod mula sa node kung saan ito inilunsad na may walang laman na dir, tatanggalin ang walang laman na dir.

Ano pa ang maganda sa walang laman na dir? Halimbawa, maaari itong magamit bilang isang cache. Isipin natin na ang aming application ay bumubuo ng isang bagay sa mabilisang, ibinibigay ito sa mga gumagamit, at ginagawa ito nang mahabang panahon. Samakatuwid, ang application, halimbawa, ay bumubuo at nagbibigay nito sa mga user, at sa parehong oras ay nag-iimbak nito sa isang lugar, upang sa susunod na ang user ay dumating para sa parehong bagay, ito ay magiging mas mabilis upang bigyan ito kaagad na nabuo. Maaaring hilingin sa Kubernetes ang walang laman na dir na gumawa sa memorya. At sa gayon, ang iyong mga cache sa pangkalahatan ay maaaring gumana sa bilis ng kidlat - sa mga tuntunin ng bilis ng pag-access sa disk. Iyon ay, mayroon kang isang walang laman na dir sa memorya, sa OS ito ay naka-imbak sa memorya, ngunit para sa iyo, para sa gumagamit sa loob ng pod, mukhang isang lokal na direktoryo lamang. Hindi mo kailangan ang app para partikular na magturo ng anumang magic. Direkta mo lang kukunin at ilagay ang iyong file sa isang direktoryo, ngunit, sa katunayan, sa memorya sa OS. Ito rin ay isang napaka-maginhawang tampok sa mga tuntunin ng Kubernetes.

Anong mga problema ang mayroon si Minio? Ang pangunahing problema sa Minio ay upang gumana ang bagay na ito, kailangan itong tumakbo sa isang lugar, at dapat mayroong ilang uri ng file system, iyon ay, imbakan. And here we encounter the same problems that Ceph has. Iyon ay, ang Minio ay dapat mag-imbak ng mga file nito sa isang lugar. Isa lang itong HTTP interface sa iyong mga file. Bukod dito, ang pag-andar ay malinaw na mas mahirap kaysa sa S3 ng Amazon. Dati, hindi nito nagawang pahintulutan nang maayos ang user. Ngayon, sa pagkakaalam ko, maaari na itong lumikha ng mga bucket na may iba't ibang mga pahintulot, ngunit muli, tila sa akin na ang pangunahing problema ay, wika nga, ang pinagbabatayan na sistema ng imbakan sa pinakamababa.

Paano nakakaapekto ang Empty dir sa memorya sa mga limitasyon? Hindi nakakaapekto sa mga limitasyon sa anumang paraan. Ito ay namamalagi sa memorya ng host, at hindi sa memorya ng iyong lalagyan. Ibig sabihin, hindi nakikita ng iyong container ang walang laman na dir sa memorya bilang bahagi ng inookupahang memorya nito. Nakikita ito ng host. Alinsunod dito, oo, mula sa punto ng view ng mga kubernetes, kapag sinimulan mong gamitin ito, makabubuting maunawaan na inilalaan mo ang bahagi ng iyong memorya sa walang laman na dir. At nang naaayon, unawain na ang memorya ay maaaring maubusan hindi lamang dahil sa mga application, kundi pati na rin dahil may sumulat sa mga walang laman na dir na ito.

Cloudnativeness

At ang huling subtopic ay kung ano ang Cloudnative. Bakit kailangan? Cloudnativeness at iba pa.

Iyon ay, ang mga application na iyon na may kakayahan at nakasulat upang gumana sa isang modernong imprastraktura ng ulap. Ngunit, sa katunayan, ang Cloudnative ay may isa pang ganoong aspeto. Na ito ay hindi lamang isang application na isinasaalang-alang ang lahat ng mga kinakailangan ng isang modernong imprastraktura ng ulap, ngunit alam din kung paano magtrabaho kasama ang modernong imprastraktura ng ulap, samantalahin ang mga pakinabang at disadvantages ng katotohanan na ito ay gumagana sa mga ulap na ito. Huwag lamang lumampas sa dagat at magtrabaho sa ulap, ngunit samantalahin ang mga benepisyo ng pagtatrabaho sa cloud.

Mga kinakailangan para sa pagbuo ng isang aplikasyon sa Kubernetes

Kunin na lang natin ang Kubernetes bilang halimbawa. Ang iyong application ay tumatakbo sa Kubernetes. Ang iyong aplikasyon ay maaaring palaging, o sa halip, ang mga admin para sa iyong aplikasyon, ay maaaring palaging lumikha ng isang account ng serbisyo. Iyon ay, isang account para sa awtorisasyon sa Kubernetes mismo sa server nito. Magdagdag ng ilang mga karapatan na kailangan namin doon. At maaari mong i-access ang Kubernetes mula sa loob ng iyong application. Ano ang maaari mong gawin sa ganitong paraan? Halimbawa, mula sa application, tumanggap ng data tungkol sa kung saan matatagpuan ang iyong iba pang mga application, iba pang katulad na mga instance, at magkakasama kahit papaano sa itaas ng Kubernetes, kung may ganoong pangangailangan.

Muli, literal na nagkaroon kami ng kaso kamakailan. Mayroon kaming isang controller na sumusubaybay sa pila. At kapag lumitaw ang ilang bagong gawain sa queue na ito, mapupunta ito sa Kubernetes - at sa loob ng Kubernetes ay gagawa ito ng bagong pod. Binibigyan ang pod na ito ng ilang bagong gawain at sa loob ng balangkas ng pod na ito, ginagawa ng pod ang gawain, nagpapadala ng tugon sa controller mismo, at pagkatapos ay may gagawin ang controller sa impormasyong ito. Halimbawa, nagdaragdag ito ng isang database. Iyon ay, muli, ito ay isang plus ng katotohanan na ang aming application ay tumatakbo sa Kubernetes. Maaari naming gamitin ang built-in na pagpapagana ng Kubernetes mismo upang kahit papaano ay mapalawak at gawing mas maginhawa ang pagpapagana ng aming application. Iyon ay, huwag itago ang ilang uri ng magic tungkol sa kung paano maglunsad ng isang application, kung paano maglunsad ng isang manggagawa. Sa Kubernetes, magpadala ka lang ng kahilingan sa app kung nakasulat ang application sa Python.

Ang parehong naaangkop kung lalampas tayo sa Kubernetes. Mayroon kaming mga Kubernete na tumatakbo sa isang lugar - mabuti kung ito ay nasa ilang uri ng ulap. Muli, maaari nating gamitin, at kahit na dapat, naniniwala ako, gamitin ang mga kakayahan ng cloud mismo kung saan tayo tumatakbo. Mula sa mga elementarya na ibinibigay sa atin ng ulap. Ang pagbabalanse, ibig sabihin, maaari tayong lumikha ng mga cloud balancer at gamitin ang mga ito. Ito ay isang direktang bentahe ng kung ano ang maaari naming gamitin. Dahil ang pagbabalanse ng cloud, una, ay simpleng inaalis ang responsibilidad mula sa amin para sa kung paano ito gumagana, kung paano ito na-configure. Dagdag pa, ito ay napaka-maginhawa, dahil ang mga regular na Kubernete ay maaaring isama sa mga ulap.

Ang parehong napupunta para sa scaling. Ang mga regular na Kubernetes ay maaaring isama sa mga cloud provider. Alam kung paano maunawaan na kung ang cluster ay naubusan ng mga node, iyon ay, ang node space ay naubusan, pagkatapos ay kailangan mong magdagdag - Kubernetes mismo ay magdaragdag ng mga bagong node sa iyong cluster at magsisimulang maglunsad ng mga pod sa kanila. Iyon ay, kapag dumating ang iyong load, ang bilang ng mga apuyan ay nagsisimulang tumaas. Kapag naubos ang mga node sa cluster para sa mga pod na ito, maglulunsad ang Kubernetes ng mga bagong node at, nang naaayon, maaari pa ring tumaas ang bilang ng mga pod. At ito ay napaka maginhawa. Ito ay isang direktang pagkakataon upang masukat ang kumpol sa mabilisang. Hindi masyadong mabilis, sa kahulugan na ito ay hindi isang segundo, ito ay mas katulad ng isang minuto upang magdagdag ng mga bagong node.

Ngunit mula sa aking karanasan, muli, ito ang pinakaastig na bagay na nakita ko. Kapag nag-scale ang Cloudnative cluster batay sa oras ng araw. Isa itong backend na serbisyo na ginamit ng mga tao sa back office. Iyon ay, darating sila sa trabaho sa 9 ng umaga, magsimulang mag-log in sa system, at naaayon, ang Cloudnative cluster, kung saan lahat ng ito ay tumatakbo, ay nagsisimulang lumaki, na naglulunsad ng mga bagong pod upang ang lahat ng darating sa trabaho ay maaaring gumana sa application. Kapag umalis sila sa trabaho ng 8 pm o 6 pm, napansin ng mga Kubernetes cluster na wala nang gumagamit ng application at nagsisimulang lumiit. Ang mga matitipid na hanggang 30 porsiyento ay ginagarantiyahan. Gumagana ito sa Amazon noong panahong iyon; sa oras na iyon ay walang sinuman sa Russia na magagawa ito nang napakahusay.

Sasabihin ko sa iyo nang diretso, ang matitipid ay 30 porsiyento dahil lang sa gumagamit kami ng Kubernetes at sinasamantala ang mga kakayahan ng cloud. Ngayon ay maaari itong gawin sa Russia. Hindi ako mag-a-advertise sa sinuman, siyempre, ngunit sabihin na lang natin na may mga provider na magagawa ito, ibigay ito kaagad sa labas ng kahon na may isang pindutan.

May isang huling punto na gusto ko ring bigyan ng atensyon mo. Upang ang iyong aplikasyon, ang iyong imprastraktura ay maging Cloudnative, makatuwiran na sa wakas ay simulan ang pag-angkop sa diskarte na tinatawag na Infrastructure bilang isang Code. Ibig sabihin, nangangahulugan ito na ang iyong aplikasyon, o sa halip, ang iyong imprastraktura, ay kailangan sa eksaktong parehong paraan tulad ng code Ilarawan ang iyong aplikasyon, ang lohika ng iyong negosyo sa anyo ng code. At magtrabaho kasama ito bilang code, iyon ay, subukan ito, ilunsad ito, iimbak ito sa git, ilapat ang CICD dito.

At ito mismo ang nagpapahintulot sa iyo, una, na laging magkaroon ng kontrol sa iyong imprastraktura, upang laging maunawaan kung ano ang estado nito. Pangalawa, iwasan ang mga manu-manong operasyon na nagdudulot ng mga error. Pangatlo, iwasan lamang ang tinatawag na turnover, kapag palagi mong kailangang gawin ang parehong mga manu-manong gawain. Pang-apat, pinapayagan ka nitong mabawi nang mas mabilis kung sakaling mabigo. Sa Russia, sa tuwing pinag-uusapan ko ito, palaging may malaking bilang ng mga tao na nagsasabi: "Oo, malinaw, ngunit mayroon kang mga diskarte, sa madaling salita, hindi na kailangang ayusin ang anuman." Pero totoo naman. Kung may nasira sa iyong imprastraktura, pagkatapos ay mula sa punto ng view ng Cloudnative na diskarte at mula sa punto ng view ng Infrastructure bilang isang Code, sa halip na ayusin ito, pumunta sa server, alamin kung ano ang nasira at ayusin ito, mas madali upang tanggalin ang server at gawin itong muli. At ipapanumbalik ko ang lahat ng ito.

Ang lahat ng mga isyung ito ay tinalakay nang mas detalyado sa Mga kurso sa video ng Kubernetes: Junior, Basic, Mega. Sa pamamagitan ng pagsunod sa link maaari mong gawing pamilyar ang iyong sarili sa programa at kundisyon. Ang maginhawang bagay ay maaari mong master ang Kubernetes sa pamamagitan ng pag-aaral mula sa bahay o trabaho para sa 1-2 oras sa isang araw.

Pinagmulan: www.habr.com

Magdagdag ng komento