Helyi fájlok egy alkalmazás Kubernetes rendszerbe való migrálásakor

Helyi fájlok egy alkalmazás Kubernetes rendszerbe való migrálásakor

Amikor egy CI/CD folyamatot Kubernetes használatával építünk fel, néha az a probléma, hogy az új infrastruktúra és az arra átvitt alkalmazás követelményei nem kompatibilisek. Különösen az alkalmazásépítési szakaszban fontos megszerezni egy kép, amelyet használni fognak minden projektkörnyezetek és klaszterek. Ez az elv a helyes alapja a Google szerint konténerkezelés (erről többször is mondott és műszaki osztályunk).

Azonban senkit sem fog látni olyan helyzetekben, amikor az oldal kódja egy kész keretrendszert használ, amelynek használata korlátozza a további használatát. És bár egy „normál környezetben” ez könnyen kezelhető, a Kubernetesben ez a viselkedés problémát jelenthet, különösen akkor, ha először találkozik vele. Míg a találékony elme képes olyan infrastrukturális megoldásokat kitalálni, amelyek első pillantásra kézenfekvőnek vagy akár jónak tűnnek, fontos észben tartani, hogy a legtöbb helyzetben lehet és kell is. építészetileg kell megoldani.

Nézzük meg a fájlok tárolásának népszerű megkerülő megoldásait, amelyek kellemetlen következményekkel járhatnak egy fürt működtetésekor, és mutassunk rá egy helyesebb elérési utat.

Statikus tárolás

Szemléltetésképpen vegyünk fontolóra egy webalkalmazást, amely valamilyen statikus generátort használ a képek, stílusok és egyéb dolgok halmazának beszerzésére. Például a Yii PHP keretrendszer rendelkezik egy beépített eszközkezelővel, amely egyedi címtárneveket generál. Ennek megfelelően a kimenet a statikus hely útvonalainak halmaza, amelyek nyilvánvalóan nem metszik egymást (ez több okból is megtörtént - például a duplikációk kiküszöbölése érdekében, amikor több összetevő ugyanazt az erőforrást használja). Tehát, amikor először fér hozzá egy webes erőforrás modulhoz, a statikus fájlok (valójában gyakran szimbolikus hivatkozások, de erről később) jönnek létre, és egy közös gyökérkönyvtárral helyezkednek el, amely egyedi erre a telepítésre:

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

Mit jelent ez egy klaszter szempontjából?

A legegyszerűbb példa

Vegyünk egy meglehetősen gyakori esetet, amikor a PHP-t az nginx előzi meg statikus adatok terjesztésére és egyszerű kérések feldolgozására. A legegyszerűbb módja - bevetés két konténerrel:

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

Egyszerűsített formában az nginx konfigurációja a következőre csapódik le:

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

Amikor először lép fel a webhelyre, az eszközök megjelennek a PHP-tárolóban. De ha két konténer van egy podon belül, az nginx semmit sem tud ezekről a statikus fájlokról, amelyeket (a konfiguráció szerint) meg kell adni nekik. Ennek eredményeként a kliens 404-es hibát fog látni minden CSS- és JS-fájlra irányuló kérésnél.A legegyszerűbb megoldás itt az lenne, ha a konténerek számára közös könyvtárat szerveznénk. Primitív lehetőség - általános 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

Most a tárolóban generált statikus fájlokat az nginx megfelelően szolgálja ki. De hadd emlékeztessem önöket arra, hogy ez egy primitív megoldás, ami azt jelenti, hogy messze nem ideális, és megvannak a maga árnyalatai és hiányosságai, amelyeket az alábbiakban tárgyalunk.

Fejlettebb tárolás

Most képzeljünk el egy olyan helyzetet, amikor egy felhasználó felkereste a webhelyet, betöltött egy oldalt a tárolóban elérhető stílusokkal, és miközben ezt az oldalt olvasta, újra telepítettük a tárolót. Az eszközkatalógus kiürült, és kérni kell a PHP-t az újak generálásához. Azonban még ezután is a régi statikára mutató hivatkozások nem relevánsak, ami hibákhoz vezet a statika megjelenítésében.

Ezenkívül valószínűleg van egy többé-kevésbé betöltött projektünk, ami azt jelenti, hogy az alkalmazás egy példánya nem lesz elég:

  • Méretezzük fel bevetés legfeljebb két replika.
  • A webhely első elérésekor az eszközök egyetlen replikában jöttek létre.
  • Valamikor az ingress úgy döntött (terheléselosztás céljából), hogy kérelmet küld a második replikára, és ezek az eszközök még nem voltak ott. Vagy talán már nincsenek ott, mert használjuk RollingUpdate és jelenleg bevetést végzünk.

Általában az eredmény ismét hibák.

A régi eszközök elvesztésének elkerülése érdekében változtathat emptyDir on hostPath, statikus fizikai hozzáadása a fürt csomópontjához. Ez a megközelítés rossz, mert valójában muszáj kötődni egy adott fürtcsomóponthoz alkalmazását, mert - más csomópontokba költözés esetén - a könyvtár nem fogja tartalmazni a szükséges fájlokat. Vagy valamilyen háttérkönyvtár-szinkronizálás szükséges a csomópontok között.

Mik a megoldások?

  1. Ha a hardver és az erőforrások lehetővé teszik, használhatja cephfs hogy a statikus igényekhez egyformán hozzáférhető könyvtárat szervezzen. Hivatalos dokumentáció SSD-meghajtókat, legalább háromszoros replikációt és stabil „vastag” kapcsolatot ajánl a fürtcsomópontok között.
  2. Kevésbé igényes megoldás egy NFS-kiszolgáló megszervezése. Ekkor azonban figyelembe kell vennie a válaszidő esetleges növekedését a kérések webszerver általi feldolgozásakor, és a hibatűrés sok kívánnivalót hagy maga után. A kudarc következményei katasztrofálisak: a hegy elvesztése halálra ítéli a klasztert az égbe rohanó LA teher nyomása alatt.

Többek között az állandó tárhely létrehozásának minden lehetőségére szükség lesz háttér takarítás egy bizonyos idő alatt felhalmozott elavult fájlkészletek. A PHP-s konténerek elé rakhatod DaemonSet az nginx gyorsítótárazásából, amely korlátozott ideig tárolja az eszközök másolatait. Ez a viselkedés könnyen konfigurálható a használatával proxy_cache tárolási mélységgel napokban vagy gigabájt lemezterülettel.

Ennek a módszernek a fent említett elosztott fájlrendszerekkel való kombinálása hatalmas teret biztosít a képzelet számára, amelynek csak azoknak a költségvetése és technikai lehetőségei szab határt, akik megvalósítják és támogatják. Tapasztalatból elmondhatjuk, hogy minél egyszerűbb a rendszer, annál stabilabban működik. Ha ilyen rétegeket adunk hozzá, az infrastruktúra karbantartása sokkal nehezebbé válik, ugyanakkor megnövekszik az esetleges hibák diagnosztizálására és helyreállítására fordított idő.

ajánlás

Ha Önnek is indokolatlannak tűnik a javasolt tárolási lehetőségek megvalósítása (bonyolult, drága...), akkor érdemes a másik oldalról is szemlélni a helyzetet. Mégpedig beleásni a projekt architektúrába és javítsa ki a hibát a kódban, a kép valamilyen statikus adatszerkezetéhez kötve, a tartalom vagy eljárás egyértelmű meghatározása a „bemelegítés” és/vagy az eszközök előfordítása során a kép összeállítási szakaszában. Így abszolút kiszámítható viselkedést és ugyanazt a fájlkészletet kapjuk a futó alkalmazás minden környezetéhez és replikájához.

Ha visszatérünk a konkrét példához a Yii keretrendszerrel, és nem mélyedünk el a szerkezetében (ami nem a cikk célja), akkor elég két népszerű megközelítést kiemelni:

  1. Módosítsa a képalkotási folyamatot úgy, hogy az eszközöket előre látható helyen helyezze el. Ez olyan kiterjesztésekben javasolt/megvalósítható, mint pl yii2-static-assets.
  2. Határozzon meg konkrét kivonatokat az eszközkönyvtárak számára, amint azt pl. ezt a bemutatót (a 35. diáról indulva). A jelentés írója egyébként végső soron (és nem ok nélkül!) azt tanácsolja, hogy miután a build szerveren összeállítottuk az eszközöket, töltsük fel azokat egy központi tárhelyre (például az S3-ra), amely elé helyezzünk el egy CDN-t.

Letöltések

Egy másik eset, amely minden bizonnyal szóba jöhet egy alkalmazás Kubernetes-fürtre való migrálásakor, a felhasználói fájlok fájlrendszerben való tárolása. Például megint van egy PHP alkalmazásunk, amely feltöltési űrlapon keresztül fogad fájlokat, működés közben csinál velük valamit, és visszaküldi.

A Kubernetesben a fájlok elhelyezési helyének közösnek kell lennie az alkalmazás összes replikájánál. Az alkalmazás összetettségétől és a fájlok fennmaradásának megszervezésétől függően a fent említett megosztott eszközopciók lehetnek ilyen helyek, de, mint látjuk, megvannak a hátrányai.

ajánlás

Az egyik megoldás az S3-kompatibilis tárhely használatával (még akkor is, ha ez valamilyen önálló szolgáltató kategória, mint a minio). Az S3-ra való váltás változtatásokat igényel kód szintjén, és azt, hogy a tartalom hogyan fog megjelenni a kezelőfelületen, már megtudtuk писали.

Felhasználói munkamenetek

Külön érdemes megjegyezni a felhasználói munkamenetek tárolásának megszervezését. Gyakran ezek a lemezen lévő fájlok is, amelyek a Kubernetes kontextusában a felhasználó folyamatos engedélyezési kérelmeihez vezetnek, ha kérése egy másik tárolóba kerül.

A probléma részben megoldódik a bekapcsolással stickySessions behatoláskor (a funkciót minden népszerű bemeneti vezérlő támogatja – további részletekért lásd: áttekintésünket)hogy a felhasználót egy adott podhoz köthesse az alkalmazással:

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

Ez azonban nem szünteti meg az ismételt telepítésekkel kapcsolatos problémákat.

ajánlás

Helyesebb módja lenne az alkalmazás átvitele a következőre munkamenetek tárolása memcached, Redis és hasonló megoldásokban - általában teljesen elhagyja a fájllehetőségeket.

Következtetés

A szövegben tárgyalt infrastrukturális megoldások csak ideiglenes „mankók” formájában (angolul megkerülő megoldásként szebben hangzik) használhatók. Jelentősek lehetnek egy alkalmazás Kubernetesre való áttelepítésének első szakaszában, de nem szabad gyökeret verniük.

Az általánosan ajánlott út az, hogy megszabaduljunk tőlük, és az alkalmazás építészeti módosítása érdekében a sokak által már jól ismert módon módosítsuk. 12-faktoros alkalmazás. Ez azonban - az alkalmazás állapotmentes formába hozása - óhatatlanul azt jelenti, hogy a kódban változtatásokra lesz szükség, és itt fontos megtalálni az egyensúlyt a vállalkozás képességei/követelményei és a választott út megvalósításának és fenntartásának kilátásai között. .

PS

Olvassa el blogunkon is:

Forrás: will.com

Hozzászólás