Canary deployment: cum scoți cu siguranță un release în producție
Canary deployment înseamnă să trimiți un release nou doar la un procent mic din trafic, monitorizezi, și extinzi treptat. Cum funcționează pas cu pas.
Cuprins
Canary deployment este tehnica de a lansa o versiune nouă a unui serviciu la un procent mic din traficul real, a o monitoriza activ, și a extinde procentajul treptat dacă metricile rămân în limite acceptabile. Dacă ceva se degradează, faci rollback la versiunea stabilă înainte ca majoritatea utilizatorilor să fie afectați.
Numele vine de la minerii care duceau cu ei canari în mine: pasărea detecta gaze toxice înainte ca omul să fie afectat. La fel, un subset mic de utilizatori sau request-uri „testează" release-ul nou în producție reală, cu date reale și comportament real, înainte ca restul traficului să fie expus.
Ce este un canary deployment mai exact?
O strategie de release gradual în care două versiuni ale aceluiași serviciu rulează simultan în producție pentru o perioadă definită. Versiunea stabilă continuă să servească cea mai mare parte a traficului; versiunea nouă, numită canary, primește doar o fracțiune controlată.
Spre deosebire de un deployment clasic (înlocuiești toată flota instantaneu), canary limitează blast radius-ul. Dacă versiunea nouă are un bug care apare la 0,1% din request-uri, îl detectezi la 1% din trafic, nu după ce ai expus toți utilizatorii. Spre deosebire de un mediu de staging, datele și comportamentul sunt reale.
- Traffic splitting. Infrastructura direcționează un procent din cereri spre versiunea canary, prin load balancer cu ponderi, ingress controller sau feature flags evaluate la nivel de gateway.
- Observabilitate per versiune. Metricile, log-urile și erorile trebuie etichetate cu versiunea care le-a produs. Fără asta, nu poți compara versiunea nouă față de cea veche.
- Criterii de avansare și rollback. Definite înainte de rollout, nu în mijlocul lui. Ce rată de erori e acceptabilă? Ce latență la p95? Dacă nu ai răspuns înainte să pornești, decizia de rollback devine subiectivă sub presiune.
Cum diferă de blue/green deployment?
În blue/green deployment, menții două medii identice și comuti tot traficul deodată de la cel vechi la cel nou. Rollback-ul este instant, dar nu ai perioadă de validare cu trafic parțial. Dacă versiunea nouă are o problemă subtilă care apare la scară, o descoperi după ce ai comutat 100% din trafic.
Canary rezolvă exact asta. Prețul este complexitate mai mare: gestionezi simultan două versiuni active, etichetezi metricile per versiune și ai logică de traffic splitting în infrastructură. Blue/green e suficient când validarea în staging este fiabilă; canary are sens când staging-ul nu reproduce fidel producția sau când modificările sunt suficient de riscante cât să justifice validarea graduală în real.
O strategie de rolling update înlocuiește instanțele vechi una câte una, fără să controlezi explicit procentajul de trafic. Este mai simplă decât canary pur, dar nu poți menține intenționat versiunea nouă la 5% timp de o oră înainte să continui rollout-ul.
Cum decidem procentajele de rollout (1% → 10% → 50% → 100%)?
Nu există o formulă universală, dar fiecare fază trebuie să fie suficient de reprezentativă cât să detecteze problemele care apar la acea scară.
- 1% din trafic, 30-60 de minute. Validezi că versiunea pornește corect, că rata de erori nu explodează și că nu apar erori de inițializare. La această fază prinzi regresiile grave care au scăpat din staging.
- 10% din trafic, 1-2 ore. Acoperi mai multe cod paths. Compari latența p95 și p99 față de versiunea stabilă. Dacă latența crește semnificativ sau rata de erori depășește pragul definit, rollback.
- 50% din trafic, 2-4 ore. Problemele de concurență sau de cache devin vizibile. Urmărești consumul de resurse (CPU, memorie, conexiuni la baza de date), nu doar erorile.
- 100%, versiunea veche retrasă. Menții versiunea veche disponibilă pentru rollback rapid 24-48 de ore înainte să o dezafectezi.
Importante sunt criteriile de avansare, nu numerele exacte. Un rollout automatizat poate avansa fazele dacă metricile sunt în green, dar decizia de rollback trebuie să rămână declanșabilă manual în orice moment.
Ce metrici urmărim activ în timpul unui rollout?
Compari versiunea canary față de versiunea stabilă pe același interval de timp, nu față de istoricul versiunii stabile. Traficul variază în cursul zilei; o creștere a latenței dimineața nu înseamnă că versiunea nouă e vinovată dacă versiunea veche are exact același pattern.
- Rata de erori (4xx, 5xx) per versiune. Primul semnal care apare. Dacă versiunea canary produce mai multe erori de server decât versiunea stabilă, oprești imediat. Un vârf de 400 poate fi normal (validare client) sau poate semnala o schimbare de contract API neretrocompatibilă.
- Latența la p95 și p99. Media latenței ascunde probleme; percentilele le expun. Definești pragul de acceptare înainte de rollout, nu în timp ce observi că ceva se degradează.
- Saturația resurselor. O versiune nouă care consumă cu 30% mai multă memorie la același trafic devine o problemă la 100%. La 1% din trafic s-ar putea să nu observi.
- Metrici de business. Un serviciu de plată cu latență ok dar care procesează cu 5% mai puține tranzacții are o problemă pe care metricile tehnice nu o arată direct.
Eticheta de versiune pe fiecare metrică este condiția de bază. Fără ea nu poți face comparația canary vs. stabil. Dacă nu ai deja observabilitate per versiune, construiești asta înainte de primul canary deployment, nu după.
Care sunt capcanele operaționale (sticky sessions, cache invalidation, schema migrations)?
Canary deployment pare simplu în teorie și devine complex în producție exact din cauza stărilor partajate între versiuni. Trei capcane care apar cel mai des:
- Sticky sessions. Dacă aplicația menține sesiuni server-side, un utilizator poate face cereri alternativ spre versiunea veche și cea nouă. Formatul sesiunii salvat de versiunea nouă poate să nu fie citibil de versiunea veche. Soluția: sesiuni complet stateless (JWT) sau asiguri compatibilitatea de format între versiuni pe durata rollout-ului.
- Cache invalidation. Dacă ambele versiuni scriu în același cache, structura răspunsurilor poate fi incompatibilă. Versiunea nouă salvează un obiect cu un câmp nou; versiunea veche îl citește și aruncă excepție. La schimbări de format, folosești chei de cache diferite între versiuni sau inițializezi cache-ul gol la începutul rollout-ului.
- Migrări de schema. Dacă versiunea nouă necesită o modificare incompatibilă cu versiunea veche (coloană redenumită, constrângere adăugată), nu poți rula ambele versiuni simultan. Strategia sigură este expand-contract: adaugi ce e nou fără să ștergi ce e vechi; abia după rollout complet faci al doilea release care curăță. Liquibase face auditul acestor pași trasabil și reversibil.
Limitele de rate limiting bazate pe IP pot distorsiona comparația dacă sunt aplicate per instanță și nu la nivelul gateway-ului, înainte de traffic splitting. Un orchestrator precum n8n poate trimite notificări la fiecare avansare de fază sau depășire de prag, fără cod custom de integrare. Pentru echipele care operează mai multe produse în paralel și care țintesc același SLA uniform pe toată flota (la crawlerra urmărim acest SLA pe cele șase produse active în producție1), automatizarea pașilor de rollout este condiția care face canary deployment sustenabil pe termen lung.
- Stack-ul de observabilitate crawlerra acoperă șase produse active în producție: PromoAzi, RestoInsights, FarmaAzi, Crawlerra.com, Hub Travel Domus și o instanță medical-blog.
[ops.products_count]
Întrebări frecvente
Ce se întâmplă dacă metricile sunt bune la 1% dar se degradează la 10%?
Oprești rollout-ul imediat și faci rollback la versiunea stabilă. Trecerea de la 1% la 10% poate expune cod paths pe care traficul de 1% nu l-a atins. Un criteriu de succes definit înainte de fiecare fază, nu după, este singurul mod în care rollback-ul rămâne o decizie tehnică, nu politică.
Canary deployment vs feature flags: care e diferența?
Canary deployment rutează trafic la o versiune diferită a serviciului; feature flags activează cod în cadrul aceleiași versiuni. Canary cere infrastructură de traffic splitting; feature flags cer doar un if în cod. În practică se folosesc împreună: canary deployment pentru modificări de infrastructură sau schimbări de schema, feature flags pentru funcționalități noi izolate.
Cât timp stai la 1% înainte să treci la faza următoare?
Minim 30 de minute, ideal o oră, suficient cât să acoperi un ciclu complet de trafic real. Pentru produse cu variație mare de trafic între zi și noapte, poți menține faza de 1% peste noapte. Automatizarea poate avansa faza dacă toate metricile sunt în green, dar decizia de rollback trebuie să rămână declanșabilă manual în orice moment.
Trebuie să am Kubernetes pentru canary deployment?
Nu, dar ai nevoie de un mecanism de traffic splitting. Kubernetes + Argo Rollouts sau Flagger e o implementare populară, dar poți obține același efect cu un load balancer care suportă ponderi (nginx upstream weights, HAProxy, Cloudflare Load Balancer) sau cu un feature flag evaluat la nivel de gateway. Implementarea concretă depinde de infrastructura ta, nu de canary ca principiu.
Cum tratezi migrările de schema într-un canary deployment?
Migrarea de schema trebuie să fie backward-compatible cu versiunea anterioară înainte să pornești rollout-ul. Adaugi o coloană opțională sau un index nou fără să ștergi sau redenumești nimic existent. Ștergerea sau redenumirea se face abia după ce versiunea nouă a ajuns la 100% și ai confirmat că versiunea veche nu mai rulează nicăieri. Uneltele de migrare precum Liquibase te ajută să versionezi și să auditezi fiecare modificare de schema.