
CI/CD protsessi loomisel Kubernetesega võib tekkida probleem, kus uue infrastruktuuri nõudmised ja sinna kantav rakendus ei ühti. Eelkõige on rakenduse ehitamise etapis oluline saada ühe pildi, mida kasutatakse kõikides keskkondades ja projekti klastrites. Selline põhimõte on õige Google'i arvates konteinerihalduse (pole sellest kunagi varem Kuid ei ole haruldane kohtuda olukordadega, kus saidi koodis kasutatakse valmis raamistiku, mille kasutamine toob kaasa piiranguid edasisele kasutamisele. Ja kui "tavakeskkonnas" on sellega lihtne toime tulla, siis Kuberneteses võib selline käitumine muutuda probleemiks, eriti kui kohtad seda esmakordselt. Kuigi leidlik meel suudab pakkuda infrastruktuuri lahendusi, mis näivad esmapilgul ilmsed ja isegi head ... on oluline meeles pidada, et enamik olukordi võib ja peab olema
Siiski ei näe sa kedagi olukordades, kus veebikoodis kasutatakse valmis raamistiku, mille kasutamine seab piiranguid selle edasisele kasutamisele. Kui "tavalises keskkonnas" on sellega lihtne toime tulla, siis Kuberneteses võib selline käitumine muutuda probleemiks, eriti kui kohtub sellega esmakordselt. Kuigi leidlik meel suudab pakkuda infrastruktuuri lahendusi, mis tunduvad esmapilgul ilmselged ja isegi head… on oluline meeles pidada, et enamik olukordi võivad ja peavad lahendatud arhitektuuriliselt.
Käime läbi populaarsed workaround-lahendused failide hoidmiseks, mis võivad põhjustada ebameeldivaid tagajärgi klastrite kasutamisel, ja näitame üles õigemad teed.
Statika hoidmine
Kujutame ette veebirakendust, mis kasutab mingit staatika genereerijat piltide, stiilide ja muu komplekti saamiseks. Näiteks PHP-raamistikus Yii on sisseehitatud varade haldur, mis genereerib unikaalsed kaustade nimetused. Seega saadakse väljastusena kogum omavahel mittetükkivad teed saidi staatikale (see on tehtud mitmel põhjusel — näiteks, et välistada dubleeritud ressursid, mida kasutavad mitmed komponendid). Nii et välja peal, esimesel pöördumisel veebiresursi mooduli poole toimub staatika genereerimine ja paigutamine (tõenäoliselt sümlinkide, kuid sellest hiljem) unikaalse juurkaustaga selle versiooni jaoks:
-
webroot/assets/2072c2df/css/… -
webroot/assets/2072c2df/images/… -
webroot/assets/2072c2df/js/…
Millised on selle tagajärjed klastrite osas?
Lihtsaim näide
Võtame üsna levinud juhtumi, kus PHP ees on nginx staatika serveerimiseks ja lihtsate päringute töötlemiseks. Kõige lihtsam viis on Deployment kaks konteinerit:
apiVersion: apps/v1
kind: Deployment
metadata:
name: site
spec:
selector:
matchLabels:
component: backend
template:
metadata:
labels:
component: backend
spec:
volumes:
- name: nginx-config
configMap:
name: nginx-configmap
containers:
- name: php
image: own-image-with-php-backend:v1.0
command: ["/usr/local/sbin/php-fpm","-F"]
workingDir: /var/www
- name: nginx
image: nginx:1.16.0
command: ["/usr/sbin/nginx", "-g", "daemon off;"]
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: nginx.confLihtsustatud kujul koondub nginx konfiguratsioon järgmisele:
apiVersion: v1
kind: ConfigMap
metadata:
name: "nginx-configmap"
data:
nginx.conf: |
server {
listen 80;
server_name _;
charset utf-8;
root /var/www;
access_log /dev/stdout;
error_log /dev/stderr;
location / {
index index.php;
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
} Esimese korral, kui külastatakse PHP konteineris asuvat saiti, kuvatakse varad. Kuid kahe konteineri puhul ühe pod'i raames ei tea nginx neist staatilistest failidest midagi, mis (vastavalt konfiguratsioonile) peaks just neile edastatama. Tulemuseks on see, et kõikidele CSS- ja JS-failide päringutele näeb klient viga 404. Lihtsaim lahendus oleks korraldada konteineritele ühine direktorium. Primitiivne variant — ühine. emptyDir:
apiVersion: apps/v1
kind: Deployment
metadata:
name: site
spec:
selector:
matchLabels:
component: backend
template:
metadata:
labels:
component: backend
spec:
volumes:
- name: assets
emptyDir: {}
- name: nginx-config
configMap:
name: nginx-configmap
containers:
- name: php
image: own-image-with-php-backend:v1.0
command: ["/usr/local/sbin/php-fpm","-F"]
workingDir: /var/www
volumeMounts:
- name: assets
mountPath: /var/www/assets
- name: nginx
image: nginx:1.16.0
command: ["/usr/sbin/nginx", "-g", "daemon off;"]
volumeMounts:
- name: assets
mountPath: /var/www/assets
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: nginx.confNüüd edastab nginx konteineris genereeritud staatilised failid õigesti. Kuid tuletan meelde, et see on primitiivne lahendus, mis tähendab, et see on kaugel ideest ning sellel on oma nüansid ja puudused, millest allpool räägin.
Täpsem salvestus
Kujutage nüüd olukorda, kus kasutaja on veebilehel, on laadinud lehe, mis sisaldab konteineris olevaid stiile, ja samal ajal, kui ta seda lehte loeb, oleme konteineri uuesti välja deployinud. Varade kataloog on tühi ja vajame PHP päringut uute genereerimiseks. Kuid isegi pärast seda on vanad staatilised lingid ebatäpsed, mis toob kaasa staatika kuvamise vead.
Lisaks on tõenäoliselt tegemist suhteliselt suure projekti, mis tähendab, et ühekordne rakendus ei piisa:
- Suurendame Deployment kuni kahte koopiat.
- Esimese külastuse ajal ühe koopiaga loodi varad.
- Mingil hetkel otsustas ingress (koormuse tasakaalustamise eesmärgil) saata päringu teisele koopiale, ja seal pole neid varasid veel. Võib-olla ei ole neid seal enam, sest kasutame
RollingUpdateja praegu teeme deployd.
Kokkuvõttes — jälle vead.
Vanade varade kaotamise vältimiseks saab muuta emptyDir järgnevaga hostPath, ladustades staatikat füüsiliselt klastrite sõlme. See lähenemine on halb, sest me peame tegelikult seonduma konkreetse klastrite sõlmega oma rakendusega, kuna — kui kolitakse teistesse sõlmedesse — ei sisalda kataloog vajalikke faile. Vastasel juhul on vajalik teatud taustasünkroonimine katalooge vahel sõlmede.
Millised on lahenduste võimalused?
- Kui riistvara ja ressursid seda võimaldavad, võib kasutada statiiliste vajaduste jaoks ühtse juurdepääsuga katalooge korraldamiseks. soovitab SSD-ketasid, vähemalt kolmekordset replikatsiooni ja stabiilset "paksu" ühendust kahe sõlme vahel klastris.
- Vähem nõudlik variant on NFS-serveri korraldamine. Siiski tuleb arvesse võtta võimalikku vastuse ajahüpet veebiserveri päringute töötlemisel, ning ka tõrkekindlus ei jää palju soovida. Tõrke tagajärjed on katastroofilised: mount'i kadumine viib klastrisse hävinguni koormuse LA all, mis tõuseb taevasse.
Peale selle on kõigi alalise salvestamise loomise variantide jaoks vajalik taustapuhastus aegunud failikomplektide, mis on kogunenud teatud aja jooksul. PHP konteinerite ette võib seada DaemonSet nginx'i vahemälu, mis hoiab koopiat vara piiratud aja. Seda käitumist on lihtne seadistada koos proxy_cache päevade või gigabaitide salvestusruumi sügavusega.
Selle meetodi ühendamine eespool mainitud jagatud failisüsteemidega annab tohutult võimalusi, ainus piirang on eelarve ja tehniline potentsiaal nende teostajate ja hoidjate seas. Kogemuste põhjal võib öelda, et mida lihtsam on süsteem, seda stabiilsem see töötab. Kui selliseid kihte lisada, muutub infrastruktuuri hooldamine palju keerukamaks ja sellega koos suureneb ka ajaline kulu diagnostikale ja taastamisele igasuguste tõrgete korral.
Soovitus
Kui pakutud salvestusvõimaluste rakendamine tundub teile samuti ebamugav (keeruline, kallis...), siis tasub vaadata olukorda teisest küljest. Nimelt - kaevuda projekti arhitektuuri ja kaotada probleem koodis, seondades mõnedele staatilistele andmestruktuuridele pildis, ühemõtteline sisu või „soojendamise“ ja / või ressursside eelkompileerimise protseduurid pildi ehitamise etapis. Nii saame täiesti ennustatavat käitumist ja ühesuguse failide kogumi kõigis keskkondades ja rakenduse replikates.
Kui minna tagasi konkreetse näite juurde Yii raamistikuga ja mitte süveneda selle struktuuri (mis ei ole artikli eesmärk), piisab, kui märkida ära kaks populaarset lähenemist:
- Muuda pildi ehitusprotsessi nii, et asetada ressursid etteennustatavasse kohta. Nii soovitab / rakendab laiendustes nagu .
- Määrata konkreetseid hash'e ressursside kataloogidele, nagu on näiteks kirjeldatud (alates slaidist nr 35). Üksikasjalikult, et esituse autor soovitab, et pärast ressursside ehitamist ehitusserveris laadida need üles kesksetesse ladustamisse (nt S3), mille ees on CDN.
Üles laetavad failid
Teine juhtum, mis kindlasti toimib rakenduse Kubernetes klastrisse kolimisel, on kasutajafailide salvestamine failisüsteemis. Näiteks on meil taas PHP rakendus, mis võtab faile üleslaadimisvormi kaudu, teeb nende vormimise käigus midagi ja annab need tagasi.
Koht, kuhu need failid peaksid minema, peaks Kuberneteses olema kõigi rakenduse koopia jaoks ühine. Olenevalt rakenduse keerukusest ja vajadusest täiustatud failide korralduse järele, võivad sellised kohad olla eelmainitud shared-seadmed, kuid nagu näeme, on neil omad miinused.
Soovitus
Ühe lahendusena on S3-ühilduva salvestuse kasutamine (isegi kui mõni variant isehoidlast, nagu minio). Üleminek S3-le toob kaasa muudatusi kooditasandil, ja kuidas sisu edastatakse frontendi, on juba .
Kasutajaseansid
Eraldi väärib mainimist kasutajaseansside salvestamise korraldus. Tihti on need samuti failid kettal, mis Kubernetesis toob kaasa pidevad autentimispäringud kasutajalt, kui tema päring jõuab teise konteinerisse.
Osaliselt lahendab probleemi kõigi seda aktiveerimise stickySessions ingressil (funktsioon on toetatud kõigis populaarsetes ingressi kontrollerites — lisateavet leiate ), et siduda kasutaja konkreetse rakenduse pod'iga:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-test
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
rules:
- host: stickyingress.example.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /Kuid see ei vabasta korduvate väljalasetega seotud probleemidest.
Soovitus
Õigem lähenemine oleks rakenduse üleviimine sessioonide salvestamiseks memcachedi, Redis ja sarnaste lahenduste kasutamisele — üldiselt loobuda täielikult failipõhisest lähenemisest.
Kokkuvõte
Tööstuses arutletud infrastruktuuri lahendused sobivad rakendamiseks ainult ajutiste "toetuste" vormis. Need võivad olla asjakohased rakenduse migratsiooni varastes etappides Kubernetesesse, kuid ei peaks "juurduma".
Soovitatav tee on neist loobuda rakenduse arhitektuuri kohandamise kasuks, järgides juba paljudele tuntud põhimõtteid. . Siiski tähendab rakenduse viimine stateless vormi, et koodis on vajalikud muudatused, ning siin on oluline leida tasakaal äri võimaluste/nõudmiste ja valitud tee elluviimise ning hooldamise perspektiivide vahel.
P.S.
Lugege ka meie blogist:
- «»;
- «»;
- «» (Red Hati poolt);
- «».
Allikas: habr.com
