Dela via


Utnyttja containrar och orkestrerare

Dricks

Det här innehållet är ett utdrag från eBook, Architecting Cloud Native .NET Applications for Azure, tillgängligt på .NET Docs eller som en kostnadsfri nedladdningsbar PDF som kan läsas offline.

Cloud Native .NET apps for Azure eBook cover thumbnail.

Containrar och orkestrerare är utformade för att lösa problem som är gemensamma för monolitiska distributionsmetoder.

Utmaningar med monolitiska distributioner

Traditionellt har de flesta program distribuerats som en enda enhet. Sådana program kallas för en monolit. Den här allmänna metoden för att distribuera program som enskilda enheter även om de består av flera moduler eller sammansättningar kallas monolitisk arkitektur, enligt bild 3–1.

Monolithic architecture.

Bild 3-1. Monolitisk arkitektur.

Även om de har fördelen av enkelhet, står monolitiska arkitekturer inför många utmaningar:

Distribution

Dessutom kräver de en omstart av programmet, vilket tillfälligt kan påverka tillgängligheten om nollavbrottstekniker inte tillämpas under distributionen.

Skalning

Ett monolitiskt program hanteras helt på en enda datorinstans, vilket ofta kräver maskinvara med hög kapacitet. Om någon del av monoliten kräver skalning måste en annan kopia av hela programmet distribueras till en annan dator. Med en monolit kan du inte skala programkomponenter individuellt – det är allt eller inget. Skalning av komponenter som inte kräver skalning resulterar i ineffektiv och kostsam resursanvändning.

Environment

Monolitiska program distribueras vanligtvis till en värdmiljö med ett förinstallerat operativsystem, körnings- och biblioteksberoenden. Den här miljön kanske inte matchar den miljö där programmet har utvecklats eller testats. Inkonsekvenser i programmiljöer är en vanlig källa till problem för monolitiska distributioner.

Koppling

Ett monolitiskt program kommer sannolikt att uppleva hög koppling mellan dess funktionella komponenter. Utan hårda gränser resulterar systemändringar ofta i oavsiktliga och kostsamma biverkningar. Nya funktioner/korrigeringar blir knepiga, tidskrävande och dyra att implementera. Uppdateringar kräver omfattande testning. Koppling gör det också svårt att omstrukturera komponenter eller växla i alternativa implementeringar. Även när den konstrueras med en strikt uppdelning av bekymmer, sätter arkitektonisk erosion in när den monolitiska kodbasen försämras med oändliga "specialfall".

Plattformslåsning

Ett monolitiskt program är konstruerat med en enda teknikstack. Samtidigt som detta åtagande erbjuder enhetlighet kan det bli ett hinder för innovation. Nya funktioner och komponenter kommer att skapas med hjälp av programmets aktuella stack – även om modernare tekniker kan vara ett bättre val. En mer långsiktig risk är att din teknikstack blir föråldrad och föråldrad. Att omarbeta ett helt program till en ny, modernare plattform är i bästa fall dyrt och riskabelt.

Vilka är fördelarna med containrar och orkestrerare?

Vi introducerade containrar i kapitel 1. Vi lyfte fram hur Cloud Native Computing Foundation (CNCF) rankar containerisering som det första steget i deras molnbaserade trailkarta – vägledning för företag som påbörjar sin molnbaserade resa. I det här avsnittet diskuterar vi fördelarna med containrar.

Docker är den mest populära containerhanteringsplattformen. Det fungerar med containrar på både Linux eller Windows. Containrar tillhandahåller separata men reproducerbara programmiljöer som körs på samma sätt på alla system. Den här aspekten gör dem perfekta för att utveckla och hantera molnbaserade tjänster. Containrar är isolerade från varandra. Två containrar på samma värdmaskinvara kan ha olika versioner av programvara, utan att orsaka konflikter.

Containrar definieras av enkla textbaserade filer som blir projektartefakter och checkas in i källkontrollen. Även om fullständiga servrar och virtuella datorer kräver manuella åtgärder för att uppdatera, är containrar enkelt versionsstyrda. Appar som skapats för att köras i containrar kan utvecklas, testas och distribueras med hjälp av automatiserade verktyg som en del av en bygg-pipeline.

Containrar är oföränderliga. När du har definierat en container kan du återskapa och köra den på exakt samma sätt. Den här oföränderligheten lämpar sig för komponentbaserad design. Om vissa delar av ett program utvecklas annorlunda än andra, varför distribuera om hela appen när du bara kan distribuera de delar som ändras oftast? Olika funktioner och övergripande problem med en app kan delas upp i separata enheter. Bild 3–2 visar hur en monolitisk app kan dra nytta av containrar och mikrotjänster genom att delegera vissa funktioner eller funktioner. De återstående funktionerna i själva appen har också containeriserats.

Breaking up a monolithic app to use microservices in the back end.

Bild 3-2. Dela upp en monolitisk app för att omfatta mikrotjänster.

Varje molnbaserad tjänst skapas och distribueras i en separat container. Var och en kan uppdateras efter behov. Enskilda tjänster kan finnas på noder med resurser som är lämpliga för varje tjänst. Miljön som varje tjänst körs i är oföränderlig, delas mellan utvecklings-, test- och produktionsmiljöer och är lätt att versionshantera. Koppling mellan olika områden i programmet sker explicit som anrop eller meddelanden mellan tjänster, inte kompileringstidsberoenden i monoliten. Du kan också välja den teknik som passar bäst för en viss funktion utan att kräva ändringar i resten av appen.

Containerbaserade tjänster kräver automatiserad hantering. Det skulle inte vara möjligt att administrera en stor uppsättning oberoende distribuerade containrar manuellt. Tänk till exempel på följande uppgifter:

  • Hur etableras containerinstanser i ett kluster med många datorer?
  • Hur identifierar och kommunicerar containrar med varandra när de har distribuerats?
  • Hur kan containrar skalas in eller ut på begäran?
  • Hur övervakar du hälsotillståndet för varje container?
  • Hur skyddar du en container mot maskinvaru- och programvarufel?
  • Hur uppgraderar du containrar för ett live-program utan driftstopp?

Containerorkestratorer hanterar och automatiserar dessa och andra problem.

I det molnbaserade ekosystemet har Kubernetes blivit de facto-containerorkestreraren. Det är en plattform med öppen källkod som hanteras av Cloud Native Computing Foundation (CNCF). Kubernetes automatiserar distributionen, skalningen och driftsproblemen för containerbaserade arbetsbelastningar i ett datorkluster. Att installera och hantera Kubernetes är dock notoriskt komplext.

En mycket bättre metod är att använda Kubernetes som en hanterad tjänst från en molnleverantör. Azure-molnet har en fullständigt hanterad Kubernetes-plattform med titeln Azure Kubernetes Service (AKS). AKS sammanfattar komplexiteten och driftskostnaderna för att hantera Kubernetes. Du använder Kubernetes som en molntjänst. Microsoft tar ansvar för att hantera och stödja det. AKS integreras också nära med andra Azure-tjänster och utvecklingsverktyg.

AKS är en klusterbaserad teknik. En pool med federerade virtuella datorer eller noder distribueras till Azure-molnet. Tillsammans bildar de en miljö med hög tillgänglighet eller ett kluster. Klustret visas som en sömlös, enskild entitet till ditt molnbaserade program. Under huven distribuerar AKS dina containerbaserade tjänster över dessa noder enligt en fördefinierad strategi som distribuerar belastningen jämnt.

Vilka är skalningsfördelarna?

Tjänster som bygger på containrar kan dra nytta av skalningsfördelar som tillhandahålls av orkestreringsverktyg som Kubernetes. Efter design vet containrar bara om sig själva. När du har flera containrar som behöver arbeta tillsammans bör du organisera dem på en högre nivå. Organisera ett stort antal containrar och deras delade beroenden, till exempel nätverkskonfiguration, är den plats där orkestreringsverktyg kommer in för att spara dagen! Kubernetes skapar ett abstraktionslager över grupper av containrar och organiserar dem i poddar. Poddar körs på arbetsdatorer som kallas noder. Den här organiserade strukturen kallas för ett kluster. Bild 3–3 visar de olika komponenterna i ett Kubernetes-kluster.

Kubernetes cluster components.Bild 3-3. Kubernetes-klusterkomponenter.

Skalning av containerbaserade arbetsbelastningar är en viktig funktion i containerorkestrerare. AKS stöder automatisk skalning över två dimensioner: Containerinstanser och beräkningsnoder. Tillsammans ger de AKS möjlighet att snabbt och effektivt svara på toppar i efterfrågan och lägga till ytterligare resurser. Vi diskuterar skalning i AKS senare i det här kapitlet.

Deklarativ kontra imperativ

Kubernetes stöder både deklarativ och imperativ konfiguration. Den imperativa metoden innebär att köra olika kommandon som talar om för Kubernetes vad de ska göra varje steg på vägen. Kör den här avbildningen. Ta bort podden. Exponera den här porten. Med den deklarativa metoden skapar du en konfigurationsfil som kallas manifest för att beskriva vad du vill ha i stället för vad du ska göra. Kubernetes läser manifestet och omvandlar önskat sluttillstånd till verkligt sluttillstånd.

Imperativa kommandon är bra för inlärning och interaktiva experiment. Du vill dock deklarativt skapa Kubernetes-manifestfiler för att använda en infrastruktur som kodmetod, vilket ger tillförlitliga och repeterbara distributioner. Manifestfilen blir en projektartefakt och används i CI/CD-pipelinen för att automatisera Kubernetes-distributioner.

Om du redan har konfigurerat klustret med imperativa kommandon kan du exportera ett deklarativt manifest med hjälp kubectl get svc SERVICENAME -o yaml > service.yamlav . Det här kommandot genererar ett manifest som liknar det som visas nedan:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2019-09-13T13:58:47Z"
  labels:
    component: apiserver
    provider: kubernetes
  name: kubernetes
  namespace: default
  resourceVersion: "153"
  selfLink: /api/v1/namespaces/default/services/kubernetes
  uid: 9b1fac62-d62e-11e9-8968-00155d38010d
spec:
  clusterIP: 10.96.0.1
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: 6443
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

När du använder deklarativ konfiguration kan du förhandsgranska de ändringar som ska göras innan du genomför dem med hjälp kubectl diff -f FOLDERNAME av mot mappen där konfigurationsfilerna finns. När du är säker på att du vill tillämpa ändringarna kör du kubectl apply -f FOLDERNAME. Lägg till -R för att rekursivt bearbeta en mapphierarki.

Du kan också använda deklarativ konfiguration med andra Kubernetes-funktioner, varav en är distributioner. Deklarativa distributioner hjälper till att hantera versioner, uppdateringar och skalning. De instruerar Kubernetes-distributionskontrollanten om hur du distribuerar nya ändringar, skalar ut belastningen eller återställer till en tidigare revision. Om ett kluster är instabilt returnerar en deklarativ distribution automatiskt klustret tillbaka till önskat tillstånd. Om en nod till exempel kraschar distribuerar distributionsmekanismen om en ersättning för att uppnå önskat tillstånd

Med deklarativ konfiguration kan infrastrukturen representeras som kod som kan checkas in och versionshanteras tillsammans med programkoden. Det ger förbättrad ändringskontroll och bättre stöd för kontinuerlig distribution med hjälp av en bygg- och distributionspipeline.

Vilka scenarier är idealiska för containrar och orkestrerare?

Följande scenarier är idealiska för att använda containrar och orkestrerare.

Program som kräver hög drifttid och skalbarhet

Enskilda program som har höga krav på drifttid och skalbarhet är idealiska kandidater för molnbaserade arkitekturer med hjälp av mikrotjänster, containrar och orkestrerare. De kan utvecklas i containrar, testas i versionsmiljöer och distribueras till produktion utan driftstopp. Användningen av Kubernetes-kluster säkerställer att sådana appar också kan skalas på begäran och återställas automatiskt från nodfel.

Stort antal program

Organisationer som distribuerar och underhåller ett stort antal program drar nytta av containrar och orkestrerare. Det främsta arbetet med att konfigurera containerbaserade miljöer och Kubernetes-kluster är främst en fast kostnad. Att distribuera, underhålla och uppdatera enskilda program har en kostnad som varierar med antalet program. Utöver några få program överskrider komplexiteten med att underhålla anpassade program manuellt kostnaden för att implementera en lösning med hjälp av containrar och orkestrerare.

När bör du undvika att använda containrar och orkestrerare?

Om du inte kan skapa ditt program enligt principerna för tolvfaktorappar bör du överväga att undvika containrar och orkestrerare. I dessa fall bör du överväga en VM-baserad värdplattform eller eventuellt något hybridsystem. Med den kan du alltid knoppa av vissa funktioner i separata containrar eller till och med serverlösa funktioner.

Utvecklingsresurser

Det här avsnittet visar en kort lista över utvecklingsresurser som kan hjälpa dig att komma igång med containrar och orkestrerare för nästa program. Om du letar efter vägledning om hur du utformar din molnbaserade arkitekturapp för mikrotjänster kan du läsa den här bokens tilläggsapp, .NET Microservices: Architecture for Containerized .NET Applications.

Lokal Kubernetes-utveckling

Kubernetes-distributioner ger bra värde i produktionsmiljöer, men kan även köras lokalt på utvecklingsdatorn. Även om du kan arbeta med enskilda mikrotjänster oberoende av varandra kan det finnas tillfällen då du behöver köra hela systemet lokalt – precis som när det distribueras till produktion. Det finns flera verktyg som kan hjälpa dig: Minikube och Docker Desktop. Visual Studio innehåller även verktyg för Docker-utveckling.

Minikube

Vad är Minikube? Minikube-projektet säger "Minikube implementerar ett lokalt Kubernetes-kluster på macOS, Linux och Windows." Dess främsta mål är "att vara det bästa verktyget för lokal Kubernetes-programutveckling och att stödja alla Kubernetes-funktioner som passar." Installation av Minikube är separat från Docker, men Minikube stöder olika hypervisor-enheter än vad Docker Desktop stöder. Följande Kubernetes-funktioner stöds för närvarande av Minikube:

  • DNS
  • NodePorts
  • Konfiguration Kartor och hemligheter
  • Instrumentpaneler
  • Containerkörningar: Docker, rkt, CRI-O och containerd
  • Aktivera CNI (Container Network Interface)
  • Ingress

När du har installerat Minikube kan du snabbt börja använda det genom att köra minikube start kommandot som laddar ned en avbildning och startar det lokala Kubernetes-klustret. När klustret har startats interagerar du med det med kubernetes-standardkommandona kubectl .

Docker Desktop

Du kan också arbeta med Kubernetes direkt från Docker Desktop i Windows. Det är ditt enda alternativ om du använder Windows-containrar och är ett bra val även för containrar som inte är Windows-containrar. Bild 3–4 visar hur du aktiverar lokalt Kubernetes-stöd när du kör Docker Desktop.

Configuring Kubernetes in Docker Desktop

Bild 3-4. Konfigurera Kubernetes i Docker Desktop.

Docker Desktop är det mest populära verktyget för att konfigurera och köra containerbaserade appar lokalt. När du arbetar med Docker Desktop kan du utveckla lokalt mot exakt samma uppsättning Docker-containeravbildningar som du ska distribuera till produktion. Docker Desktop är utformat för att "skapa, testa och skicka" containerbaserade appar lokalt. Det stöder både Linux- och Windows-containrar. När du har push-överfört dina avbildningar till ett avbildningsregister, till exempel Azure Container Registry eller Docker Hub, kan AKS hämta och distribuera dem till produktion.

Visual Studio Docker-verktyg

Visual Studio stöder Docker-utveckling för webbaserade program. När du skapar ett nytt ASP.NET Core-program kan du konfigurera det med Docker-stöd, enligt bild 3–5.

Visual Studio Enable Docker Support

Bild 3-5. Visual Studio Aktivera Docker-stöd

När det här alternativet har valts skapas projektet med en Dockerfile i roten, som kan användas för att skapa och vara värd för appen i en Docker-container. Ett exempel på Dockerfile visas i bild 3-6.

FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["eShopWeb/eShopWeb.csproj", "eShopWeb/"]
RUN dotnet restore "eShopWeb/eShopWeb.csproj"
COPY . .
WORKDIR "/src/eShopWeb"
RUN dotnet build "eShopWeb.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "eShopWeb.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "eShopWeb.dll"]

Bild 3-6. Visual Studio-genererad Dockerfile

När stödet har lagts till kan du köra programmet i en Docker-container i Visual Studio. Bild 3–7 visar de olika körningsalternativen som är tillgängliga från ett nytt ASP.NET Core-projekt som skapats med Docker-stöd tillagt.

Visual Studio Docker Run Options

Bild 3-7. Alternativ för Visual Studio Docker-körning

Du kan också när som helst lägga till Docker-stöd i ett befintligt ASP.NET Core-program. I Visual Studio Solution Explorer högerklickar du på projektet och väljer Lägg till>Docker-stöd, enligt bild 3–8.

Visual Studio Add Docker Support

Bild 3-8. Lägga till Docker-stöd i Visual Studio

Visual Studio Code Docker-verktyg

Det finns många tillägg för Visual Studio Code som stöder Docker-utveckling.

Microsoft tillhandahåller Docker för Visual Studio Code-tillägget. Det här tillägget förenklar processen med att lägga till containerstöd i program. Den skapar nödvändiga filer, skapar Docker-avbildningar och gör att du kan felsöka din app i en container. Tillägget har en visuell utforskare som gör det enkelt att vidta åtgärder på containrar och bilder, till exempel starta, stoppa, inspektera, ta bort med mera. Tillägget stöder även Docker Compose så att du kan hantera flera containrar som körs som en enda enhet.