Vietējie faili, migrējot lietojumprogrammu uz Kubernetes

Vietējie faili, migrējot lietojumprogrammu uz Kubernetes

Veidojot CI/CD procesu, izmantojot Kubernetes, dažkārt rodas problēmas nesaderÄ«ba starp jaunās infrastruktÅ«ras prasÄ«bām un uz to pārsÅ«tÄ«to lietojumprogrammu. Jo Ä«paÅ”i lietojumprogrammas izveides stadijā ir svarÄ«gi iegÅ«t viens attēls, kas tiks izmantots viss projektu vides un klasteri. Å is princips ir pareizā pamatā saskaņā ar Google konteineru pārvaldÄ«ba (vairāk nekā vienu reizi par to teica un mÅ«su tehniskajā nodaļā).

Tomēr jÅ«s neredzēsit nevienu situācijās, kad vietnes kods izmanto gatavu ietvaru, kura izmantoÅ”ana ierobežo tās turpmāko izmantoÅ”anu. Un, lai gan ā€œnormālā vidēā€ ar to ir viegli tikt galā, Kubernetes Ŕī uzvedÄ«ba var kļūt par problēmu, it Ä«paÅ”i, ja ar to saskaraties pirmo reizi. Lai gan atjautÄ«gs prāts var nākt klajā ar infrastruktÅ«ras risinājumiem, kas pirmajā mirklÄ« Ŕķiet paÅ”saprotami vai pat labi... ir svarÄ«gi atcerēties, ka vairums situāciju var un vajag jāatrisina arhitektoniski.

Apskatīsim populāros risinājumus failu glabāŔanai, kas var radīt nepatīkamas sekas, darbinot klasteru, kā arī norādīsim pareizāku ceļu.

Statiskā krātuve

Lai ilustrētu, apsveriet tÄ«mekļa lietojumprogrammu, kas izmanto sava veida statisko Ä£eneratoru, lai iegÅ«tu attēlu, stilu un citu lietu kopu. Piemēram, Yii PHP ietvarā ir iebÅ«vēts lÄ«dzekļu pārvaldnieks, kas Ä£enerē unikālus direktoriju nosaukumus. AttiecÄ«gi izvade ir statiskās vietnes acÄ«mredzami nekrustojoÅ”u ceļu kopa (tas tika darÄ«ts vairāku iemeslu dēļ - piemēram, lai novērstu dublikātus, ja vienu un to paÅ”u resursu izmanto vairāki komponenti). Tātad, pirmo reizi piekļūstot tÄ«mekļa resursu modulim, statiskie faili (patiesÄ«bā bieži vien simbolu saites, bet vairāk par to vēlāk) tiek izveidoti un izkārtoti ar kopÄ«gu saknes direktoriju, kas ir unikāls Å”ai izvietoÅ”anai:

  • webroot/assets/2072c2df/css/ā€¦
  • webroot/assets/2072c2df/images/ā€¦
  • webroot/assets/2072c2df/js/ā€¦

Ko tas nozīmē klastera izteiksmē?

VienkārŔākais piemērs

Ņemsim diezgan izplatÄ«tu gadÄ«jumu, kad statisko datu izplatÄ«Å”anai un vienkārÅ”u pieprasÄ«jumu apstrādei PHP priekŔā ir nginx. Vieglākais veids - IzvietoÅ”anas ar diviem konteineriem:

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

VienkārŔotā veidā nginx konfigurācija ir Ŕāda:

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

Kad pirmo reizi piekļūstat vietnei, lÄ«dzekļi tiek parādÄ«ti PHP konteinerā. Bet gadÄ«jumā, ja vienā podā ir divi konteineri, nginx neko nezina par Å”iem statiskajiem failiem, kuri (pēc konfigurācijas) viņiem bÅ«tu jāiedod. Rezultātā klients visiem pieprasÄ«jumiem uz CSS un JS failiem redzēs kļūdu 404. VienkārŔākais risinājums Å”eit bÅ«tu izveidot kopÄ«gu konteineru direktoriju. PrimitÄ«vs variants - vispārÄ«gs 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

Tagad nginx pareizi apkalpo konteinerā ģenerētos statiskos failus. Bet ļaujiet man atgādināt, ka tas ir primitīvs risinājums, kas nozīmē, ka tas ir tālu no ideāla un tam ir savas nianses un trūkumi, par kuriem mēs runāsim tālāk.

Uzlabota krātuve

Tagad iedomājieties situāciju, kad lietotājs apmeklēja vietni, ielādēja lapu ar konteinerā pieejamajiem stiliem un, kamēr viņŔ lasÄ«ja Å”o lapu, mēs atkārtoti izvietojām konteineru. AktÄ«vu katalogs ir kļuvis tukÅ”s, un ir nepiecieÅ”ams pieprasÄ«jums PHP, lai sāktu Ä£enerēt jaunus. Tomēr pat pēc tam saitēm uz veco statiku nebÅ«s nozÄ«mes, kas radÄ«s kļūdas statikas attēloÅ”anā.

Turklāt mums, visticamāk, ir vairāk vai mazāk ielādēts projekts, kas nozīmē, ka ar vienu aplikācijas eksemplāru nepietiks:

  • Palielināsim to mērogu IzvietoÅ”anas lÄ«dz divām replikām.
  • Pirmoreiz piekļūstot vietnei, lÄ«dzekļi tika izveidoti vienā replikā.
  • Kādā brÄ«dÄ« ingress nolēma (slodzes lÄ«dzsvaroÅ”anas nolÅ«kos) nosÅ«tÄ«t pieprasÄ«jumu otrajai kopijai, un Å”ie lÄ«dzekļi tur vēl nebija. Vai varbÅ«t to vairs nav, jo mēs lietojam RollingUpdate un Å”obrÄ«d mēs veicam izvietoÅ”anu.

Kopumā rezultāts atkal ir kļūdas.

Lai nezaudētu vecos lÄ«dzekļus, varat mainÄ«t emptyDir par hostPath, fiziski pievienojot klastera mezglam statisku. Å Ä« pieeja ir slikta, jo mums tas patiesÄ«bā ir jādara saistÄ«ties ar konkrētu klastera mezglu savu lietojumprogrammu, jo - pārejas uz citiem mezgliem gadÄ«jumā - direktorijā nebÅ«s nepiecieÅ”amie faili. Vai arÄ« ir nepiecieÅ”ama kāda veida fona direktoriju sinhronizācija starp mezgliem.

Kādi ir risinājumi?

  1. Ja aparatÅ«ra un resursi atļauj, varat izmantot cephfs organizēt vienlÄ«dz pieejamu direktoriju statiskām vajadzÄ«bām. Oficiālā dokumentācija iesaka SSD diskus, vismaz trÄ«skārÅ”u replikāciju un stabilu ā€œbiezuā€ savienojumu starp klastera mezgliem.
  2. Mazāk prasÄ«ga iespēja bÅ«tu organizēt NFS serveri. Tomēr tad jums ir jāņem vērā iespējamais atbildes laika palielinājums tÄ«mekļa servera pieprasÄ«jumu apstrādei, un kļūdu tolerance atstās daudz vēlamo. Neveiksmes sekas ir katastrofālas: kalna zaudÄ“Å”ana nolemj kopu lÄ«dz nāvei zem debesÄ«s steidzÄ«gās LA slodzes spiediena.

Cita starpā bÅ«s nepiecieÅ”amas visas pastāvÄ«gas krātuves izveides iespējas fona tÄ«rÄ«Å”ana novecojuÅ”as failu kopas, kas uzkrātas noteiktā laika periodā. PriekŔā konteinerus ar PHP var likt DaemonSet no keÅ”atmiņas saglabāŔanas nginx, kurā ierobežotu laiku tiks glabātas lÄ«dzekļu kopijas. Å o darbÄ«bu var viegli konfigurēt, izmantojot proxy_cache ar uzglabāŔanas dziļumu dienās vai gigabaitos diska vietas.

Å Ä«s metodes apvienoÅ”ana ar iepriekÅ” minētajām izplatÄ«tajām failu sistēmām nodroÅ”ina milzÄ«gu iztēles lauku, ko ierobežo tikai to cilvēku budžets un tehniskais potenciāls, kuri to ieviesÄ«s un atbalstÄ«s. No pieredzes mēs varam teikt, ka jo vienkārŔāka sistēma, jo stabilāk tā darbojas. Pievienojot Ŕādus slāņus, kļūst daudz grÅ«tāk uzturēt infrastruktÅ«ru, un tajā paŔā laikā palielinās laiks, kas tiek patērēts diagnosticÄ“Å”anai un atveseļoÅ”anai pēc jebkādām kļūmēm.

Ieteikums

Ja arÄ« piedāvāto uzglabāŔanas iespēju ievieÅ”ana tev Ŕķiet nepamatota (sarežģīta, dārga...), tad ir vērts paskatÄ«ties uz situāciju no citas puses. Proti, iedziļināties projekta arhitektÅ«rā un novērsiet problēmu kodā, kas ir saistÄ«ts ar kādu statisku datu struktÅ«ru attēlā, nepārprotama satura definÄ«cija vai procedÅ«ra ā€œiesildÄ«Å”anaiā€ un/vai lÄ«dzekļu iepriekŔējai kompilÄ“Å”anai attēla montÄ“Å”anas stadijā. Tādā veidā mēs iegÅ«stam absolÅ«ti paredzamu uzvedÄ«bu un vienādu failu kopu visām vidēm un darbojoŔās lietojumprogrammas replikām.

Ja atgriežamies pie konkrētā piemēra ar Yii ietvaru un neiedziļināmies tā struktūrā (kas nav raksta mērķis), pietiek norādīt uz divām populārām pieejām:

  1. Mainiet attēla veidoÅ”anas procesu, lai lÄ«dzekļus novietotu paredzamā vietā. Tas ir ieteikts/ieviests tādos paplaÅ”inājumos kā yii2-static-assets.
  2. Definējiet Ä«paÅ”us lÄ«dzekļu direktoriju jaucējus, kā aprakstÄ«ts piem. Ŕī prezentācija (sākot no slaida Nr. 35). Starp citu, ziņojuma autors galu galā (un ne bez iemesla!) iesaka pēc lÄ«dzekļu salikÅ”anas bÅ«vÄ“Å”anas serverÄ« augÅ”upielādēt tos centrālajā krātuvē (piemēram, S3), kuras priekŔā ievieto CDN.

Lejupielādējami faili

Vēl viens gadÄ«jums, kas noteikti parādÄ«sies, migrējot lietojumprogrammu uz Kubernetes klasteru, ir lietotāja failu glabāŔana failu sistēmā. Piemēram, mums atkal ir PHP lietojumprogramma, kas pieņem failus, izmantojot augÅ”upielādes veidlapu, kaut ko veic ar tiem darbÄ«bas laikā un nosÅ«ta tos atpakaļ.

Programmā Kubernetes vietai, kur Å”ie faili jānovieto, jābÅ«t kopējai visām lietojumprogrammas replikām. AtkarÄ«bā no lietojumprogrammas sarežģītÄ«bas un nepiecieÅ”amÄ«bas organizēt Å”o failu noturÄ«bu, iepriekÅ” minētās koplietotās ierÄ«ces opcijas var bÅ«t Ŕāda vieta, taču, kā redzam, tām ir savi trÅ«kumi.

Ieteikums

Viens risinājums ir izmantojot ar S3 saderÄ«gu krātuvi (pat ja tā ir sava veida paÅ”mitināta kategorija, piemēram, minio). Lai pārslēgtos uz S3, bÅ«s nepiecieÅ”amas izmaiņas koda lÄ«menÄ«, un to, kā saturs tiks piegādāts priekÅ”pusē, mēs jau esam sapratuÅ”i ŠæŠøсŠ°Š»Šø.

Lietotāju sesijas

AtseviŔķi ir vērts atzÄ«mēt lietotāju sesiju uzglabāŔanas organizÄ“Å”anu. Bieži vien tie ir arÄ« faili diskā, kas Kubernetes kontekstā novedÄ«s pie pastāvÄ«giem autorizācijas pieprasÄ«jumiem no lietotāja, ja viņa pieprasÄ«jums nonāk citā konteinerā.

Problēma daļēji tiek atrisināta, ieslēdzot stickySessions par iekļūŔanu (funkcija tiek atbalstÄ«ta visos populārajos ieejas kontrolleros ā€” sÄ«kāku informāciju skatiet mÅ«su pārskats)lai saistÄ«tu lietotāju ar noteiktu aplikāciju ar lietojumprogrammu:

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

Bet tas nenovērsÄ«s problēmas ar atkārtotu izvietoÅ”anu.

Ieteikums

Pareizāks veids būtu pārsūtīt pieteikumu uz sesiju glabāŔana memcached, Redis un līdzīgos risinājumos - kopumā pilnībā atsakieties no failu opcijām.

Secinājums

Tekstā aplÅ«kotie infrastruktÅ«ras risinājumi ir izmantoÅ”anas vērti tikai pagaidu ā€œkruÄ·uā€ formātā (kas angliski izklausās skaistāk kā risinājums). Tie var bÅ«t svarÄ«gi lietojumprogrammas migrÄ“Å”anas uz Kubernetes pirmajos posmos, taču tiem nevajadzētu iesakņoties.

Vispārējais ieteicamais ceļŔ ir atbrÄ«voties no tiem par labu lietojumprogrammas arhitektoniskām modifikācijām saskaņā ar daudziem jau labi zināmo. 12 faktoru lietotne. Taču tas ā€“ aplikācijas pārveÅ”ana uz bezvalstnieku formu ā€“ neizbēgami nozÄ«mē, ka bÅ«s nepiecieÅ”amas izmaiņas kodā, un Å”eit ir svarÄ«gi atrast lÄ«dzsvaru starp biznesa iespējām/prasÄ«bām un izredzēm ieviest un uzturēt izvēlēto ceļu. .

PS

Lasi arī mūsu emuārā:

Avots: www.habr.com

Pievieno komentāru