Gebruik maken van containers en orchestrators
Tip
Deze inhoud is een fragment uit het eBook, Cloud Native .NET Applications for Azure ontwerpen, beschikbaar op .NET Docs of als een gratis downloadbare PDF die offline kan worden gelezen.
Containers en orchestrators zijn ontworpen om problemen op te lossen die vaak voorkomen bij monolithische implementatiemethoden.
Uitdagingen met monolithische implementaties
De meeste toepassingen zijn traditioneel geïmplementeerd als één eenheid. Dergelijke toepassingen worden een monolith genoemd. Deze algemene benadering van het implementeren van toepassingen als één eenheid, zelfs als ze bestaan uit meerdere modules of assembly's, wordt monolithische architectuur genoemd, zoals wordt weergegeven in afbeelding 3-1.
Afbeelding 3-1. Monolithische architectuur.
Hoewel ze het voordeel hebben van eenvoud, hebben monolithische architecturen veel uitdagingen:
Implementatie
Daarnaast moeten ze de toepassing opnieuw opstarten, wat tijdelijk van invloed kan zijn op de beschikbaarheid als er geen downtimetechnieken worden toegepast tijdens de implementatie.
Schalen
Een monolithische toepassing wordt volledig gehost op één computerexemplaren, waarvoor vaak hardware met hoge capaciteit is vereist. Als een deel van de monolith moet worden geschaald, moet een andere kopie van de hele toepassing worden geïmplementeerd op een andere computer. Met een monolith kunt u toepassingsonderdelen niet afzonderlijk schalen. Dit is alles of niets. Het schalen van onderdelen waarvoor geen schaalaanpassing is vereist, resulteert in inefficiënt en kostbaar resourcegebruik.
Omgeving
Monolithische toepassingen worden doorgaans geïmplementeerd in een hostingomgeving met een vooraf geïnstalleerd besturingssysteem, runtime en bibliotheekafhankelijkheden. Deze omgeving mag niet overeenkomen met die waarop de toepassing is ontwikkeld of getest. Inconsistenties in toepassingsomgevingen zijn een veelvoorkomende bron van problemen voor monolithische implementaties.
Koppeling
Een monolithische toepassing ondervindt waarschijnlijk een hoge koppeling tussen de functionele onderdelen. Zonder harde grenzen leiden systeemwijzigingen vaak tot onbedoelde en kostbare bijwerkingen. Nieuwe functies/oplossingen worden lastig, tijdrovend en duur om te implementeren. Updates vereisen uitgebreide tests. Het koppelen maakt het ook moeilijk om onderdelen te herstructureren of te wisselen in alternatieve implementaties. Zelfs wanneer ze zijn gebouwd met een strikte scheiding van zorgen, wordt architectuurerosie ingesteld als de monolithische codebasis verslechtert met nooit-eindigende 'speciale gevallen'.
Platformvergrendeling
Een monolithische toepassing wordt samengesteld met één technologiestack. Hoewel het aanbieden van uniformiteit, kan deze toezegging een belemmering voor innovatie worden. Nieuwe functies en onderdelen worden gebouwd met behulp van de huidige stack van de toepassing, zelfs wanneer modernere technologieën een betere keuze kunnen zijn. Een risico op de langere termijn is dat uw technologiestack verouderd en verouderd wordt. Het opnieuw ontwerpen van een hele toepassing naar een nieuw, moderner platform is het beste duur en riskant.
Wat zijn de voordelen van containers en orchestrators?
We hebben containers geïntroduceerd in hoofdstuk 1. We hebben gemarkeerd hoe de Cloud Native Computing Foundation (CNCF) containerisatie rangschikt als de eerste stap in hun Cloud-Native Trail Map - richtlijnen voor ondernemingen die hun cloudeigen traject beginnen. In deze sectie bespreken we de voordelen van containers.
Docker is het populairste containerbeheerplatform. Het werkt met containers in zowel Linux als Windows. Containers bieden afzonderlijke, maar reproduceerbare toepassingsomgevingen die op dezelfde manier op elk systeem worden uitgevoerd. Dit aspect maakt ze perfect voor het ontwikkelen en hosten van cloudeigen services. Containers worden geïsoleerd van elkaar. Twee containers op dezelfde hosthardware kunnen verschillende versies van software hebben, zonder conflicten te veroorzaken.
Containers worden gedefinieerd door eenvoudige op tekst gebaseerde bestanden die projectartefacten worden en worden ingecheckt bij broncodebeheer. Hoewel voor volledige servers en virtuele machines handmatige inspanningen nodig zijn om bij te werken, zijn containers eenvoudig versiebeheerd. Apps die zijn gebouwd om in containers te worden uitgevoerd, kunnen worden ontwikkeld, getest en geïmplementeerd met behulp van geautomatiseerde hulpprogramma's als onderdeel van een build-pijplijn.
Containers zijn onveranderbaar. Zodra u een container hebt gedefinieerd, kunt u deze op dezelfde manier opnieuw maken en uitvoeren. Deze onveranderbaarheid leent zich voor ontwerp op basis van onderdelen. Als sommige onderdelen van een toepassing zich anders ontwikkelen dan andere, waarom moet u de hele app opnieuw implementeren wanneer u alleen de onderdelen kunt implementeren die het vaakst veranderen? Verschillende functies en kruislingse zorgen van een app kunnen worden onderverdeeld in afzonderlijke eenheden. Afbeelding 3-2 laat zien hoe een monolithische app kan profiteren van containers en microservices door bepaalde functies of functionaliteit te delegeren. De resterende functionaliteit in de app zelf is ook in een container geplaatst.
Afbeelding 3-2. Een monolithische app opsplitsen om microservices te omarmen.
Elke cloudeigen service wordt gebouwd en geïmplementeerd in een afzonderlijke container. Elke kan indien nodig worden bijgewerkt. Afzonderlijke services kunnen worden gehost op knooppunten met resources die geschikt zijn voor elke service. De omgeving waarin elke service wordt uitgevoerd, is onveranderbaar, gedeeld in ontwikkel-, test- en productieomgevingen, en kan eenvoudig worden geversied. Koppeling tussen verschillende gebieden van de toepassing vindt expliciet plaats als aanroepen of berichten tussen services, niet compileertijdafhankelijkheden binnen de monolithische omgeving. U kunt ook de technologie kiezen die het beste past bij een bepaalde mogelijkheid zonder dat de rest van de app hoeft te worden gewijzigd.
Voor containerservices is geautomatiseerd beheer vereist. Het zou niet haalbaar zijn om handmatig een grote set onafhankelijk geïmplementeerde containers te beheren. Denk bijvoorbeeld aan de volgende taken:
- Hoe worden containerinstanties ingericht in een cluster van veel computers?
- Hoe worden containers na de implementatie met elkaar gedetecteerd en gecommuniceerd?
- Hoe kunnen containers op aanvraag worden ingeschaald of uitgeschaald?
- Hoe controleert u de status van elke container?
- Hoe beveiligt u een container tegen hardware- en softwarefouten?
- Hoe upgraden containers voor een live-toepassing zonder uitvaltijd?
Containerorchestrators kunnen deze en andere problemen oplossen en automatiseren.
In het cloudeigen ecosysteem is Kubernetes de feitelijke containerorchestrator geworden. Het is een opensource-platform dat wordt beheerd door de Cloud Native Computing Foundation (CNCF). Kubernetes automatiseert de implementatie, schaalaanpassing en operationele problemen van in containers geplaatste workloads in een machinecluster. Het installeren en beheren van Kubernetes is echter berucht complex.
Een veel betere benadering is het gebruik van Kubernetes als een beheerde service van een cloudleverancier. De Azure-cloud bevat een volledig beheerd Kubernetes-platform met de naam Azure Kubernetes Service (AKS). AKS abstraheert de complexiteit en operationele overhead van het beheren van Kubernetes. U gebruikt Kubernetes als een cloudservice; Microsoft neemt de verantwoordelijkheid voor het beheren en ondersteunen ervan. AKS kan ook nauw worden geïntegreerd met andere Azure-services en ontwikkelhulpprogramma's.
AKS is een technologie op basis van clusters. Een pool met federatieve virtuele machines of knooppunten wordt geïmplementeerd in de Azure-cloud. Samen vormen ze een maximaal beschikbare omgeving of cluster. Het cluster wordt weergegeven als een naadloze, individuele entiteit voor uw cloudeigen toepassing. Onder de schermen implementeert AKS uw containerservices op deze knooppunten volgens een vooraf gedefinieerde strategie die de belasting gelijkmatig distribueert.
Wat zijn de voordelen van schalen?
Services die zijn gebouwd op containers kunnen gebruikmaken van schaalvoordelen die worden geboden door indelingshulpprogramma's zoals Kubernetes. Standaard weten containers alleen van zichzelf. Zodra u meerdere containers hebt die moeten samenwerken, moet u ze op een hoger niveau organiseren. Het organiseren van grote aantallen containers en hun gedeelde afhankelijkheden, zoals netwerkconfiguratie, is de plek waar indelingshulpprogramma's binnenkomen om de dag op te slaan. Kubernetes maakt een abstractielaag over groepen containers en organiseert deze in pods. Pods worden uitgevoerd op werkcomputers die knooppunten worden genoemd. Deze georganiseerde structuur wordt een cluster genoemd. Afbeelding 3-3 toont de verschillende onderdelen van een Kubernetes-cluster.
Afbeelding 3-3. Kubernetes-clusteronderdelen.
Het schalen van containerworkloads is een belangrijke functie van containerorchestrators. AKS ondersteunt automatisch schalen in twee dimensies: Containerinstanties en rekenknooppunten. Samen bieden ze AKS de mogelijkheid om snel en efficiënt te reageren op pieken in de vraag en extra resources toe te voegen. Verderop in dit hoofdstuk bespreken we schalen in AKS.
Declaratief versus imperatief
Kubernetes ondersteunt zowel declaratieve als imperatieve configuratie. De imperatieve benadering omvat het uitvoeren van verschillende opdrachten waarmee Kubernetes wordt verteld wat elke stap van de manier moet worden uitgevoerd. Voer deze installatiekopieën uit. Verwijder deze pod. Deze poort beschikbaar maken. Met de declaratieve benadering maakt u een configuratiebestand, een manifest genoemd, om te beschrijven wat u wilt in plaats van wat u moet doen. Kubernetes leest het manifest en transformeert de gewenste eindstatus in de werkelijke eindstatus.
Imperatieve opdrachten zijn ideaal voor leren en interactieve experimenten. U wilt echter declaratief Kubernetes-manifestbestanden maken om een infrastructuur als codebenadering te omarmen, waardoor betrouwbare en herhaalbare implementaties worden geboden. Het manifestbestand wordt een projectartefact en wordt gebruikt in uw CI/CD-pijplijn voor het automatiseren van Kubernetes-implementaties.
Als u uw cluster al hebt geconfigureerd met imperatieve opdrachten, kunt u een declaratief manifest exporteren met behulp van kubectl get svc SERVICENAME -o yaml > service.yaml
. Met deze opdracht wordt een manifest geproduceerd dat lijkt op een manifest dat hieronder wordt weergegeven:
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: {}
Wanneer u declaratieve configuratie gebruikt, kunt u een voorbeeld bekijken van de wijzigingen die worden aangebracht voordat u ze doorvoert met behulp van kubectl diff -f FOLDERNAME
de map waarin uw configuratiebestanden zich bevinden. Zodra u zeker weet dat u de wijzigingen wilt toepassen, voert u de opdracht uit kubectl apply -f FOLDERNAME
. Voeg toe -R
om recursief een maphiërarchie te verwerken.
U kunt ook declaratieve configuratie gebruiken met andere Kubernetes-functies, waarvan een implementatie is. Declaratieve implementaties helpen bij het beheren van releases, updates en schalen. Ze geven de Kubernetes-implementatiecontroller instructies voor het implementeren van nieuwe wijzigingen, het uitschalen van de belasting of het terugdraaien naar een eerdere revisie. Als een cluster instabiel is, retourneert een declaratieve implementatie het cluster automatisch terug naar een gewenste status. Als een knooppunt bijvoorbeeld vastloopt, implementeert het implementatiemechanisme een vervanging opnieuw om de gewenste status te bereiken
Met behulp van declaratieve configuratie kan de infrastructuur worden weergegeven als code die naast de toepassingscode kan worden ingecheckt en geversied. Het biedt verbeterde wijzigingsbeheer en betere ondersteuning voor continue implementatie met behulp van een build- en implementatiepijplijn.
Welke scenario's zijn ideaal voor containers en orchestrators?
De volgende scenario's zijn ideaal voor het gebruik van containers en orchestrators.
Toepassingen waarvoor hoge uptime en schaalbaarheid nodig zijn
Afzonderlijke toepassingen met hoge vereisten voor uptime en schaalbaarheid zijn ideale kandidaten voor cloudeigen architecturen met behulp van microservices, containers en orchestrators. Ze kunnen worden ontwikkeld in containers, getest in geversiede omgevingen en worden geïmplementeerd in productie zonder downtime. Het gebruik van Kubernetes-clusters zorgt ervoor dat dergelijke apps ook op aanvraag kunnen worden geschaald en automatisch kunnen worden hersteld na knooppuntfouten.
Grote aantallen toepassingen
Organisaties die grote aantallen toepassingen implementeren en onderhouden, profiteren van containers en orchestrators. De eerste inspanning voor het instellen van containeromgevingen en Kubernetes-clusters is voornamelijk een vaste kosten. Het implementeren, onderhouden en bijwerken van afzonderlijke toepassingen heeft een prijs die varieert van het aantal toepassingen. Naast enkele toepassingen overschrijdt de complexiteit van het handmatig onderhouden van aangepaste toepassingen de kosten voor het implementeren van een oplossing met behulp van containers en orchestrators.
Wanneer moet u het gebruik van containers en orchestrators vermijden?
Als u uw toepassing niet kunt bouwen volgens de principes van twaalf-factor-apps, moet u overwegen containers en orchestrators te vermijden. In dergelijke gevallen kunt u een hostplatform op basis van een VIRTUELE machine of mogelijk een hybride systeem overwegen. Hiermee kunt u altijd bepaalde onderdelen van functionaliteit in afzonderlijke containers of zelfs serverloze functies instellen.
Ontwikkelingsbronnen
In deze sectie ziet u een korte lijst met ontwikkelingsbronnen die u kunnen helpen aan de slag te gaan met containers en orchestrators voor uw volgende toepassing. Als u op zoek bent naar richtlijnen voor het ontwerpen van uw cloudeigen microservicesarchitectuur-app, leest u de bijbehorende .NET-microservices van dit boek: Architectuur voor in containers geplaatste .NET-toepassingen.
Lokale Kubernetes-ontwikkeling
Kubernetes-implementaties bieden veel waarde in productieomgevingen, maar kunnen ook lokaal worden uitgevoerd op uw ontwikkelcomputer. Hoewel u onafhankelijk van elkaar aan afzonderlijke microservices werkt, kan het voorkomen dat u het hele systeem lokaal moet uitvoeren, net zoals het wordt uitgevoerd wanneer het wordt geïmplementeerd in productie. Er zijn verschillende hulpprogramma's die u kunnen helpen: Minikube en Docker Desktop. Visual Studio biedt ook hulpprogramma's voor Docker-ontwikkeling.
Minikube
Wat is Minikube? Het Minikube-project zegt: 'Minikube implementeert een lokaal Kubernetes-cluster op macOS, Linux en Windows'. De belangrijkste doelstellingen zijn 'om het beste hulpprogramma te zijn voor het ontwikkelen van lokale Kubernetes-toepassingen en om alle Kubernetes-functies te ondersteunen die passen'. Het installeren van Minikube staat los van Docker, maar Minikube ondersteunt verschillende hypervisors dan Docker Desktop ondersteunt. De volgende Kubernetes-functies worden momenteel ondersteund door Minikube:
- DNS
- NodePorts
- Configuratie Kaarten en geheimen
- Dashboards
- Containerruntimes: Docker, rkt, CRI-O en containerd
- CNI (Container Network Interface) inschakelen
- Inkomend verkeer
Nadat u Minikube hebt geïnstalleerd, kunt u deze snel gebruiken door de minikube start
opdracht uit te voeren, waarmee een installatiekopieën worden gedownload en het lokale Kubernetes-cluster wordt gestart. Zodra het cluster is gestart, communiceert u hiermee met behulp van de standaard Kubernetes-opdrachten kubectl
.
Docker Desktop
U kunt ook rechtstreeks vanuit Docker Desktop in Windows met Kubernetes werken. Dit is uw enige optie als u Windows-containers gebruikt en ook een uitstekende keuze is voor niet-Windows-containers. Afbeelding 3-4 laat zien hoe u lokale Kubernetes-ondersteuning inschakelt bij het uitvoeren van Docker Desktop.
Afbeelding 3-4. Kubernetes configureren in Docker Desktop.
Docker Desktop is het populairste hulpprogramma voor het lokaal configureren en uitvoeren van container-apps. Wanneer u met Docker Desktop werkt, kunt u lokaal ontwikkelen op basis van dezelfde set Docker-containerinstallatiekopieën die u in productie gaat implementeren. Docker Desktop is ontworpen voor het lokaal bouwen, testen en verzenden van apps in containers. Het ondersteunt zowel Linux- als Windows-containers. Zodra u uw installatiekopieën naar een installatiekopieregister pusht, zoals Azure Container Registry of Docker Hub, kan AKS deze ophalen en implementeren in productie.
Visual Studio Docker Tooling
Visual Studio ondersteunt Docker-ontwikkeling voor webtoepassingen. Wanneer u een nieuwe ASP.NET Core-toepassing maakt, kunt u deze configureren met Docker-ondersteuning, zoals wordt weergegeven in afbeelding 3-5.
Afbeelding 3-5. Docker-ondersteuning voor Visual Studio inschakelen
Wanneer deze optie is geselecteerd, wordt het project gemaakt met een Dockerfile
in de hoofdmap, die kan worden gebruikt voor het bouwen en hosten van de app in een Docker-container. Een voorbeeld van een Dockerfile wordt weergegeven in afbeelding 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"]
Afbeelding 3-6. Dockerfile gegenereerd door Visual Studio
Zodra ondersteuning is toegevoegd, kunt u uw toepassing uitvoeren in een Docker-container in Visual Studio. In afbeelding 3-7 ziet u de verschillende uitvoeringsopties die beschikbaar zijn vanuit een nieuw ASP.NET Core-project dat is gemaakt met Docker-ondersteuning toegevoegd.
Afbeelding 3-7. Uitvoeringsopties voor Visual Studio Docker
U kunt ook op elk gewenst moment Docker-ondersteuning toevoegen aan een bestaande ASP.NET Core-toepassing. Klik in Visual Studio Solution Explorer met de rechtermuisknop op het project en selecteer Docker-ondersteuning toevoegen>, zoals wordt weergegeven in afbeelding 3-8.
Afbeelding 3-8. Docker-ondersteuning toevoegen aan Visual Studio
Docker-hulpprogramma's voor Visual Studio Code
Er zijn veel extensies beschikbaar voor Visual Studio Code die ondersteuning bieden voor Docker-ontwikkeling.
Microsoft biedt de Docker voor Visual Studio Code-extensie. Deze extensie vereenvoudigt het proces van het toevoegen van containerondersteuning aan toepassingen. Het maakt vereiste bestanden, bouwt Docker-installatiekopieën en stelt u in staat om fouten in uw app in een container op te sporen. De extensie bevat een visual explorer waarmee u eenvoudig acties kunt uitvoeren op containers en installatiekopieën, zoals starten, stoppen, inspecteren, verwijderen en meer. De extensie biedt ook ondersteuning voor Docker Compose, zodat u meerdere actieve containers als één eenheid kunt beheren.