Limang hindi nakuha kapag nagde-deploy ng unang application sa Kubernetes

Limang hindi nakuha kapag nagde-deploy ng unang application sa KubernetesNabigo ni Aris-Dreamer

Maraming tao ang naniniwala na sapat na na ilipat ang application sa Kubernetes (gamitin man ang Helm o manu-mano) at magiging masaya sila. Ngunit hindi ito ganoon kasimple.

Koponan Mail.ru Cloud Solutions isinalin ang isang artikulo ng engineer ng DevOps na si Julian Gindi. Ibinahagi niya kung ano ang mga pitfalls na naranasan ng kanyang kumpanya sa proseso ng paglipat upang hindi ka makatapak sa parehong rake.

Unang Hakbang: Pagse-set Up ng Mga Kahilingan at Limitasyon sa Pod

Magsimula tayo sa pamamagitan ng pag-set up ng malinis na kapaligiran kung saan tatakbo ang ating mga pod. Mahusay ang ginagawa ng Kubernetes sa pag-iiskedyul ng mga pod at paghawak sa mga kundisyon ng pagkabigo. Ngunit kung minsan ay hindi makakapaglagay ng pod ang scheduler kung mahirap tantiyahin kung gaano karaming mga mapagkukunan ang kailangan nito upang matagumpay na gumana. Dito lumalabas ang mga kahilingan para sa mga mapagkukunan at limitasyon. Maraming debate tungkol sa pinakamahusay na diskarte sa pagtatakda ng mga kahilingan at limitasyon. Minsan talaga parang mas sining kaysa sa agham. Narito ang aming diskarte.

Mga kahilingan sa pod - Ito ang pangunahing value na ginagamit ng scheduler para mailagay nang husto ang pod.

Ng Dokumentasyon ng Kubernetes: Tinutukoy ng hakbang sa pag-filter ang hanay ng mga node kung saan maaaring iiskedyul ang pod. Halimbawa, sinusuri ng filter ng PodFitsResources kung ang isang node ay may sapat na mapagkukunan upang matugunan ang mga partikular na kahilingan sa mapagkukunan ng pod.

Gumagamit kami ng mga kahilingan sa application upang magamit ang mga ito upang tantiyahin kung gaano karaming mga mapagkukunan sa katunayan Kailangan ito ng application upang gumana nang maayos. Sa ganitong paraan makakapaglagay ang scheduler ng mga node nang makatotohanan. Noong una, gusto naming magtakda ng mga kahilingan na may margin upang matiyak na ang bawat pod ay may sapat na malaking bilang ng mga mapagkukunan, ngunit napansin namin na ang mga oras ng pag-iiskedyul ay tumaas nang malaki at ang ilang mga pod ay hindi kailanman ganap na nakaiskedyul, na parang walang natanggap na mga kahilingan sa mapagkukunan para sa kanila.

Sa kasong ito, madalas na itutulak ng scheduler ang mga pod at hindi na muling maiiskedyul ang mga ito dahil walang ideya ang control plane kung gaano karaming mga mapagkukunan ang kakailanganin ng application, isang mahalagang bahagi ng algorithm ng pag-iiskedyul.

Mga limitasyon ng pod - ito ay isang mas malinaw na limitasyon para sa pod. Kinakatawan nito ang maximum na dami ng mga mapagkukunan na ilalaan ng cluster sa container.

Muli, mula sa opisyal na dokumentasyon: Kung ang isang container ay may nakatakdang 4 GiB memory limit, ipapatupad ito ng kubelet (at ang runtime ng container). Hindi pinapayagan ng runtime ang container na gumamit ng higit sa tinukoy na limitasyon ng mapagkukunan. Halimbawa, kapag sinubukan ng isang proseso sa isang lalagyan na gumamit ng higit sa pinapayagang dami ng memorya, tinatapos ng kernel ng system ang proseso na may error na "out of memory" (OOM).

Ang isang container ay maaaring palaging gumamit ng higit pang mga mapagkukunan kaysa sa tinukoy sa kahilingan ng mapagkukunan, ngunit hindi kailanman maaaring gumamit ng higit sa tinukoy sa limitasyon. Ang halagang ito ay mahirap itakda nang tama, ngunit ito ay napakahalaga.

Sa isip, gusto naming magbago ang mga kinakailangan sa mapagkukunan ng isang pod sa buong ikot ng buhay ng isang proseso nang hindi nakikialam sa iba pang mga proseso sa systemβ€”iyon ang layunin ng pagtatakda ng mga limitasyon.

Sa kasamaang palad, hindi ako makapagbigay ng mga tiyak na tagubilin sa kung anong mga halaga ang itatakda, ngunit kami mismo ay sumusunod sa mga sumusunod na patakaran:

  1. Gamit ang isang load testing tool, ginagaya namin ang baseline level ng trapiko at sinusubaybayan ang paggamit ng pod resources (memory at processor).
  2. Itinakda namin ang mga kahilingan sa pod sa isang arbitraryong mababang halaga (na may limitasyon sa mapagkukunan na humigit-kumulang 5 beses ang halaga ng mga kahilingan) at obserbahan. Kapag masyadong mababa ang mga kahilingan, hindi maaaring magsimula ang proseso, kadalasang nagiging sanhi ng mga mahiwagang error sa runtime ng Go.

Tandaan na ang mas mataas na mga limitasyon sa mapagkukunan ay nagpapahirap sa pag-iskedyul dahil ang pod ay nangangailangan ng isang target na node na may sapat na mga mapagkukunang magagamit.

Isipin ang isang sitwasyon kung saan mayroon kang magaan na web server na may napakataas na limitasyon sa mapagkukunan, sabihin nating 4 GB ng memorya. Ang prosesong ito ay malamang na kailangang i-scale nang pahalang, at ang bawat bagong module ay kailangang naka-iskedyul sa isang node na may hindi bababa sa 4 GB ng magagamit na memorya. Kung walang ganoong node, dapat magpakilala ang cluster ng bagong node para maproseso ang pod na iyon, na maaaring tumagal ng ilang oras. Mahalagang panatilihing pinakamababa ang pagkakaiba sa pagitan ng mga kahilingan sa mapagkukunan at mga limitasyon upang matiyak ang mabilis at maayos na pag-scale.

Pangalawang hakbang: pag-set up ng mga pagsubok sa Liveness at Readiness

Ito ay isa pang banayad na paksa na madalas na tinatalakay sa komunidad ng Kubernetes. Mahalagang magkaroon ng mahusay na pag-unawa sa mga pagsubok sa Liveness at Readiness dahil nagbibigay ang mga ito ng mekanismo para sa software na tumakbo nang maayos at mabawasan ang downtime. Gayunpaman, maaari silang maging sanhi ng isang malubhang hit sa pagganap sa iyong application kung hindi na-configure nang tama. Nasa ibaba ang isang buod ng kung ano ang parehong mga sample.

Buhay na buhay ipinapakita kung tumatakbo ang lalagyan. Kung nabigo ito, papatayin ng kubelet ang container at pinagana ang isang patakaran sa pag-restart para dito. Kung ang lalagyan ay hindi nilagyan ng Liveness probe, ang default na estado ay magiging tagumpay - ito ang sinasabi nito Dokumentasyon ng Kubernetes.

Dapat ay mura ang liveness probe, ibig sabihin, hindi sila dapat kumonsumo ng maraming mapagkukunan, dahil madalas silang tumatakbo at kailangang ipaalam sa Kubernetes na tumatakbo ang application.

Kung itatakda mo ang opsyong tumakbo bawat segundo, magdaragdag ito ng 1 kahilingan sa bawat segundo, kaya't magkaroon ng kamalayan na kakailanganin ang mga karagdagang mapagkukunan upang mahawakan ang trapikong ito.

Sa aming kumpanya, sinusuri ng Liveness test ang mga pangunahing bahagi ng isang application, kahit na ang data (halimbawa, mula sa isang malayuang database o cache) ay hindi ganap na naa-access.

Na-configure namin ang mga app na may endpoint na "kalusugan" na nagbabalik lang ng response code na 200. Isa itong indikasyon na tumatakbo ang proseso at may kakayahang magproseso ng mga kahilingan (ngunit hindi pa trapiko).

Sample Kahandaan ay nagpapahiwatig kung ang lalagyan ay handa na upang maghatid ng mga kahilingan. Kung nabigo ang ready probe, aalisin ng endpoint controller ang IP address ng pod mula sa mga endpoint ng lahat ng serbisyong nauugnay sa pod. Nakasaad din ito sa dokumentasyon ng Kubernetes.

Ang mga pagsusuri sa pagiging handa ay kumonsumo ng mas maraming mapagkukunan dahil dapat silang ipadala sa backend sa paraang nagpapahiwatig na ang application ay handa nang tumanggap ng mga kahilingan.

Mayroong maraming debate sa komunidad tungkol sa kung direktang i-access ang database. Dahil sa overhead (madalas na ginagawa ang mga pagsusuri, ngunit maaaring isaayos), napagpasyahan namin na para sa ilang aplikasyon, binibilang lang ang kahandaang maghatid ng trapiko pagkatapos ma-verify na ibinalik ang mga tala mula sa database. Tiniyak ng mahusay na disenyo ng mga pagsubok sa pagiging handa at mas mataas na antas ng kakayahang magamit at inalis ang downtime sa panahon ng pag-deploy.

Kung magpasya kang i-query ang database upang subukan ang kahandaan ng iyong aplikasyon, siguraduhing ito ay mura hangga't maaari. Kunin natin ang kahilingang ito:

SELECT small_item FROM table LIMIT 1

Narito ang isang halimbawa kung paano namin i-configure ang dalawang value na ito sa Kubernetes:

livenessProbe: 
 httpGet:   
   path: /api/liveness    
   port: http 
readinessProbe:  
 httpGet:    
   path: /api/readiness    
   port: http  periodSeconds: 2

Maaari kang magdagdag ng ilang karagdagang mga opsyon sa pagsasaayos:

  • initialDelaySeconds β€” ilang segundo ang lilipas sa pagitan ng paglulunsad ng lalagyan at pagsisimula ng mga sample.
  • periodSeconds β€” agwat ng paghihintay sa pagitan ng mga sample run.
  • timeoutSeconds β€” ang bilang ng mga segundo pagkatapos kung saan ang unit ay itinuturing na isang emergency. Regular na timeout.
  • failureThreshold β€” ang bilang ng mga pagsubok na nabigo bago ang isang restart signal ay ipinadala sa pod.
  • successThreshold β€” ang bilang ng mga matagumpay na probe bago ang pod ay pumasok sa handa na estado (pagkatapos ng isang pagkabigo, kapag ang pod ay nagsimula o nakabawi).

Ikatlong hakbang: pag-set up ng mga default na patakaran sa network para sa pod

Ang Kubernetes ay may "flat" na topograpiya ng network; bilang default, lahat ng pod ay direktang nakikipag-ugnayan sa isa't isa. Sa ilang mga kaso ito ay hindi kanais-nais.

Ang isang potensyal na isyu sa seguridad ay ang isang umaatake ay maaaring gumamit ng isang masusugatan na application upang magpadala ng trapiko sa lahat ng mga pod sa network. Tulad ng maraming lugar ng seguridad, ang prinsipyo ng hindi bababa sa pribilehiyo ay nalalapat dito. Sa isip, dapat na tahasang tukuyin ng mga patakaran ng network kung aling mga koneksyon sa pagitan ng mga pod ang pinapayagan at alin ang hindi.

Halimbawa, sa ibaba ay isang simpleng patakaran na tinatanggihan ang lahat ng papasok na trapiko para sa isang partikular na namespace:

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:  
 name: default-deny-ingress
spec:  
 podSelector: {}  
 policyTypes:  
   - Ingress

Visualization ng configuration na ito:

Limang hindi nakuha kapag nagde-deploy ng unang application sa Kubernetes
(https://miro.medium.com/max/875/1*-eiVw43azgzYzyN1th7cZg.gif)
Higit pang mga detalye dito.

Hakbang apat: custom na gawi gamit ang mga hook at init container

Isa sa aming mga pangunahing layunin ay magbigay ng mga deployment sa Kubernetes nang walang downtime para sa mga developer. Mahirap ito dahil maraming mga opsyon para sa pag-shut down ng mga application at pagpapalaya sa mga mapagkukunang ginamit nila.

Ang mga partikular na paghihirap ay lumitaw sa Nginx. Napansin namin na kapag ang mga pod na ito ay na-deploy nang sunud-sunod, ang mga aktibong koneksyon ay ibinaba bago matagumpay na makumpleto.

Pagkatapos ng malawak na pananaliksik online, lumalabas na hindi hinihintay ng Kubernetes ang mga koneksyon ng Nginx na maubos ang sarili bago wakasan ang pod. Gamit ang isang pre-stop hook, ipinatupad namin ang sumusunod na functionality at ganap na inalis ang downtime:

lifecycle: 
 preStop:
   exec:
     command: ["/usr/local/bin/nginx-killer.sh"]

Pero nginx-killer.sh:

#!/bin/bash
sleep 3
PID=$(cat /run/nginx.pid)
nginx -s quit
while [ -d /proc/$PID ]; do
   echo "Waiting while shutting down nginx..."
   sleep 10
done

Ang isa pang lubhang kapaki-pakinabang na paradigma ay ang paggamit ng mga lalagyan ng init upang mahawakan ang pagsisimula ng mga partikular na application. Ito ay lalong kapaki-pakinabang kung mayroon kang proseso ng paglilipat ng database na masinsinan sa mapagkukunan na kailangang tumakbo bago magsimula ang application. Maaari ka ring tumukoy ng mas mataas na limitasyon sa mapagkukunan para sa prosesong ito nang hindi nagtatakda ng naturang limitasyon para sa pangunahing aplikasyon.

Ang isa pang karaniwang pamamaraan ay ang pag-access ng mga lihim sa isang lalagyan ng init na nagbibigay ng mga kredensyal na iyon sa pangunahing module, na pumipigil sa hindi awtorisadong pag-access sa mga lihim mula sa mismong pangunahing module ng application.

Gaya ng dati, quote mula sa dokumentasyon: Ligtas na nagpapatakbo ang mga Init container ng custom na code o mga utility na kung hindi man ay makakabawas sa seguridad ng imahe ng container ng application. Sa pamamagitan ng paghiwalay ng mga hindi kinakailangang tool, nililimitahan mo ang ibabaw ng pag-atake ng larawan ng container ng application.

Ikalimang Hakbang: Pag-configure ng Kernel

Sa wakas, pag-usapan natin ang isang mas advanced na pamamaraan.

Ang Kubernetes ay isang napaka-flexible na platform na hinahayaan kang magpatakbo ng mga workload sa paraang nakikita mong akma. Mayroon kaming ilang mga application na may mataas na pagganap na lubhang masinsinang mapagkukunan. Pagkatapos magsagawa ng malawakang pagsusuri sa pagkarga, natuklasan namin na ang isang application ay nahihirapang pangasiwaan ang inaasahang pagkarga ng trapiko kapag ang mga default na setting ng Kubernetes ay may bisa.

Gayunpaman, pinapayagan ka ng Kubernetes na magpatakbo ng isang privileged container na nagbabago ng mga parameter ng kernel para lang sa isang partikular na pod. Narito ang ginamit namin upang baguhin ang maximum na bilang ng mga bukas na koneksyon:

initContainers:
  - name: sysctl
     image: alpine:3.10
     securityContext:
         privileged: true
      command: ['sh', '-c', "sysctl -w net.core.somaxconn=32768"]

Ito ay isang mas advanced na pamamaraan na kadalasang hindi kinakailangan. Ngunit kung ang iyong aplikasyon ay nahihirapang makayanan ang mabigat na pagkarga, maaari mong subukang i-tweak ang ilan sa mga setting na ito. Higit pang mga detalye sa prosesong ito at pagtatakda ng iba't ibang mga halaga - gaya ng dati sa opisyal na dokumentasyon.

Sa pagtatapos

Bagama't ang Kubernetes ay maaaring mukhang isang handa na solusyon sa labas ng kahon, may ilang mahahalagang hakbang na kailangan mong gawin upang mapanatiling maayos ang iyong mga application.

Sa kabuuan ng iyong paglilipat sa Kubernetes, mahalagang sundin ang "cycle ng pag-load ng pagsubok": ilunsad ang application, i-load ang pagsubok dito, obserbahan ang mga sukatan at gawi sa pag-scale, isaayos ang configuration batay sa data na iyon, pagkatapos ay ulitin muli ang cycle.

Maging makatotohanan tungkol sa iyong inaasahang trapiko at subukang lumampas dito upang makita kung aling mga bahagi ang unang masira. Gamit ang umuulit na diskarteng ito, ilan lamang sa mga nakalistang rekomendasyon ang maaaring sapat upang makamit ang tagumpay. O maaaring mangailangan ito ng mas malalim na pagpapasadya.

Palaging itanong sa iyong sarili ang mga tanong na ito:

  1. Gaano karaming mga mapagkukunan ang ginagamit ng mga application at paano magbabago ang volume na ito?
  2. Ano ang mga tunay na kinakailangan sa pag-scale? Gaano karaming trapiko ang hahawakan ng app sa karaniwan? Paano naman ang peak traffic?
  3. Gaano kadalas kailangang i-scale nang pahalang ang serbisyo? Gaano kabilis kailangang dalhin ang mga bagong pod online para makatanggap ng trapiko?
  4. Gaano katama ang pagsara ng mga pod? Ito ba ay kailangan sa lahat? Posible bang makamit ang deployment nang walang downtime?
  5. Paano mo mababawasan ang mga panganib sa seguridad at malimitahan ang pinsala mula sa anumang mga nakompromisong pod? May mga pahintulot o access ba ang anumang mga serbisyo na hindi nila kailangan?

Nagbibigay ang Kubernetes ng hindi kapani-paniwalang platform na nagbibigay-daan sa iyong gamitin ang pinakamahuhusay na kagawian para sa pag-deploy ng libu-libong serbisyo sa isang cluster. Gayunpaman, ang bawat aplikasyon ay naiiba. Minsan ang pagpapatupad ay nangangailangan ng kaunting trabaho.

Sa kabutihang palad, ang Kubernetes ay nagbibigay ng kinakailangang pagsasaayos upang makamit ang lahat ng mga teknikal na layunin. Gamit ang kumbinasyon ng mga kahilingan at limitasyon ng mapagkukunan, Liveness at Readiness probe, init container, mga patakaran sa network, at custom na kernel tuning, makakamit mo ang mataas na performance kasama ng fault tolerance at mabilis na scalability.

Ano pa ang dapat basahin:

  1. Pinakamahuhusay na kagawian at pinakamahuhusay na kagawian para sa pagpapatakbo ng mga container at Kubernetes sa mga kapaligiran ng produksyon.
  2. 90+ kapaki-pakinabang na tool para sa Kubernetes: deployment, pamamahala, pagsubaybay, seguridad at higit pa.
  3. Ang aming channel sa Paikot ng Kubernetes sa Telegram.

Pinagmulan: www.habr.com

Magdagdag ng komento