Plaaslike lêers wanneer 'n toepassing na Kubernetes migreer

Plaaslike lêers wanneer 'n toepassing na Kubernetes migreer

Wanneer 'n CI/CD-proses met Kubernetes gebou word, ontstaan ​​soms die probleem van onversoenbaarheid tussen die vereistes van die nuwe infrastruktuur en die toepassing wat daarna oorgedra word. In die besonder, by die aansoek bou stadium is dit belangrik om te kry 1 beeld wat in gebruik sal word alle projekomgewings en -klusters. Hierdie beginsel onderlê die korrekte volgens Google houerbestuur (meer as een keer hieroor hy het gesê en ons tegniese afdeling).

U sal egter niemand sien in situasies waar die werf se kode 'n klaargemaakte raamwerk gebruik, waarvan die gebruik beperkings op die verdere gebruik daarvan plaas nie. En hoewel dit in 'n "normale omgewing" maklik is om te hanteer, kan hierdie gedrag in Kubernetes 'n probleem word, veral wanneer jy dit vir die eerste keer teëkom. Terwyl 'n vindingryke gees vorendag kan kom met infrastruktuuroplossings wat met die eerste oogopslag ooglopend of selfs goed lyk ... is dit belangrik om te onthou dat die meeste situasies kan en moet argitektonies opgelos word.

Kom ons kyk na gewilde oplossings vir die stoor van lêers wat tot onaangename gevolge kan lei wanneer 'n groepering bestuur word, en wys ook 'n meer korrekte pad uit.

Statiese berging

Ter illustrasie, oorweeg 'n webtoepassing wat 'n soort statiese kragopwekker gebruik om 'n stel beelde, style en ander dinge te verkry. Byvoorbeeld, die Yii PHP-raamwerk het 'n ingeboude batebestuurder wat unieke gidsname genereer. Gevolglik is die uitset 'n stel paaie vir die statiese webwerf wat natuurlik nie met mekaar sny nie (dit is om verskeie redes gedoen - byvoorbeeld om duplikate uit te skakel wanneer dieselfde hulpbron deur baie komponente gebruik word). Dus, uit die boks, die eerste keer wat jy toegang tot 'n webhulpbronmodule kry, word statiese lêers (in werklikheid dikwels simlinks, maar meer daaroor later) gevorm en uiteengesit met 'n gemeenskaplike wortelgids wat uniek is vir hierdie ontplooiing:

  • webroot/assets/2072c2df/css/…
  • webroot/assets/2072c2df/images/…
  • webroot/assets/2072c2df/js/…

Wat beteken dit in terme van 'n groepering?

Die eenvoudigste voorbeeld

Kom ons neem 'n redelik algemene geval, wanneer PHP deur nginx voorafgegaan word om statiese data te versprei en eenvoudige versoeke te verwerk. Die maklikste manier - Ontplooiing met twee houers:

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.conf

In 'n vereenvoudigde vorm kom die nginx-konfigurasie op die volgende neer:

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;
        }
    }

Wanneer jy die eerste keer toegang tot die werf kry, verskyn bates in die PHP-houer. Maar in die geval van twee houers binne een peul, weet nginx niks van hierdie statiese lêers nie, wat (volgens die konfigurasie) aan hulle gegee moet word. As gevolg hiervan sal die kliënt 'n 404-fout sien vir alle versoeke na CSS- en JS-lêers. Die eenvoudigste oplossing hier sal wees om 'n gemeenskaplike gids vir houers te organiseer. Primitiewe opsie - algemeen 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.conf

Nou word statiese lêers wat in die houer gegenereer word, korrek deur nginx bedien. Maar laat ek jou daaraan herinner dat dit 'n primitiewe oplossing is, wat beteken dit is ver van ideaal en het sy eie nuanses en tekortkominge, wat hieronder bespreek word.

Meer gevorderde berging

Stel jou nou 'n situasie voor waar 'n gebruiker die webwerf besoek het, 'n bladsy gelaai het met die style wat in die houer beskikbaar is, en terwyl hy hierdie bladsy lees, het ons die houer herontplooi. Die bateskatalogus het leeg geword en 'n versoek aan PHP word vereis om nuwes te begin genereer. Selfs hierna sal skakels na ou staties egter irrelevant wees, wat sal lei tot foute in die vertoon van staties.

Daarbenewens het ons heel waarskynlik 'n min of meer gelaaide projek, wat beteken dat een kopie van die aansoek nie genoeg sal wees nie:

  • Kom ons skaal dit op Ontplooiing tot twee replikas.
  • Toe die webwerf die eerste keer verkry is, is bates in een replika geskep.
  • Op 'n stadium het ingress besluit (vir lasbalanseringsdoeleindes) om 'n versoek na die tweede replika te stuur, en hierdie bates was nog nie daar nie. Of dalk is hulle nie meer daar nie, want ons gebruik RollingUpdate en op die oomblik is ons besig met ontplooiing.

Oor die algemeen is die resultaat weer foute.

Om te verhoed dat u ou bates verloor, kan u verander emptyDir op hostPath, wat staties fisies by 'n groepknoop voeg. Hierdie benadering is sleg, want ons moet eintlik bind aan 'n spesifieke groepknoop jou toepassing, want - in die geval van skuif na ander nodusse - die gids nie die nodige lêers sal bevat nie. Of 'n soort agtergrondgidssinchronisasie tussen nodusse word vereis.

Wat is die oplossings?

  1. As hardeware en hulpbronne dit toelaat, kan jy dit gebruik cephfs om 'n ewe toeganklike gids vir statiese behoeftes te organiseer. Amptelike dokumentasie beveel SSD-aandrywers aan, ten minste drievoudige replikasie en 'n stabiele "dik" verbinding tussen cluster nodusse.
  2. 'n Minder veeleisende opsie sou wees om 'n NFS-bediener te organiseer. U moet egter die moontlike toename in reaksietyd vir die verwerking van versoeke deur die webbediener in ag neem, en fouttoleransie sal veel te wense oorlaat. Die gevolge van mislukking is katastrofies: die verlies van die berg verdoem die groep tot die dood onder die druk van die LA-vrag wat die lug instorm.

Onder andere sal alle opsies vir die skep van aanhoudende berging vereis word agtergrond skoonmaak verouderde stelle lêers wat oor 'n sekere tydperk opgehoop is. Voor houers met PHP kan jy sit DaemonSet van kas nginx, wat kopieë van bates vir 'n beperkte tyd sal stoor. Hierdie gedrag is maklik konfigureerbaar met behulp van proxy_cache met stoordiepte in dae of gigagrepe skyfspasie.

Die kombinasie van hierdie metode met die verspreide lêerstelsels wat hierbo genoem is, bied 'n groot veld vir verbeelding, slegs beperk deur die begroting en tegniese potensiaal van diegene wat dit sal implementeer en ondersteun. Uit ondervinding kan ons sê dat hoe eenvoudiger die stelsel is, hoe stabieler werk dit. Wanneer sulke lae bygevoeg word, word dit baie moeiliker om die infrastruktuur in stand te hou, en terselfdertyd neem die tyd wat spandeer word aan die diagnose en herstel van enige mislukkings toe.

aanbeveling

As die implementering van die voorgestelde bergingsopsies ook vir jou ongeregverdig lyk (ingewikkeld, duur ...), dan is dit die moeite werd om na die situasie van die ander kant af te kyk. Naamlik om te delf in die projek argitektuur en los die probleem in die kode op, gekoppel aan een of ander statiese datastruktuur in die beeld, 'n ondubbelsinnige definisie van die inhoud of prosedure vir "opwarming" en/of voorafsamestelling van bates tydens die beeldsamestellingstadium. Op hierdie manier kry ons absoluut voorspelbare gedrag en dieselfde stel lêers vir alle omgewings en replikas van die lopende toepassing.

As ons terugkeer na die spesifieke voorbeeld met die Yii-raamwerk en nie in die struktuur daarvan delf nie (wat nie die doel van die artikel is nie), is dit genoeg om twee gewilde benaderings uit te wys:

  1. Verander die beeldbouproses om bates op 'n voorspelbare plek te plaas. Dit word voorgestel/geïmplementeer in uitbreidings soos yii2-statiese-bates.
  2. Definieer spesifieke hashes vir bategidse, soos bespreek in bv. hierdie aanbieding (begin vanaf skyfie nr. 35). Terloops, die skrywer van die verslag beveel uiteindelik (en nie sonder rede nie!) aan dat nadat jy bates op die boubediener bymekaargemaak het, dit oplaai na 'n sentrale berging (soos S3), voor wat 'n CDN plaas.

Aflaaie

Nog 'n geval wat beslis ter sprake sal kom wanneer 'n toepassing na 'n Kubernetes-kluster migreer, is die berging van gebruikerlêers in die lêerstelsel. Ons het byvoorbeeld weer 'n PHP-toepassing wat lêers deur 'n oplaaivorm aanvaar, iets daarmee doen tydens operasie en dit terugstuur.

In Kubernetes moet die ligging waar hierdie lêers geplaas moet word, algemeen wees vir alle replikas van die toepassing. Afhangende van die kompleksiteit van die toepassing en die behoefte om die volharding van hierdie lêers te organiseer, kan die bogenoemde gedeelde toestelopsies so 'n plek wees, maar, soos ons sien, het hulle hul nadele.

aanbeveling

Een oplossing is gebruik S3-versoenbare berging (selfs al is dit 'n soort kategorie wat self aangebied word, soos minio). Om oor te skakel na S3 sal veranderinge vereis op kodevlak, en hoe inhoud aan die voorkant gelewer sal word, het ons reeds писали.

Gebruiker sessies

Afsonderlik is dit die moeite werd om te let op die organisasie van berging van gebruikerssessies. Dikwels is dit ook lêers op skyf, wat in die konteks van Kubernetes tot konstante magtigingsversoeke van die gebruiker sal lei as sy versoek in 'n ander houer beland.

Die probleem word gedeeltelik opgelos deur aan te skakel stickySessions op ingang (die kenmerk word ondersteun in alle gewilde ingangsbeheerders - vir meer besonderhede, sien ons resensie)om die gebruiker met die toepassing aan 'n spesifieke pod te bind:

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: /

Maar dit sal nie probleme met herhaalde ontplooiings uitskakel nie.

aanbeveling

'n Meer korrekte manier sal wees om die aansoek na stoor sessies in memcached, Redis en soortgelyke oplossings - in die algemeen, heeltemal laat vaar lêer opsies.

Gevolgtrekking

Die infrastruktuuroplossings wat in die teks bespreek word, is slegs waardig om te gebruik in die formaat van tydelike “krukke” (wat in Engels mooier klink as oplossing). Hulle kan relevant wees in die eerste stadiums van die migreer van 'n toepassing na Kubernetes, maar behoort nie wortel te skiet nie.

Die algemene aanbevole pad is om van hulle ontslae te raak ten gunste van argitektoniese wysiging van die toepassing in ooreenstemming met wat reeds aan baie bekend is 12-faktor-toepassing. Dit - om die aansoek na 'n staatlose vorm te bring - beteken egter onvermydelik dat veranderinge in die kode vereis sal word, en hier is dit belangrik om 'n balans te vind tussen die vermoëns/vereistes van die besigheid en die vooruitsigte vir die implementering en instandhouding van die gekose pad .

PS

Lees ook op ons blog:

Bron: will.com

Voeg 'n opmerking