Een Java-app containeriseren
In deze les gaat u een Java-toepassing containeriseren.
Zoals eerder vermeld, worden containers rechtstreeks boven op het hostbesturingssysteem, de kernel en de hardware uitgevoerd, net als een ander systeemproces. Containers vereisen minder systeemresources, wat resulteert in een kleinere footprint, minder overhead en snellere opstarttijden van toepassingen. Dit zijn geweldige gebruiksvoorbeelden voor het schalen op aanvraag.
Er zijn Windows-containers en Linux-containers. In deze module maakt u gebruik van de veelgebruikte Docker-runtime om een Linux-containerinstallatiekopieën te bouwen. Vervolgens implementeert u de Linux-containerinstallatiekopie op het hostbesturingssysteem van uw lokale computer. Ten slotte implementeert u de Linux-containerinstallatiekopieën in Azure Kubernetes Service.
Dockeroverzicht
De Docker-runtime wordt gebruikt voor het bouwen, pullen, uitvoeren en pushen van containerinstallatiekopieën. In de volgende afbeelding ziet u deze use cases, gevolgd door een beschrijving van elke use case/Docker-opdracht.
Docker-opdracht | Beschrijving |
---|---|
docker build |
Hiermee wordt een containerinstallatiekopieën gebouwd; In wezen zijn de instructies/lagen die nodig zijn voor Docker om uiteindelijk een actieve container te maken op basis van een installatiekopieën. Het resultaat van deze opdracht is een installatiekopieën. |
docker pull |
Containers worden geïnitialiseerd op basis van installatiekopieën, die worden opgehaald uit registers zoals Azure Container Registry, en dit is waar Azure Kubernetes Service vandaan komt. Het resultaat van deze opdracht is een netwerk pull van een installatiekopie die in Azure plaatsvindt. Houd er rekening mee dat u optioneel lokaal installatiekopieën kunt ophalen; Dit is gebruikelijk bij het bouwen van installatiekopieën waarvoor afhankelijkheden/lagen nodig zijn waarvoor uw toepassing mogelijk nodig is, zoals een toepassingsserver. |
docker run |
Een actief exemplaar van een installatiekopieën is een container en met deze opdracht worden alle lagen uitgevoerd die nodig zijn om de actieve containertoepassing uit te voeren en te gebruiken. Het resultaat van deze opdracht is een actief toepassingsproces op het hostbesturingssysteem. |
docker push |
In Azure Container Registry worden de installatiekopieën opgeslagen, zodat ze direct beschikbaar zijn en het netwerk dicht bij Azure-implementaties en -schaal ligt. |
De Java-toepassing klonen
Eerst kloont u het Flight Booking System for Airline Reservations repository en cd naar de projectmap Airlines-webtoepassing.
Notitie
Als het maken van de Azure Kubernetes Service is voltooid op het tabblad CLI, gebruikt u dat tabblad; Als het nog steeds wordt uitgevoerd, opent u een nieuw tabblad en cd naar de locatie waar u liever het Flight Booking System for Airline Reservations kloont.
Voer de volgende opdracht uit in de CLI:
git clone https://github.com/Azure-Samples/containerize-and-deploy-Java-app-to-Azure.git
Voer de volgende opdracht uit in de CLI:
cd containerize-and-deploy-Java-app-to-Azure/Project/Airlines
Notitie
Als u Java en Maven hebt geïnstalleerd, kunt u desgewenst de volgende opdrachten uitvoeren in uw CLI om inzicht te krijgen in de ervaring bij het bouwen van de toepassing zonder Docker. Als u Java en Maven niet hebt geïnstalleerd, kunt u veilig naar de volgende sectie gaan, een Docker-bestand maken. In deze sectie gebruikt u Docker om Java en Maven op te halen om de builds namens u uit te voeren.
Als u Maven en een JDK(8) of hoger hebt geïnstalleerd, kunt u de volgende opdracht uitvoeren in uw CLI:
mvn clean install
Notitie
We hebben de mvn clean install
opdracht gebruikt om de operationele uitdagingen te illustreren van het niet gebruiken van Docker-builds met meerdere fases, die we hierna behandelen. Nogmaals, deze stap is optioneel; in beide gevallen kunt u veilig meegaan zonder de Maven-opdracht uit te voeren.
Maven had het Flight Booking System for Airline Reservations Web Application Archive-artefact FlightBookingSystemSample-0.0.-SNAPSHOT.war moeten hebben gebouwd, zoals in de volgende uitvoer:
[INFO] Building war: /mnt/c/Users/chtrembl/dev/git/containerize-and-deploy-Java-app-to-Azure/Project/FlightBookingSystemSample/target/FlightBookingSystemSample-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17.698 s
[INFO] Finished at: 2021-09-28T15:18:07-04:00
[INFO] ------------------------------------------------------------------------
Stel dat u een Java-ontwikkelaar bent en u dit FlightBookingSystemSample-0.0.1-SNAPSHOT.war
zojuist hebt gebouwd. De volgende stap bestaat uit het werken met de technici voor bewerkingen om dit artefact te implementeren op een on-premises server of een virtuele machine. De toepassing kan alleen worden gestart en uitgevoerd als de servers en virtuele machines beschikbaar zijn en geconfigureerd met de vereiste afhankelijkheden. Dit is lastig en tijdrovend, met name op aanvraag wanneer de belasting toeneemt aan uw toepassing. Met containers worden deze uitdagingen verholpen.
Een Dockerfile maken
Op dit moment kunt u een Dockerfile maken. Een Dockerfile is een tekstdocument dat alle opdrachten bevat die een gebruiker op de opdrachtregel kan uitvoeren om een containerinstallatiekopie samen te stellen, die elk lagen (die voor efficiëntie in de cache kunnen worden opgeslagen) die op elkaar bouwen.
Flight Booking System for Airline Reservations moet bijvoorbeeld worden geïmplementeerd en uitgevoerd binnen een toepassingsserver. Een toepassingsserver is niet verpakt in de FlightBookingSystemSample-0.0.1-SNAPSHOT.war
toepassingsserver; het is een externe afhankelijkheid die nodig is voor het FlightBookingSystemSample-0.0.1-SNAPSHOT.war
uitvoeren, luisteren naar HTTP-aanvragen, het beheren van gebruikerssessies en het vergemakkelijken van vluchtreserveringen. Als dit een traditionele, niet-containerimplementatie was, zouden bewerkingstechnici een toepassingsserver installeren en configureren op een fysieke server en/of virtuele machine voordat de implementatie erop FlightBookingSystemSample-0.0.1-SNAPSHOT.war
uitgaat. Deze operation engineers moeten er ook voor zorgen dat de JDK die wordt gebruikt op uw computer (wat mvn clean install
gebruikte om de .war te compileren) in feite overeenkomt met dezelfde JRE die door de toepassingsserver wordt gebruikt. Het beheren van deze afhankelijkheden is lastig en tijdrovend.
Met een Dockerfile kunt u de instructies (lagen) schrijven die nodig zijn om dit automatisch te bereiken door lagen in de stappen te plaatsen die nodig zijn om ervoor te zorgen dat Flight Booking System voor Luchtvaartmaatschappijen alle afhankelijkheden bevat die nodig zijn om te implementeren in de Docker-containerruntime. Dit is zeer aantrekkelijk wanneer u begint na te denken over schaal op aanvraag met ongeplande intervallen. Het is de moeite waard om te vermelden dat elke laag gebruikmaakt van Docker-cache, die de status van de containerinstallatiekopie op elke instructiemijlpal bevat, de rekentijd optimaliseert en opnieuw gebruikt. Als een laag niet wordt gewijzigd, worden lagen in de cache gebruikt. Veelvoorkomende gebruiksvoorbeelden voor lagen in de cache zijn zaken zoals Java Runtime, toepassingsserver en/of andere afhankelijkheden voor de webtoepassing Flight Booking System for Airline Reservations. Als en wanneer een versie wordt gewijzigd op een eerder in de cache geplaatste laag, wordt er een nieuwe vermelding in de cache gemaakt.
In de volgende afbeelding ziet u de lagen van een containerinstallatiekopieën. U ziet dat de bovenste laag het read/write Flight Booking System is voor de webtoepassingslaag Airline Reservations, die is gebouwd op basis van de vorige alleen-lezen lagen, die allemaal het gevolg zijn van de opdrachten in het Dockerfile.
Docker heeft ook het concept van builds met meerdere fases, een functie waarmee u een kleinere containerinstallatiekopieën kunt maken met betere caching en een kleinere footprint voor beveiliging, waardoor de Dockerfile in de loop van de tijd beter kan worden geoptimaliseerd en onderhouden; Instructies die u bijvoorbeeld kunt gebruiken om zowel een compilatie van de toepassing (FlightBookingSystemSample-0.0.1-SNAPSHOT.war
) als een build van de containerinstallatiekopieën zelf uit te voeren, waardoor de restanten van de FlightBookingSystemSample-0.0.1-SNAPSHOT.war
compilatie achterblijven, wat resulteert in een kleinere footprint. Op lange termijn betaalt dit dividenden uit wanneer u begint na te denken over deze afbeeldingen die rond het netwerk reizen. Met builds met meerdere fases gebruikt u meerdere FROM-instructies in uw Dockerfile. Elke FROM-instructie kan een andere basis gebruiken en elk van deze instructies begint met een schone lei, waardoor onnodige bestanden in de cachelaag worden verwijderd die normaal gesproken in de cache worden opgeslagen.
Het is noodzakelijk om ervoor te zorgen dat de toepassing wordt gebouwd door dezelfde JDK die overeenkomt met dezelfde JRE die tijdens runtime wordt geïsoleerd in de containerinstallatiekopie. In het volgende voorbeeld hebt u een buildfase die gebruikmaakt van een specifieke versie van Maven en een specifieke versie van de JDK om de FlightBookingSystemSample-0.0.1-SNAPSHOT.war
. Deze fase zorgt ervoor dat elke Docker-runtime die deze fase uitvoert, de verwachte gegenereerde bytecode krijgt die de auteur van het Dockerfile heeft opgegeven (anders moeten de bewerkingstechnici naar hun Java- en toepassingsserverruntime verwijzen met de ontwikkelaar). De pakketfase gebruikt vervolgens een specifieke versie van Tomcat en de JRE die overeenkomt met de JDK in de buildfase. Opnieuw wordt dit gedaan om ervoor te zorgen dat alle afhankelijkheden (Java Development Kit JDK, Java Runtime Environment JRE, toepassingsserver) worden beheerd en geïsoleerd om ervoor te zorgen dat het verwachte gedrag wordt gegarandeerd op alle computers waarop deze installatiekopieën worden uitgevoerd.
Het is ook de moeite waard om te weten dat met deze multistage-build technisch gezien geen Maven en Java hoeven te worden geïnstalleerd op het systeem. Docker haalt deze op voor gebruik met zowel het bouwen van de toepassing als de toepassingsruntime, waardoor mogelijk versiebeheerconflicten en onverwacht gedrag worden vermeden; tenzij u natuurlijk code compileert en artefacten bouwt buiten Docker.
In de volgende afbeelding ziet u de build met meerdere fasen en wat er in elke fase gebeurt op basis van de opdrachten die zijn opgegeven in het Dockerfile. In fase 0, de buildfase, wordt de webtoepassing Flight Booking System for Airline Reservations gecompileerd en FlightBookingSystemSample-0.0.1-SNAPSHOT.war
gegenereerd. In deze fase is consistentie mogelijk van Maven- en Java-versies die worden gebruikt om deze toepassing te compileren. Zodra de FlightBookingSystemSample-0.0.1-SNAPSHOT.war
laag is gemaakt, is dit de enige laag die nodig is voor de fase 1 (runtimefase) en kunnen alle vorige lagen worden verwijderd. Docker gebruikt deze FlightBookingSystemSample-0.0.1-SNAPSHOT.war
laag vervolgens vanuit fase 0 om de resterende lagen te maken die nodig zijn voor runtime. In dit geval configureert u de toepassingsserver en start u de toepassing.
Maak in de hoofdmap van uw project containerize-and-deploy-Java-app-to-Azure/Project/Airlines een bestand met de naam Dockerfile:
vi Dockerfile
Voeg de volgende inhoud toe aan Dockerfile en sla deze op en sluit af door op Esc te drukken en vervolgens :wq! te typen en op Enter te drukken:
#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
WORKDIR /build
COPY pom.xml .
COPY src ./src
COPY web ./web
RUN mvn clean package
#
# Package stage
#
FROM tomcat:8.5.72-jre11-openjdk-slim
COPY tomcat-users.xml /usr/local/tomcat/conf
COPY --from=build /build/target/*.war /usr/local/tomcat/webapps/FlightBookingSystemSample.war
EXPOSE 8080
CMD ["catalina.sh", "run"]
Notitie
Desgewenst bevat de Dockerfile_Solution in de hoofdmap van uw project de benodigde inhoud.
Deze Dockerfile Build-fase bevat zes instructies:
Docker-opdracht | Beschrijving |
---|---|
FROM |
FROM maven is de basislaag waaruit dit FlightBookingSystemSample-0.0.1-SNAPSHOT.war is gebouwd, een specifieke versie van Maven en een specifieke versie van JDK om ervoor te zorgen dat dezelfde compilatie van bytecode plaatsvindt op alle computers waarop deze build wordt uitgevoerd. |
WORKDIR |
WORKDIR wordt gebruikt om de werkmap van een container op elk gewenst moment te definiëren; in dit geval, waarbij gecompileerde artefacten zich bevinden. |
COPY |
COPY voegt bestanden toe uit de huidige map van uw Docker-client. Het instellen van de bestanden die nodig zijn voor het compileren van Maven, pom.xml nodig zijn voor de Docker-context. |
COPY |
Hiermee stelt u de bestanden in die nodig zijn om Maven te compileren. De Docker-context heeft de src-map met de webtoepassing Flight Booking System for Airline Reservations nodig. |
COPY |
Hiermee stelt u de bestanden in die nodig zijn om Maven te compileren. De web-Docket-context heeft de map met de webtoepassingsafhankelijkheden Flight Booking System for Airline Reservations nodig. |
UITVOEREN | De RUN mvn clean package instructie wordt gebruikt om een opdracht boven op de huidige installatiekopie uit te voeren. In dit geval wordt RUN gebruikt om de Maven-build uit te voeren, waarmee de FlightBookingSystemSample-0.0.1-SNAPSHOT.war . |
Deze fase van het Docker-bestandpakket bevat vijf instructies:
Docker-opdracht | Beschrijving |
---|---|
FROM |
FROM tomcat is de basislaag waarop deze boven op welke containerinstallatiekopie wordt gebouwd. De containerinstallatiekopie flight booking system for Airline Reservations is een installatiekopie die is gebouwd op de tomcat-installatiekopie. De Docker-runtime probeert de tomcat-installatiekopie lokaal te vinden. Als deze versie niet is geïnstalleerd, wordt er een uit het register gehaald. Als u de tomcat-installatiekopie hebt gecontroleerd waarnaar hier wordt verwezen, zou u merken dat deze is gebouwd met behulp van veel andere lagen, waardoor deze allemaal opnieuw kunnen worden gebruikt als een containerinstallatiekopie van een verpakte toepassingsserver voor de wereld die moet worden gebruikt bij het implementeren van hun Java-toepassing. We hebben de module geselecteerd en getest tomcat:8.5.72-jre11-openjdk-slim . Houd er rekening mee dat alle vorige lagen uit de eerste buildfase zijn verdwenen zodra Docker deze tweede FROM-instructie herkent. |
COPY |
COPY tomcat-users.xml kopieert het tomcat-users.xml bestand dat het Flight Booking System voor luchtvaartmaatschappijen reserveringsgebruikers beheert (beheerd binnen broncodebeheer met behulp van Tomcat-identiteit; dit zou meestal in een extern identiteitsbeheersysteem) in de tomcat-containerinstallatiekopie staan, zodat deze aanwezig is in de containerinstallatiekopie telkens wanneer een containerinstallatiekopie wordt gemaakt. |
ADD |
ADD target/*.war /usr/local/tomcat/webapps/FlightBookingSystemSample.war kopieert de maven die is gecompileerd FlightBookingSystemSample-0.0.1-SNAPSHOT.war naar de map tomcat images webapps om ervoor te zorgen dat wanneer Tomcat wordt geïnitialiseerd, het FlightBookingSystemSample-0.0.1-SNAPSHOT.war bestand wordt geïnstalleerd op de toepassingsserver. |
EXPOSE |
EXPOSE 8080 is nodig omdat Tomcat is geconfigureerd om te luisteren naar verkeer op poort 8080. Dit zorgt ervoor dat het Docker-proces luistert op deze poort. |
CMD |
Met de CMD-instructie wordt een opdracht ingesteld die moet worden uitgevoerd bij het uitvoeren van de container. In dit geval CMD ["catalina.sh", "run"] geeft u Docker opdracht om de Tomcat-toepassingsserver te initialiseren. |
Notitie
Zonder versietag op de FROM tomcat
regel wordt de meest recente versie toegepast. Over het algemeen wilt u gebruikmaken van een versietag (onthoud dat caching wordt toegepast, dus als lagen consistent veranderen, treedt er bandbreedte, latentie, rekentijd en/of neveneffecten op van niet-geteste builds/lagen). In het belang van deze module hebben we specifieke Maven-, Tomcat- en Java JRE-/JDK-tags geselecteerd die tijdens runtime zijn getest om mee FlightBookingSystemSample-0.0.1-SNAPSHOT.war
te werken.
Zie Dockerfile-naslaginformatie voor meer informatie over dockerfile-constructie