Vad är canary deployment? En praktisk guide för utvecklare

Summary

En canary deployment skickar en ny version till en liten andel riktig trafik, ofta 1 till 5 procent, innan alla får den. Du jämför felfrekvens och svarstid mot den stabila versionen, ökar andelen om allt håller och sätter canary-vikten till noll om det inte gör det. Metoden begränsar skadan av en dålig release, men den kräver mätvärden per version och tillräckligt med trafik för att betyda något.

Ett mörkt utvecklarskrivbord på natten med en trafikdashboard och en liten gul kanariefigur

Vad är canary deployment? Det är en release där den nya versionen av appen först får en liten andel riktig trafik, säg 1 till 5 procent, medan alla andra fortsätter på den gamla versionen. Du följer felfrekvens och svarstid på just den andelen. Ser det friskt ut ökar du andelen. Ser det dåligt ut skickar du tillbaka trafiken, och nästan ingen märkte något. Det är hela idén, och resten av artikeln handlar om hur du får den att fungera i praktiken.

En gammal gruvlampa och en tom fågelbur på en arbetsbänk, ursprunget till namnet canary

Varför heter det canary?

Gruvarbetare tog med sig kanariefåglar ner i gruvorna eftersom fåglarna reagerade på giftig gas innan människorna gjorde det. En kanariefågel som slutade sjunga var signalen att ta sig upp. En canary deployment fungerar på samma sätt: en liten grupp användare träffar den nya koden först och blir den tidiga varningen. CNCF:s ordlista beskriver det som två miljöer, där den ena tar emot live-trafik och den andra kör den uppdaterade koden, och där trafiken flyttas gradvis, med start på en liten andel som 1 procent.

Så här ser det ut i praktiken: canary-användarna är riktiga användare. Staging kan inte ge dig det. Produktion har de konstiga webbläsarna, de gamla cacheminnena och den ena kunden med en importfil på 40 MB. En canary är sättet att möta dem innan alla möter din bugg.

Hur fungerar en canary deployment egentligen?

Fyra delar, inget exotiskt.

En typisk uppskalning ser ut så här: 1 procent, 5 procent, 25 procent, 50 procent, 100 procent, med en paus vid varje steg. Google Cloud Deploy beskriver samma upplägg. Du definierar en serie andelar och verktyget fördelar trafiken, och exemplet använder faserna 25, 50 och 75 procent innan den sista stabila versionen. Cloud Deploy-dokumentationen för canary visar också att varje fas kan köra ett verifieringsjobb och ett analyssteg för att avgöra om man ska gå vidare.

Det är inte en perfekt uppsättning, men den går att bygga. Du behöver inte Kubernetes för detta. En viktad route i nginx, en Cloudflare worker som växlar en cookie eller två Fly.io-maskiner bakom en proxy räknas alla.

Hur ser trafikfördelningen ut i en konfig?

Här är det minsta användbara exemplet, en nginx-upstream med vikter. Nio av tio anrop går till den stabila versionen och ett går till canary.

upstream app {
    server 10.0.0.10:3000 weight=9;   # stabil
    server 10.0.0.11:3000 weight=1;   # canary
}

Den här uppsättningen har en brist som du bör känna till: fördelningen sker per anrop, så en användare kan hoppa mellan versionerna vid två klick i rad. Om din nya version ändrar formen på ett API-svar eller en databaskolumn får den användaren en dålig stund. Sticky routing med cookie eller användar-ID löser det, och det är första saken att lägga till när den grundläggande fördelningen fungerar.

Bärbar dator som visar två mätlinjer som divergerar och jämför en stabil release med en canary

Vad ska du titta på medan canary:n kör?

Jämför canary mot den stabila versionen i samma ögonblick, inte mot förra veckan. Förra veckan hade annan trafik. Frågan är alltid: är canary sämre än versionen som betjänar de övriga 95 procenten just nu?

Det vanligaste misstaget vi ser i små team är att trappa upp på en timer. Fem minuter på 1 procent, sedan 25 procent, oavsett vad graferna säger. Vid låg trafik kan fem minuter på 1 procent vara sex anrop, och det säger dig ingenting. Vänta på ett minsta antal anrop, inte på ett minsta antal minuter.

Verktyg som gör detta mindre manuellt är värda en titt när du har riktig trafik.

Canary eller blue-green: vilken ska du välja?

Blue-green håller två fullständiga miljöer och vänder all trafik på en gång. Rollback innebär att vända tillbaka, vilket är snabbt och rent. Priset är att alla användare för en stund är på den nya versionen, och att du betalar för dubbel infrastruktur under bytet.

Canary exponerar bara en andel, så skadeområdet blir mindre. Priset är komplexitet: du behöver viktad trafik, mätvärden per version och en beslutsregel. Rollback innebär att sätta canary-vikten till noll. Det går snabbt men inte bokstavligen direkt om anslutningar måste tömmas.

Det finns tre skäl att välja canary och ett skäl att låta bli. Välj canary när en bugg i produktion är dyr, när du har tillräckligt med trafik för att en liten andel ska betyda något, och när du kan jämföra mätvärden per version. Hoppa över det när du har några dussin användare om dagen. Då blir canary-andelen statistiskt tom och du gissar. I den skalan är blue-green, eller till och med en vanlig deploy med ett snabbt rollback-skript, det ärliga svaret.

Rullande uppdateringar ligger mitt emellan. De ersätter instanser en i taget, vilket är skonsamt, men de är inget kontrollerat experiment. Du väljer inte vem som ser den nya versionen och du jämför inte grupper av användare.

Var passar feature flags in?

En canary deployment delar trafiken mellan versioner av koden. En feature flag delar beteendet inuti en och samma version. Folk blandar ihop dem, och förväxlingen blir dyr.

Deploya den nya koden till alla, gömd bakom en flagga som är av. Slå sedan på flaggan för 1 procent av användarna, sedan för 10 procent och till sist för alla. Det här kallas ofta en canary-release på funktionsnivå. Fördelen är att rollback innebär att vända en flagga, ingen ny deploy. Nackdelen är att den döda kodvägen ligger i produktion för alla, och flaggor som glöms kvar blir teknisk skuld.

För en solo-utvecklare är flaggor oftast det billigare första steget. En boolean i en konfigtabell och en hash av användar-ID ger dig ungefär 80 procent av nyttan. Om du växer ur det tar en hanterad tjänst hand om targeting, audit-loggar och gradvisa procentuella utrullningar.

En vridknapp som har vridits lite uppåt, som att flytta en liten andel trafik till en ny version

Vad går fel med canaries i riktiga projekt?

Testat. Inte optimalt. Här är varför vi ändå gör det. Det här är felen som faktiskt biter.

Databasmigreringar. Båda versionerna pratar med samma databas samtidigt. Om canary tar bort eller byter namn på en kolumn går den stabila versionen sönder. Lösningen är expand and contract-mönstret: lägg till den nya kolumnen först, skicka kod som hanterar båda formerna, och ta bort den gamla kolumnen först i en senare release. Hoppar du över det tar din canary ner den stabila versionen.

Sessioner i minnet. Om sessioner ligger i minnet på en instans loggas användaren ut när den hoppar mellan versionerna. Flytta sessionstillståndet till en delad lagring innan du provar canaries.

Cache-förgiftning. En ny version som skriver ett annat cacheformat kan korrumpera det som den gamla versionen läser. Versionera dina cache-nycklar.

Bakgrundsjobb. Canary konsumerar också kömeddelanden. En trasig worker kan tugga igenom jobb i full fart, eftersom trafikprocenten inte begränsar hur snabbt kön töms. Ge canary sin egen kö eller en egen konsumentvikt.

Larm som ingen kopplade in. Canary kan misslyckas högljutt på en dashboard som ingen öppnar. Automatisk avbrytning vid ett tröskelvärde slår en människa som tittar, särskilt klockan två på natten när den enda vakna personen är den som precis deployade.

Hur börjar man med en canary i ett sidoprojekt?

Börja mindre än du tror att du borde. Du är en utvecklare, inte ett plattformsteam.

  1. Märk varje mätvärde med en version. Lägg git-SHA:n i en header och i loggarna. Utan det kan du inte alls jämföra canary och stabil.

  2. Välj en avbrytningsregel. Till exempel: om felfrekvensen på canary ligger över 2 gånger den stabila i fem minuter rullar du tillbaka. En regel, nedskriven.

  3. Lägg till en viktad route. Nginx-vikter, en Cloudflare-regel eller din hostings funktion för trafikfördelning. De flesta hanterade plattformar erbjuder numera procentbaserad routing utan extra verktyg.

  4. Skicka något tråkigt först. En textändring, inte en omskrivning av prissidan. Öva uppskalningen och rollbacken när ingenting står på spel.

  5. Tidtaga rollbacken. Kör den faktiskt en gång. Tar den tio minuters fumlande är det det du ska fixa, inte uppskalningen.

Om ditt projekt fortfarande är i fasen där du tar reda på vem som betalar för det är det troligen för tidigt. Skicka enkelt, behåll ett rollback-skript, och återkom till canaries när en driftstörning skulle kosta dig riktiga kunder. Om du redan är där är en viktad route plus en avbrytningsregel ett veckoslut av arbete, och det betalar sig första gången en dålig release dör på 1 procent i stället för på 100.

Ska du köra canary på allt?

Nej. Konfigändringar, textjusteringar och rättelser av ett stavfel i en footer behöver ingen stegvis utrullning. Använd canaries för ändringar där fel kostar pengar eller förtroende: betalningar, autentisering, datamodeller och allt som ligger på den heta vägen. En pipeline som bygger upp trafiken stegvis för varje commit i en timme kommer att kringgås första gången någon har bråttom, och en kringgången process är värre än ingen process alls.

Så vad är den riskabelaste ändringen i din nästa release, och vad skulle det krävas för att skicka den till 1 procent av användarna först?

Frequently asked questions

Vad är canary deployment i enkla termer?
Det är en releasemetod där en ny version först betjänar en liten andel riktiga användare medan resten ligger kvar på den gamla versionen. Om måtten fortsätter att vara friska växer andelen tills den nya versionen betjänar alla. Om de försämras går trafiken tillbaka till den stabila versionen.
Vilken andel trafik ska en canary börja med?
Många team börjar på cirka 1 till 5 procent. Rätt siffra beror på volymen: andelen måste ge tillräckligt många anrop för att kunna jämföra felfrekvens och svarstid. Vid mycket låg trafik bör du vänta på ett minsta antal anrop i stället för ett fast antal minuter.
Vad är skillnaden mellan canary och blue-green deployment?
Blue-green kör två fullständiga miljöer och växlar all trafik på en gång, så rollback är att vända tillbaka. Canary flyttar trafiken gradvis, så färre användare utsätts för en dålig release, men det kräver viktad trafik och övervakning per version.
Är en canary deployment samma sak som en feature flag?
Nej. En canary delar trafiken mellan två utrullade versioner av koden. En feature flag slår av och på ett beteende inuti en och samma version. De fungerar bra ihop: deploya dolt bakom en flagga och aktivera sedan för en liten andel användare.
Behöver du Kubernetes för att köra canary deployments?
Nej. Viktade upstreams i nginx, en CDN- eller edge-regel eller trafikfördelning hos en hanterad hostingtjänst klarar det också. Kubernetes-verktygen gör stegvisa ökningar och automatisk analys enklare, men de krävs inte.
Hur fungerar databasmigreringar med canary-releaser?
Båda versionerna delar en databas, så använd expand and contract-mönstret: lägg till nya kolumner först, skicka kod som hanterar båda formerna, och ta bort gamla kolumner först i en senare release.