«Moln-native» eller helt enkelt «molnappar» skapas speciellt för att fungera i molninfrastrukturer. De bygger vanligtvis som ett set av svagt kopplade mikrotjÀnster, förpackade i containrar, som i sin tur hanteras av en molnplattform. SÄdana appar Àr som standard redo för fel, vilket innebÀr att de pÄ ett tillförlitligt sÀtt fungerar och kan skalas Àven vid allvarliga infrastruktursfel. En baksida Àr de uppsÀttningar av begrÀnsningar (kontrakt) som molnplattformen pÄlÀgger containertjÀnster för att kunna hantera dem automatiskt.

Med en klar insikt om nödvÀndigheten och vikten av att övergÄ till molnappar, vet mÄnga organisationer fortfarande inte var de ska börja. I detta inlÀgg kommer vi att utforska ett antal principer som, om de följs vid utvecklingen av containertjÀnster, kommer att möjliggöra att utnyttja potentialen hos molnplattformar och uppnÄ tillförlitlig funktion och skalning av appar Àven vid allvarliga IT-infrastrukturfel. Det slutliga mÄlet med de principer som presenteras hÀr Àr att lÀra sig att skapa appar som kan hanteras automatiskt av molnplattformar, sÄsom Kubernetes.
Principer för mjukvarudesign
Inom programmering refererar principer till ganska allmÀnna regler som mÄste följas vid utveckling av programvara. De kan tillÀmpas pÄ vilket programmeringssprÄk som helst. Varje princip har sina egna mÄl, vars verktyg ofta Àr mallar och praxis. Det finns ocksÄ en uppsÀttning grundlÀggande principer för att skapa kvalitetsmjukvara, frÄn vilka alla andra principiellt följer. LÄt oss ge exempel pÄ grundlÀggande principer:
- (Keep it simple, stupid) â hĂ„ll det enkelt;
- (Donât repeat yourself) â upprepa inte;
- (You arenât gonna need it) â skapa inte det som inte Ă€r omedelbart nödvĂ€ndigt;
- (Separation of concerns) â separera ansvar.
Som vi kan se anger dessa principer inga specifika regler, utan tillhör en kategori av sÄ kallade sunt förnuft-betraktelser baserade pÄ praktisk erfarenhet, som mÄnga utvecklare delar och som de regelbundet hÀnvisar till.
Dessutom finns det â en uppsĂ€ttning av de första fem principerna för objektorienterad programmering och design, formulerade av Robert Martin. SOLID omfattar allmĂ€nna och öppna för tolkning komplementĂ€ra principer som, om de tillĂ€mpas tillsammans, hjĂ€lper till att skapa mer kvalitativa mjukvarusystem och bĂ€ttre underhĂ„lla dem pĂ„ lĂ„ng sikt.
SOLID-principerna relaterar till OOP och formuleras pÄ ett sprÄk av sÄdana begrepp och koncept som klasser, grÀnssnitt och arv. PÄ samma sÀtt kan det ocksÄ formuleras utvecklingsprinciper för molnapplikationer, dÀr den grundlÀggande enheten inte Àr en klass, utan en container. Genom att följa dessa principer kan man skapa containerapplikationer som bÀttre svarar mot mÄlen och behoven hos molnplattformar sÄsom Kubernetes.
Molnorienterade containrar: Red Hat-ansatsen
I dag kan nÀstan vilken applikation som helst relativt enkelt packas i containrar. Men för att applikationer effektivt automatiseras och orkestreras inom en molnplattform som Kubernetes krÀvs det ytterligare insatser.
Grunden för de idĂ©er som presenteras nedan Ă€r metodologin och mĂ„nga andra arbeten som rör olika aspekter av att skapa webbapplikationer, frĂ„n hantering av kĂ€llkod till skalningsmodeller. De principer som beskrivs gĂ€ller endast utveckling av containerapplikationer som Ă€r uppbyggda pĂ„ mikrotjĂ€nster och avsedda för molnplattformar som Kubernetes. Den grundlĂ€ggande enheten i vĂ„ra resonemang Ă€r containeravbildningen, och den avsedda körmiljön för containrar definieras som en plattform för orkestrering av containrar. MĂ„let med de föreslagna principerna Ă€r att skapa containrar för vilka man pĂ„ de flesta orkestreringsplattformar kan automatisera schemalĂ€ggningsuppgifter (scheduling â valet av vĂ€rd för att köra en container-instans), skalning och övervakning. Principerna presenteras i godtycklig ordning.
Principen om en enda uppgift (Single Concern Principle, SCP)
Denna princip liknar i stor utstrÀckning principen om en enda ansvarighet (Single Responsibility Principle, ), som ingÄr i SOLID-settet och sÀger att varje objekt ska ha ett enda ansvar, och detta ansvar ska vara helt inkapslat i klassen. KÀrnan i SRP Àr att varje ansvar Àr en orsak till förÀndringar, och klassen ska ha en och endast en orsak till förÀndring.
I SCP anvÀnder vi ordet "uppgift" (concern) istÀllet för "ansvar" (responsibility) för att indikera en högre abstraktionsnivÄ och en bredare syftning för containern jÀmfört med OOP-klassen. Och om mÄlet med SRP Àr att ha endast en orsak till förÀndringar, sÄ ligger syftet med SCP i att öka möjligheterna till ÄteranvÀndning och ersÀttning av containrar. Genom att följa SRP och skapa en container som löser en enda uppgift pÄ ett funktionellt fullstÀndigt sÀtt ökar du chansen att ÄteranvÀnda denna container i olika applikationssammanhang.
SCP-principen sÀger att varje container ska lösa en enda uppgift och göra det bra. Dessutom uppnÄs SCP i vÀrlden av containrar enklare Àn SRP i OOP-vÀrlden, eftersom containrar vanligtvis utför en enda process, och det mesta av tiden handlar denna process om att lösa en enda uppgift.
Om en viss container-mikrotjÀnst mÄste lösa flera uppgifter kan den delas upp i enuppgiftcontainrar och sammanfogas inom en pod (en enhet för driftsÀttning av containerplattformen) med hjÀlp av sidecar-mallar och init-containrar. Dessutom underlÀttar SCP ersÀttningen av en gammal container (till exempel en webbserver eller meddelandebroker) med en ny som löser samma uppgift men har utökad funktionalitet eller bÀttre skalbarhet.

Principen för hög observerbarhet (High Observability Principle, HOP)
NÀr man anvÀnder containrar som en enhetlig metod för att paketera och köra applikationer betraktas sjÀlva applikationen som en "svart ruta". Om det handlar om molncontainrar mÄste de dock tillhandahÄlla specifika API:er för körmiljön för att övervaka containerstatus och vid behov vidta lÀmpliga ÄtgÀrder. Utan detta kan man inte standardisera automatisering av containeruppdateringar och hantering av deras livscykel, vilket i sin tur försÀmrar systemets stabilitet och anvÀndbarhet.
I praktiken bör en containerapplikation minst ha API:er för olika typer av hÀlsokontroller: livstrÀningstester (liveness) och beredskapstester (readiness). Om applikationen gör ansprÄk pÄ mer, bör den ocksÄ erbjuda andra medel för att kontrollera sitt tillstÄnd. Till exempel registrering av viktiga hÀndelser via STDERR och STDOUT för aggregering av loggar med hjÀlp av Fluentd, Logstash och andra liknande verktyg. Dessutom krÀvs integration med spÄrbibliotek och metrikinsamling, sÄsom OpenTracing, Prometheus, m.m.
Generellt kan applikationen fortfarande betraktas som en "svart ruta", men den mÄste utrustas med alla API:er som plattformen behöver för att övervaka och hantera den pÄ bÀsta sÀtt.
LivscykelöverensstÀmmelseprincipen (Life-cycle Conformance Principle, LCP)
LCP Àr en kontrast till HOP. Medan HOP anger att containern ska tillhandahÄlla plattformen API:er för lÀsning, krÀver LCP att applikationen har förmÄga att ta emot information frÄn plattformen. Dessutom ska containern inte bara ta emot hÀndelser, utan ocksÄ anpassa sig, det vill sÀga reagera pÄ dem. DÀrav namnet pÄ principen, som kan ses som ett krav pÄ att tillhandahÄlla plattformen API:er för skrivning.

Plattformar har olika typer av hÀndelser som hjÀlper till att hantera livscykeln för containern. Men det Àr applikationen som ska bestÀmma vilka av dessa den ska uppfatta och hur den ska reagera.
Det Àr uppenbart att vissa hÀndelser Àr viktigare Àn andra. Till exempel, om en applikation inte tÄl ett katastrofalt avslut, mÄste den kunna ta emot signaler som signal: terminate (SIGTERM) och sÄ snabbt som möjligt initiera sin avslutningsprocedur för att hinna innan signal: kill (SIGKILL) kommer, vilket sker efter SIGTERM.
Dessutom kan hÀndelser som PostStart och PreStop vara viktiga för applikationens livscykel. Till exempel kan en applikation behöva viss tid för ''uppvÀrmning'' efter lansering innan den kan svara pÄ förfrÄgningar. Eller sÄ mÄste applikationen pÄ nÄgot sÀrskilt sÀtt frigöra resurser vid avslut.
Principen om oförÀnderliga containerbilder (Image Immutability Principle, IIP)
Det Àr allmÀnt accepterat att containerapplikationer ska förbli oförÀndrade efter byggnation, Àven om de körs i olika miljöer. DÀrför uppstÄr behovet av att externisera datalagring under körning (det vill sÀga anvÀnda externa medel för detta), samt att förlita sig pÄ externa, miljöspecifika konfigurationer istÀllet för att modifiera eller skapa unika containrar för varje miljö. Efter alla Àndringar i applikationen mÄste containerbilden byggas om och distribueras i alla anvÀnda miljöer. För övrigt anvÀnds en liknande princip vid hantering av IT-system, kÀnd som principen om oförÀnderliga servrar och infrastruktur.
MÄlet med IIP Àr att förhindra skapandet av separata containerbilder för olika körmiljöer och istÀllet anvÀnda samma bild överallt tillsammans med en lÀmplig konfiguration för den specifika miljön. Att följa denna princip möjliggör implementering av sÄdana viktiga praktiker för automatisering av molnsystem som ÄterstÀllning (roll-back) och framgÄng av uppdateringar av applikationen (roll-forward).

Principen om engÄngsanvÀndning av processer (Process Disposability Principle, PDP)
En av de viktigaste egenskaperna hos en container Àr dess ephemeralitet: en containerinstans kan lÀtt skapas och lÀtt förstöras, vilket gör att den nÀr som helst enkelt kan ersÀttas med en annan instans. Det finns mÄnga anledningar till att en sÄdan ersÀttning kan behövas: ett misslyckat hÀlsotest, skalning av applikationen, flytt till en annan vÀrd, resursbrist pÄ plattformen eller andra situationer.
Som följd av detta mÄste containerbaserade applikationer spara sitt tillstÄnd med hjÀlp av externa medel, eller anvÀnda interna distribuerade scheman med redundans. Dessutom mÄste applikationen kunna starta snabbt och stÀngas av snabbt, samt vara förberedd för plötsliga fatala hÄrdvarufel.
En av metoderna som hjĂ€lper till att uppnĂ„ detta princip Ă€r att skapa smĂ„ containrar. Molnmiljöer kan automatiskt vĂ€lja vĂ€rden för att köra containerinstanser, sĂ„ ju mindre storleken pĂ„ containern Ă€r, desto snabbare kan den startas â den kopieras helt enkelt snabbare till mĂ„lvĂ€rden via nĂ€tverket.
Principen om sjÀlvförsörjning (Self-containment Principle, S-CP)
Enligt denna princip inkluderar containern alla nödvÀndiga komponenter under byggfasen. Containern ska byggas med hÀnsyn till att endast en ren Linux-kÀrna finns i systemet, sÄ alla nödvÀndiga ytterligare bibliotek mÄste placeras i sjÀlva containern. DÀr bör ocksÄ finnas saker som körmiljön för motsvarande programmeringssprÄk, applikationsplattform (om nödvÀndigt) och andra beroenden som behövs under arbetet med containerapplikationen.

Undantag görs endast för konfigurationer som varierar frÄn miljö till miljö och som mÄste tillhandahÄllas under körning, till exempel genom Kubernetes ConfigMap.
Applikationen kan bestÄ av flera containeriserade komponenter, som en separat databascontainer inom en containerbaserad webbapplikation. Enligt principen S-CP ska dessa containrar inte slÄs ihop till en utan göras sÄ att databascontainern innehÄller allt som krÀvs för att driva databasen, medan webbapplikationscontainern innehÄller allt som behövs för att driva webbapplikationen, sÄsom webbservern. Som ett resultat kommer webbapplikationscontainern under körning att bero pÄ databascontainern och komma i kontakt med den vid behov.
Principen om begrÀnsning vid körning (Runtime Confinement Principle, RCP)
Principen S-CP definierar hur containern ska byggas och vad den binĂ€ra bildfilen ska innehĂ„lla. Men containern Ă€r inte bara en "svart lĂ„da" med en endast en egenskap â filstorlek. Under körning fĂ„r containern andra dimensioner: mĂ€ngden anvĂ€nd minne, processortid och andra systemresurser.

HÀr kommer principen RCP in, enligt vilken containern ska separera sina krav pÄ systemresurser och överföra dem till plattformen. Genom att ha resursprofiler för varje container (hur mycket CPU, minne, nÀtverk och lagringsresurser den behöver), kan plattformen optimalt utföra schemalÀggning och automatisk skalning, hantera IT-kapacitet och upprÀtthÄlla SLA-nivÄer för containrar.
Förutom att tillgodose behoven för containerresurser Àr det ocksÄ viktigt för applikationen att inte överskrida de grÀnser som den sjÀlv angivit. Annars, vid brist pÄ resurser, Àr det mer sannolikt att plattformen inkluderar den pÄ listan över applikationer som ska avbrytas eller migreras.
NÀr vi pratar om molnorientering menar vi först och frÀmst hur arbetet utförs.
Som nÀmnts ovan har vi formulerat en rad allmÀnna principer som utgör den metodologiska grunden för att bygga kvalitativa containerapplikationer för molnmiljöer.
Observera att utöver dessa allmÀnna principer kommer du ocksÄ att behöva ytterligare avancerade metoder och tekniker för att arbeta med containrar. Dessutom har vi nÄgra korta rekommendationer som Àr mer specifika och bör tillÀmpas (eller inte tillÀmpas) beroende pÄ situationen:
- StrĂ€va efter att minska bilders storlek: ta bort tillfĂ€lliga filer och installera inte onödiga paket â ju mindre storleken pĂ„ containern, desto snabbare byggs och kopieras den till mĂ„lhardvaran via nĂ€tverket.
- Fokusera pÄ godtyckliga anvÀndar-ID:n: anvÀnd inte kommandot sudo eller nÄgra speciella userid för att köra dina containrar.
- MĂ€rk viktiga portar: portnummer kan anges under körning, men det Ă€r bĂ€ttre att ange dem med kommandot EXPOSE â det blir enklare för andra mĂ€nniskor och program att anvĂ€nda dina bilder.
- Spara bestÀndiga data pÄ volymer: data som ska finnas kvar efter att containern har raderats bör skrivas till volymer.
- Skriv ner bildens metadata: taggar, etiketter och anteckningar underlĂ€ttar anvĂ€ndningen av bilder â andra utvecklare kommer att uppskatta det.
- Synkronisera vÀrden och bilder: vissa containerapplikationer krÀver synkronisering av containern med vÀrden baserat pÄ vissa attribut, sÄsom tid eller maskinidentifierare.
- Avslutningsvis delar vi med oss av mallar och bÀsta praxis som hjÀlper till att effektivisera implementeringen av ovanstÄende principer:
11 juni kl. 11.00
Vad du kommer att lÀra dig:
- Immutable Red Hat Enterprise Linux CoreOS
- OpenShift service mesh
- Operator framework
- Knative framework
KĂ€lla: habr.com
