# Blå-grön driftsättning

## Vad det är

Blå-grön driftsättning är ett sätt att släppa programvara med två
produktionsmiljöer som är byggda så lika som möjligt. Den ena, här kallad den
blå, betjänar alla anrop. Den nya versionen installeras i den andra, den gröna,
och testas där medan inga kunder når den. När den är klar ändras det som står
framför de två miljöerna, så att alla nya anrop går till den gröna. Den blå kör
vidare orörd, och om den gröna beter sig illa sätter samma ändring gjord
baklänges den blå i tjänst igen. På engelska heter det blue-green deployment,
och i svenska team säger man ofta bara blue-green.

Färgerna betyder ingenting, och det är hela poängen. Namn som ”gammal” och ”ny”
eller ”primär” och ”reserv” byter innebörd efter varje release, medan två färger
bara turas om: efter nästa växling är den gröna skarp och den blå den lediga.
Martin Fowler beskrev tekniken på sin bliki 2010 och tillskriver namnet Daniel
Terhorst-North och Jez Humble, även om han medger att han minns ursprunget
något dimmigt. Verktygen stavar det på sitt eget sätt: Argo Rollouts, en
Kubernetes-controller som lägger till driftsättningsstrategier av det här
slaget, kallar det `blueGreen` i sin konfiguration.

Växeln kan vara vilken enskild punkt som helst som avgör vart anropen tar vägen.
I Fowlers version är det en router. Det kan lika gärna vara målet för en
lastbalanserare, upstream i en omvänd proxy eller, i Kubernetes, en Service vars
label-selektor pekar ut vilka poddar som får trafiken. De två miljöerna behöver
inte heller vara två datacenter: Fowler nämner separat hårdvara, separata
virtuella maskiner eller två zoner på samma system med egna IP-adresser som
lika goda lösningar.

Två grannstrategier gör skillnaden tydlig. En rullande driftsättning byter ut
instanser några i taget, så att gammal och ny version svarar sida vid sida tills
den sista gamla är borta, och att backa innebär ännu en rullande driftsättning
åt andra hållet. En canary release skickar först en liten andel av trafiken till
den nya versionen och vidgar den steg för steg. Blå-grön driftsättning flyttar
allt på en gång men behåller en komplett, körande kopia av den föregående
versionen, så vägen tillbaka är ett steg, lika stort som vägen framåt.

## Varför det spelar roll

En release blir en kort händelse som går att ångra i stället för en lång
enkelresa. Det som tar tid, som att kopiera filer, starta processer och värma
upp cachar, sker i den gröna miljön medan den blå fortfarande betjänar kunderna,
så ingen väntar på det. Själva växlingen går snabbt, och det gör ångrandet
också: inget behöver byggas eller installeras om, eftersom den föregående
versionen aldrig slutade köra. Det ändrar hur ett team känner inför att släppa
en helt vanlig eftermiddag, och hur snabbt det kan agera när något ser fel ut.

Den gröna miljön kan dessutom prövas under förhållanden som ligger mycket nära
produktion innan någon kund ser den: samma nätverk, samma konfiguration, samma
databas. Ett röktest mot den gröna bevisar betydligt mer än samma test i en
stagingmiljö som skiljer sig på ett dussin små punkter. Argo Rollouts
formaliserar det med en preview-Service som skickar trafik till den nya
versionen före promoteringen, alltså steget där den blir skarp, så att den kan
testas utan att betjäna produktionstrafik.

Den lediga miljön har ett jobb till. När en release har satt sig blir den sida
som nyss blev tyst platsen där nästa release förbereds, och fram till dess är
den en varm reserv. Fowler påpekar att samma mekanism låter en organisation
pröva sin plan för katastrofåterställning vid varje release, eftersom varje
växling är en failover som någon håller ögonen på.

Priset är lätt att se. Två produktionsmiljöer kräver kapacitet för två,
åtminstone medan en release pågår. Och även om applikationslagret är lätt att
duplicera är data det inte: den blå och den gröna delar nästan alltid en
databas, så varje release måste gå att läsa för båda versionerna. Ett team som
inte kan lova det får en snabb växling framåt och en växling tillbaka som inte
fungerar.

## Så ser det ut i praktiken

I Kubernetes är den minsta fungerande versionen två Deployment-objekt och en
Service. Objekten `web-blue` och `web-green` kör samma applikation med
etiketterna `app: web` och `slot: blue` eller `slot: green`. Den Service som
kunderna når väljer en av dem:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
    slot: blue
  ports:
    - port: 80
      targetPort: 8080
```

En release lägger den nya avbildningen på den lediga sidan, väntar in den,
testar den genom en extra Service som bara väljer `slot: green` och flyttar
sedan den skarpa:

```sh
kubectl set image deployment/web-green web=registry.example.com/web:1.5.0
kubectl rollout status deployment/web-green --timeout=5m
# röktester mot preview-Servicen för web-green här
kubectl patch service web -p '{"spec":{"selector":{"slot":"green"}}}'
# vägen tillbaka är samma kommando med den andra färgen
kubectl patch service web -p '{"spec":{"selector":{"slot":"blue"}}}'
```

`kubectl patch` använder som standard en strategic merge patch, så bara nyckeln
`slot` i selektorn ändras medan `app: web` står kvar. Servicens controller letar
hela tiden efter poddar som matchar selektorn och uppdaterar Servicens
ändpunkter när mängden ändras, så att nya anslutningar hamnar i den gröna medan
den blå står redo med den föregående avbildningen.

Argo Rollouts automatiserar samma dans med ett enda `Rollout`-objekt: en
`activeService` som den pekar mot de nya poddarna vid promoteringen och en
valfri `previewService` som når dem innan dess. Med
`autoPromotionEnabled: false` pausar utrullningen före växlingen tills någon kör
`kubectl argo rollouts promote web`.

[Tjänsten DevOps och CI/CD-automatisering](/sv/services/devops-cicd/) utlovar
ändringar som är testade, släppta och möjliga att backa, och blå-grön
driftsättning är ett sätt att göra det sista billigt. Tekniken vilar på två
vanor som
[driftsättningarna av en plattform till Azure](/sv/portfolio/owned-end-to-end-platform-deployments-to-azure/)
visar i bruk, utan någon andra produktionsmiljö: Bicep-mallarna håller
målinfrastrukturen identisk från en miljö till nästa, och samma byggda artefakt
förs vidare från utveckling via staging till produktion och plockar upp rätt
inställningar där den hamnar. Den vägen för en release genom miljöerna i tur och
ordning. Blå-grön driftsättning ställer en tvilling vid vägens slut, och samma
två vanor, likadan infrastruktur och en oförändrad artefakt, är det som låter
ett team lita på att tvillingen verkligen är likadan.

## Var det går fel

**En schemaändring gör vägen tillbaka till en återvändsgränd.** Den gröna
startar, kör en migrering som byter namn på en kolumn och betjänar trafik utan
problem. Tio minuter senare skickar ett fel tillbaka trafiken till den blå, som
fortfarande frågar efter det gamla kolumnnamnet och fallerar på varje anrop.
Återgången var planerad för applikationen, inte för data. Fowlers råd från 2015
är att hålla isär de två: släpp först en databasändring som båda versionerna
klarar av, sedan applikationen, och ta bort det som bara den gamla versionen
behövde när den nya har satt sig.

**Tillstånd som skrivits i den gröna blir strandat vid en växling tillbaka.**
Allt som den gröna håller för sig själv, till exempel filer uppladdade till den
lokala disken, sessioner i minnet eller en egen cache med väntande jobb, finns
inte i den blå när trafiken återvänder. Användarna blir utloggade eller saknar
det de nyss sparade. Håll delat tillstånd i lagringsplatser som båda färgerna
använder. Måste den gröna ha egna data föreslår Fowler att skicka
transaktionerna till båda miljöerna, eller att starta den gröna skrivskyddad och
öppna för skrivning först när den har visat sig hålla.

**Vägen tillbaka skalas bort innan felet syns.** Argo Rollouts skalar ner det
gamla ReplicaSet-objektet efter växlingen, och `scaleDownDelaySeconds` är 30 som
standard. Ett fel som dyker upp först efter en kvart, ett nattligt jobb eller en
långsam minnesläcka, hittar ingen blå att återvända till. Sätt fördröjningen så
att den täcker den tid det brukar ta innan problem syns, och acceptera att
priset är kapaciteten:

```yaml
strategy:
  blueGreen:
    activeService: web
    previewService: web-preview
    autoPromotionEnabled: false
    scaleDownDelaySeconds: 3600
```

**Promoteringen följer beredskap, inte korrekthet.** `autoPromotionEnabled` är
true som standard, så Argo Rollouts växlar så snart de nya poddarna är redo. En
readiness probe säger att en process svarar, inte att kassan fungerar. Pausa
före promoteringen som i blocket ovan och testa genom preview-Servicen, eller
lägg till en `prePromotionAnalysis` som avbryter utrullningen om den misslyckas
och en `postPromotionAnalysis` som växlar tillbaka till den föregående versionen
om den misslyckas efter växlingen.

**Den lediga sidan glider isär från den skarpa.** Mellan två releaser lägger
någon in en brådskande konfigurationsändring enbart i den skarpa miljön. Nästa
release landar på den lediga sidan, som fortfarande har den gamla inställningen,
och växlingen som skulle ändra en sak ändrar två. Bygg båda miljöerna från samma
mallar och samma konfigurationskälla, så att en ändring i den ena är en ändring
i båda, och använd den lediga sidan som staging för nästa release, så som Fowler
beskriver.

## Läs mer

- [Blue Green Deployment](https://martinfowler.com/bliki/BlueGreenDeployment.html)
  — Martin Fowlers beskrivning från 2010, med hans tillägg från 2015 om
  databasändringar.
- [Argo Rollouts: BlueGreen](https://argo-rollouts.readthedocs.io/en/stable/features/bluegreen/)
  — aktiv och preview-Service, automatisk promotering, analys före och efter
  växlingen och fördröjningen av nedskalningen.
- [Kubernetes Service](https://kubernetes.io/docs/concepts/services-networking/service/)
  — hur en selektor pekar ut vilka poddar som får en Services trafik.
- [kubectl patch](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_patch/)
  — strategic merge, merge och JSON-patchar, kommandot som vänder selektorn i
  exemplet ovan.

<https://engineer.company/sv/glossary/blue-green-deployment/>
