Litt om DevOps - Teori og praksis
DevOps er et av mange buzzord man ofte kommer borti som utvikler. Det er et omfattende tema som er skrevet mye om av strateger, prosjektledere og utviklere, men kan som konsept virke litt diffust om man ikke har vært direkte borti det. Hensikten med dette innlegget er derfor å utdype litt om bakgrunnen og teorien bak DevOps, samt å gi et lite eksempel på hvordan det kan se ut i praksis.
Et lite throwback
IT-industrien har kontinuerlig gått gjennom store endringer så lenge den har eksistert. Bare 10-15 år tilbake var verktøyene, metodene og mulighetene mye mer begrensede enn de er i dag. Disse begrensingene gjorde at å splitte opp et softwareprosjekt i to grunnleggende kategorier virket fornuftig. Utvikling (development, Dev) var den ene, og drift (operations, Ops) var den andre. Det var på den tiden to ganske forskjellige fagfelt. Å utvikle et system handlet for det meste om å skrive kode og å designe grensesnitt, mens drifting handlet om å sørge for at en eller flere servere var oppe og kjørte programvaren de skulle kjøre uten å bli overbelastet eller kapitulere. Ettersom skyen (Public Cloud) ikke var en stor greie ennå var serverne ofte "on site" hos bedriften, og Ops-gjengen kunne ha ansvaret for driften av alle IT-systemene til bedriften.
Dette var kanskje den beste ordningen på den tiden, men det skapte en del problemer, og ofte litt friksjon mellom Devs og Ops. Utviklerne ville ha stadig endring og forbedring av produktet, mens drifterne likte stabilitet og trygghet. Var det bugs eller andre uforutsette hendelser med programvaren som Ops-gjengen plukket opp var det ikke lett å debugge uten hjelp fra Devs-gjengen. Så rundt 2008 tenkte noen kloke hoder at disse to gruppene burde jobbe tettere sammen!
Hva er DevOps?
Dette leder oss til introduksjonen av DevOps' prinsipper. I korte trekk går ideen ut på at utviklere og driftere skal jobbe så tett sammen som mulig, og helst så tett at det ikke lenger er et skille i det hele tatt. Alle som utvikler har et forhold til og en forståelse av driftingen, og vice versa. Utover dette er det variasjoner i hva folk legger i begrepet, men for de fleste inkluderer konseptet også ting som:
- Små og inkrementelle oppdateringer av gangen, i stedet for massive "releases".
- Kort og enkel vei fra utvikling til release, typisk gjennom såkalte "pipelines".
- Automatiske prosesser for kvalitetssikring og testing før oppdateringer.
- Logging av alle kritiske operasjoner i systemet (f. eks betaling). Loggene burde være lett tilgjengelige, beskrivende og bør inneholde nok relevant informasjon. Logging og varsling når uforutsette feil oppstår.
- Monitorering av ytelse og varsling om hardwareressurser ikke er tilstrekkelig.
Det er mange fordeler ved å jobbe etter disse prinsippene sammenlignet med "gamlemåten". Siden vi er mennesker vil vi nødvendigvis gjøre feil før eller siden, også med DevOps. Men ikke bare er sannsynlighetene for kritiske feil mye lavere med DevOps, når feilen først oppstår går det mye fortere å rette opp i den og å slenge ut en fix i produksjon. Du vet jo akkurat hvor i koden feilen oppstår, og forhåpentligvis hvordan det skal fikses. Har du vært flink og brukt et versjonskontrollsystem, som git, hvor du har organisert oppdateringer i klare meldinger vil det også være mulig å gå tilbake til en versjon der du vet feilen ikke var til stede.
Trenger du DevOps?
Basert på det du har lest til nå høres kanskje dette spørsmålet ut som en "no brainer". Det høres jo mye bedre ut enn "gamlemåten"? Og etter min mening, så er det det. I de fleste tilfeller. Vi har et uttrykk i Norge som heter "å skyte spurv med kanon", og dette gjelder også i softwareutvikling. Svaret kommer an på hvor stort og avansert prosjektet er, og hvor mange involverte parter det har. Lager du en bloggside, som denne, er det mye mer "hassle" enn nødvendig å oppfylle alle DevOps-prinsippene. Jeg trenger kun å vite om bloggen er oppe og kjører som forventet, og ikke akkurat hvor mange % CPUen på serveren er på. Å sette opp enhetstester, integrasjonstester og logging tar dessuten tid og krefter som kunne vært brukt på utvikling. Så mitt svar på spørsmålet blir:
- Er systemet relativt enkelt, lite og har få involverte personer: Nei.
- Ellers: Ja!
"Nei" i dette tilfellet betyr ikke at gode rutiner for kjappe releases og automatiske prosesser er uønsket, men at det ikke skal prioriteres å bruke mye tid på å sette opp, monitorere, og andre mer tradisjonelle "Ops"-oppgaver. Heldigvis gjør mange moderne teknologier det lett å gå kjapt fra utivkling til release i dag.
DevOps i praksis
Nå skal vi se hvordan DevOps kan se ut i praksis, inkludert å skrape overflaten av flere forskjellige verktøy som kan brukes.
Business case
Tenk deg en mikrotjeneste som prosesserer utførte transaksjoner og solgte produkter for en nettbutikk. Tjenesten skal plukke opp all info om salg, inkludert tidspunkt, produkt, kuponger brukt etc. Hensikten er å samle opp og bearbeide relevant data og generere dashboards som kan brukes for å ta gode avgjørelser for videreutvikling av produktene og justering av tilbud og priser. Denne tjenesten er svært nyttig og kritisk for salgs- og businness intelligence-avdelingene. Da tjenesten ble opprettet vedtok utviklere og prosjektleder følgende krav for quality assurance:
- Teste alt som testes kan.
- Verktøy og prosesser for å sørge for god kodekvalitet.
- Nøye monitorering av pågang og trafikk i tjenesten.
- Kort vei fra utvikling til produksjon ved hjelp av CI/CD-pipelines.
- Logging av unormale hendelser, og varsling til Slack ved enkelte kritiske feil. Loggene skal være lett tilgjengelige.
- Et testmiljø, altså en fungerende kopi av tjenesten hvor nye features kan testes ut før det sendes i produksjon.
En løsning
Mikrotjenesten er skrevet i Kotlin og Spring Boot, og hostes i Google Cloud Platform (GCP). Med dette i betraktning tar vi følgende teknologivalg:
- Vi skriver enhetstester med JUnit5. Vi driver testdreven utvikling, som betyr at vi skriver enhetstester for nye features før vi skriver koden. Vi bruker Mockk for å "mocke" oppførsel og data for koden vår der det er praktisk.
- For å sørge for god kodekvalitet gjør vi to ting:
- Vi bruker SonarQube for å analysere kode for bugs eller andre potensielle sikkerhetsproblemer, og ktlint for å sørge for at kodekonvensjoner og riktig formattering blir opprettholdt.
- Alle nye features skal til "master branch" gjennom Pull Requests og reviews på Github, og må godkjennes av minst 2 andre på teamet før det settes i produksjon.
- For monitorering tilbyr GCP en tjeneste som heter Cloud Monitoring, hvor vi setter opp dashboards for antall forespørsler, trafikk og transaksjoner i databasen, CPU-bruk og RAM-bruk over tid, og tilgjengelig plass i databasen. Prosjektlederen liker også Grafana, for der har h*n oversikt over alle de andre prosjektene h*n også styrer, så vi oppretter et dashboard med ulike metrikker der og.
- Vi ønsker det slik at alle endringer i "master branch" automatisk setter endringene ut til produksjon. Vi har også en "testing branch" som automatisk dytter endringer til testmiljøet vårt. For å gjøre dette bruker vi CircleCI. I "pipelinen" sørger vi for at alle enhetstester og kodeanalyser når minimumskrav, og at pipelinen brytes om noe går galt.
- Vi bruker Sentry for å plukke opp "exceptions", i tillegg til de meste kritiske loggmeldingene. Kritiske feil blir sendt til en Slack-kanal, mens katastrofale feil trigger SMS til prosjektleder. Utvikleren som må stå opp på natten og løse det blir veldig godt kompensert økonomisk, selvfølgelig!
- Vi har satt opp to prosjekter i Google Cloud, ett for produksjonsmiljøet, og ett for testmiljøet. For å ikke måtte klikke på de samme knappene i GCPs GUI flere ganger bruker vi "Infrastructure as Code" og moduler i Terraform. CircleCI plukker opp hvilken branch på Github som er endret og publiserer til riktig miljø.
Phew. Det blir plutselig mange bevegende deler. Så jeg håper at uttrykket "å skyte spurv med kanon" tas i betrakning før man går løs på DevOps!
Konklusjon
Om du ikke er kjent med disse prinsippene og teknologiene, må du ikke bli stressa om dette virket litt overveldende. For det er nettopp det. DevOps virket lenge for meg som et litt difust konsept. Etter hvert som man får erfaring med å jobbe på større prosjekter ser man fort nytten av DevOps, hvordan det kan benyttes, og hvordan det gjør utvikling lettere og mer sømløst. DevOps har utviklet seg til å bli et ganske stort fagfelt, og mange organisasjoner har dedikerte teams som jobber fulltid med å sette opp gode rutiner for utviklere for å gjøre DevOps så lett som mulig. Så med mindre du jobber på et slikt team trenger du ofte ikke kunne alle disse teknoligene ut og inn (det ville nok krevd noen år!), men jeg tror uansett det er nyttig å ha litt greie på prinsippene bak, og hvilke teknologier som er involvert i praksis.
Main image attribution: Illustrations vector created by freepik.