I fugliali lucali durante a migrazione di una applicazione à Kubernetes

I fugliali lucali durante a migrazione di una applicazione à Kubernetes

Quandu si custruisce un prucessu CI/CD cù Kubernetes, qualchì volta u prublema nasce di l'incompatibilità trà i requisiti di a nova infrastruttura è l'applicazione trasferita à questu. In particulare, in a fase di creazione di l'applicazione hè impurtante per ottene один immagine chì serà usata in всех ambienti di prughjettu è clusters. Stu principiu sottu à u currettu secondu Google gestione di u containeru (più di una volta nantu à questu parlava è u nostru dipartimentu tecnicu).

Tuttavia, ùn vi vede à nimu in situazioni induve u codice di u situ usa un framework ready-made, l'usu di quale impone restrizioni à u so usu più. E mentri in un "ambienti nurmale" questu hè faciule da trattà, in Kubernetes stu cumpurtamentu pò diventà un prublema, soprattuttu quandu u scontru per a prima volta. Mentre chì una mente inventiva pò vene cun suluzioni infrastrutturali chì parenu evidenti o ancu boni à u primu sguardu ... hè impurtante ricurdà chì a maiò parte di e situazioni ponu è duveranu. esse risolta architetturale.

Fighjemu solu solu suluzione populari per almacenà i fugliali chì ponu purtà à cunsequenze spiacevoli quandu operanu un cluster, è ancu indicà una strada più curretta.

Almacenamiento staticu

Per illustrà, cunzidira una applicazione web chì usa un tipu di generatore staticu per ottene un inseme d'imaghjini, stili è altre cose. Per esempiu, u framework Yii PHP hà un gestore di asset integratu chì genera nomi di repertori unichi. In cunsiquenza, l'output hè un inseme di percorsi per u situ staticu chì ovviamente ùn si intersectanu micca cù l'altri (questu hè statu fattu per parechje motivi - per esempiu, per eliminà i duplicati quandu parechji cumpunenti utilizanu u stessu risorsu). Allora, fora di a scatula, a prima volta chì accede à un modulu di risorsa web, i schedarii statichi (in fatti, spessu ligami simbolichi, ma più nantu à questu dopu) sò furmati è disposti cù un repertoriu radicale cumuni unicu per questa implementazione:

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

Chì significarà questu in termini di un cluster?

L'esempiu più simplice

Pigliemu un casu abbastanza cumuni, quandu PHP hè precedutu da nginx per distribuisce dati statici è processà e dumande simplici. U modu più faciule - Mudellu cù dui cuntenituri:

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 una forma simplificata, a cunfigurazione nginx si riduce à i seguenti:

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

Quandu accede prima à u situ, l'assi appariscenu in u cuntinuu PHP. Ma in u casu di dui cuntenituri in un pod, nginx ùn sapi nunda di questi schedari statichi, chì (sicondu a cunfigurazione) deve esse datu à elli. In u risultatu, u cliente vi vede un errore 404 per tutte e dumande à i schedari CSS è JS. A suluzione più simplice quì seria di urganizà un repertoriu cumuni per i cuntenituri. Opzione primitiva - generale 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

Avà i schedarii statici generati in u cuntinuu sò servuti da nginx currettamente. Ma lasciami ricurdà chì questu hè una suluzione primitiva, chì significa chì hè luntanu da l'ideale è hà i so sfumaturi è i difetti, chì sò discututi quì sottu.

Storage più avanzatu

Avà imaginate una situazione induve un utilizatore hà visitatu u situ, hà caricatu una pagina cù i stili dispunibuli in u cuntinuu, è mentre ellu stava leghjendu sta pagina, avemu ridistribuitu u cuntinuu. U catalogu di l'assi hè diventatu viotu è una dumanda à PHP hè necessaria per cumincià à generà novi. In ogni casu, ancu dopu à questu, i ligami à l'antica statics seranu irrilevanti, chì portanu à l'errore in a visualizazione di statics.

Inoltre, probabilmente avemu un prughjettu più o menu caricatu, chì significa chì una copia di l'applicazione ùn serà micca abbastanza:

  • Scalemu Mudellu finu à duie ripliche.
  • Quandu u situ hè statu prima accessu, l'assi sò stati creati in una replica.
  • À un certu puntu, l'ingressu hà decisu (per scopi di equilibriu di carica) di mandà una dumanda à a seconda replica, è questi assi ùn eranu micca quì. O forse ùn ci sò più perchè avemu usatu RollingUpdate è in u mumentu facemu a distribuzione.

In generale, u risultatu hè di novu sbagli.

Per evitari di perde i vechji assi, pudete cambià emptyDir nantu hostPath, aghjunghjendu statica fisicamenti à un node di cluster. Stu approcciu hè male perchè avemu daveru ligà à un node di cluster specificu a vostra applicazione, perchè - in casu di trasfurmà à altri nodi - u cartulare ùn cuntene micca i schedarii necessarii. O un certu tipu di sincronizzazione di u cartulare di fondo trà i nodi hè necessariu.

Chì sò e suluzione ?

  1. Se hardware è risorse permettenu, pudete aduprà cephfs per urganizà un repertoriu ugualmente accessibile per i bisogni statici. Documentazione ufficiale ricumanda unità SSD, replicazione almenu trè volte è una cunnessione stabile "grossa" trà i nodi di cluster.
  2. Una opzione menu esigente seria di urganizà un servitore NFS. In ogni casu, allora avete bisognu di piglià in contu l'aumentu pussibule di u tempu di risposta per u processu di e dumande da u servitore web, è a tolleranza di difetti lascià assai per esse desideratu. E cunsequenze di u fallimentu sò catastròfichi: a perdita di a muntagna cundanna u cluster à a morte sottu l'assaltu di a carica di LA chì si precipita in u celu.

Frà altre cose, tutte l'opzioni per creà un almacenamentu persistente necessitanu pulizia di fondo insemi obsoleti di schedari accumulati in un certu periodu di tempu. In fronte di cuntenituri cù PHP pudete mette DaemonSet da caching nginx, chì guardà copie di l'assi per un tempu limitatu. Stu cumpurtamentu hè facilmente configurabile usendu proxy_cache cù a prufundità di almacenamiento in ghjorni o gigabyte di spaziu di discu.

Cumminendu stu metudu cù i sistemi di schedarii distribuiti sopra citati furnisce un campu enormu per l'imaginazione, limitatu solu da u budgetu è u putenziale tecnicu di quelli chì l'implementanu è sustenenu. Da l'esperienza, pudemu dì chì u più simplice u sistema, u più stabile funziona. Quandu tali strati sò aghjuntu, diventa assai più difficiuli di mantene l'infrastruttura, è à u stessu tempu u tempu passatu per diagnosticà è ricuperà da ogni fallimentu aumenta.

Cunsigliia

Se l'implementazione di l'opzioni d'almacenamiento pruposti vi pare ancu micca ghjustificatu (cumplicatu, caru ...), allora vale a pena guardà a situazione da l'altra parte. Vale à dì, per scavà in l'architettura di u prugettu è risolve u prublema in u codice, liata à una certa struttura di dati statica in l'imaghjini, una definizione senza ambiguità di u cuntenutu o prucedura per "warming up" è / o precompiling assets in u stadiu di l'assemblea di l'imaghjini. In questu modu avemu un cumpurtamentu assolutamente prevedibile è u stessu set di schedari per tutti l'ambienti è ripliche di l'applicazione in esecuzione.

Se vultemu à l'esempiu specificu cù u framework Yii è ùn sfondate micca in a so struttura (chì ùn hè micca u scopu di l'articulu), hè abbastanza per indicà dui approcci populari:

  1. Cambia u prucessu di creazione di l'imaghjini per mette l'assi in un locu prevedibile. Questu hè suggeritu / implementatu in estensioni cum'è yii2-static-assets.
  2. Definite hashs specifichi per i repertorii di asset, cum'è discutitu in p.e. sta presentazione (partendu da u slide n ° 35). In modu, l'autore di u rapportu in ultimamente (è micca senza ragiuni!) Cunsigliu chì dopu avè assemblatu l'assi nantu à u servitore di custruzzione, caricate à un almacenamentu cintrali (cum'è S3), davanti à quale mette un CDN.

Downloads

Un altru casu chì certamenti entrerà in ghjocu quandu migrate una applicazione à un cluster Kubernetes hè di almacenà i fugliali d'utilizatori in u sistema di fugliale. Per esempiu, avemu dinò una applicazione PHP chì accetta i schedari attraversu una forma di upload, face qualcosa cun elli durante l'operazione, è li manda torna.

In Kubernetes, u locu induve questi schedari deve esse posti deve esse cumunu à tutte e repliche di l'applicazione. Sicondu a cumplessità di l'appiecazione è a necessità di urganizà a persistenza di sti schedari, l'opzioni di u dispusitivu spartutu sopra-mintuatu pò esse un tali locu, ma, cum'è avemu vistu, anu i so inconvenienti.

Cunsigliia

Una suluzione hè aduprendu l'almacenamiento compatible S3 (ancu s'ellu hè un tipu di categuria self-hosted cum'è minio). Passà à S3 richiederà cambiamenti à u livellu di codice, è cumu u cuntenutu serà furnitu in u front end, avemu digià hà scrittu.

Sessioni d'utilizatori

Separatamente, vale a pena nutà l'urganizazione di almacenamiento di sessioni d'utilizatori. Spessu questi sò ancu schedarii nantu à u discu, chì in u cuntestu di Kubernetes portanu à dumande d'autorizazione custanti da l'utilizatori se a so dumanda finisci in un altru cuntainer.

U prublema hè in parte risolta accendendu stickySessions à l'entrata (a funzione hè supportata in tutti i controller di ingressu populari - per più dettagli, vede a nostra recensione)per ligà l'utilizatore à un pod specificu cù l'applicazione:

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

Ma questu ùn eliminerà micca i prublemi cù implementazioni ripetute.

Cunsigliia

Una manera più curretta seria di trasfiriri l'applicazione à almacenà e sessioni in memcached, Redis è soluzioni simili - in generale, abbandunà completamente l'opzioni di u schedariu.

cunchiusioni

I suluzioni infrastrutturali discututi in u testu sò degne di usu solu in u formatu di "crutches" tempuranee (chì sona più bella in inglese cum'è workaround). Puderanu esse pertinenti in i primi fasi di a migrazione di una applicazione à Kubernetes, ma ùn deve micca radicà.

U percorsu generale cunsigliatu hè di sbarazzarsi di elli in favore di a mudificazione architettonica di l'applicazione in cunfurmità cù ciò chì hè digià cunnisciutu da parechji. 12-Factor App. In ogni casu, questu - purtendu l'applicazione à una forma senza statu - inevitabbilmente significa chì i cambiamenti in u codice saranu necessarii, è quì hè impurtante truvà un equilibriu trà e capacità / esigenze di l'affari è e prospettive per implementà è mantene a strada scelta. .

PS

Leghjite puru nant'à u nostru blog:

Source: www.habr.com

Add a comment