Kontejnerizace aplikace v Javě

Dokončeno

V této lekci kontejnerizujete aplikaci v Javě.

Jak už bylo zmíněno dříve, kontejnery běží přímo na hostitelském operačním systému, jádru a hardwaru jako běžné systémové procesy. Kontejnery vyžadují méně systémových prostředků, což vede k menšímu systémovému otisku, nižším režijním nákladům a rychlejšímu spouštění aplikací. Tyto výhody jsou skvělé případy použití škálování na vyžádání.

Existují kontejnery Windows a linuxové kontejnery. V tomto modulu použijete široce používaný modul runtime Dockeru k sestavení image kontejneru Linuxu. Potom nasadíte image kontejneru Linuxu do hostitelského operačního systému místního počítače. Nakonec nasadíte image kontejneru Linuxu do služby Azure Kubernetes Service.

Přehled Dockeru

Modul runtime Dockeru se používá k sestavení, vyžádání, spuštění a nasdílení imagí kontejneru, jak je znázorněno v následujícím diagramu:

Diagram znázorňující příkazy Dockeru

Následující tabulka popisuje jednotlivé příkazy Dockeru:

Příkaz Dockeru Popis
docker build Vytvoří image kontejneru skládající se z pokynů nebo vrstev potřebných pro Docker k vytvoření spuštěného kontejneru z image. Výsledkem tohoto příkazu je obrázek.
docker pull Kontejnery se inicializují z imagí, které se načítají z registrů, jako je Azure Container Registry. Tento registr je místo, odkud služba Azure Kubernetes Service načítá. Výsledkem tohoto příkazu je načtení image ze sítě, ke které dochází v Azure. Volitelně můžete stáhnout obrázky místně. Tato možnost je běžná při vytváření imagí, které vyžadují závislosti nebo vrstvy, které může vaše aplikace potřebovat, například aplikační server.
docker run Spuštěná instance image je kontejner a tento příkaz spustí všechny vrstvy potřebné ke spuštění a interakci se spuštěnou aplikací kontejneru. Výsledkem tohoto příkazu je spuštěný proces aplikace v hostitelském operačním systému.
docker push Azure Container Registry ukládá snímky, aby byly snadno dostupné a v blízkosti sítě pro nasazení a škálování v Azure.

Klonování aplikace v Javě

Nejprve naklonujte úložiště Flight Booking System for Airline Reservations a přejděte do složky projektu webové aplikace Airlines.

Poznámka

Pokud se vytvoření služby Azure Kubernetes Service dokončí na kartě rozhraní příkazového řádku, použijte tuto kartu. Pokud je stále spuštěno, otevřete novou kartu a přejděte na místo, kam chcete klonovat systém rezervací letenek pro letecké společnosti.

Spusťte následující příkazy:

git clone https://github.com/Azure-Samples/containerize-and-deploy-Java-app-to-Azure.git
cd containerize-and-deploy-Java-app-to-Azure/Project/Airlines

Pokud máte nainstalovanou Javu a Maven, můžete v konzole terminálu spustit následující příkaz, abyste získali představu o vytváření aplikace bez Dockeru. Pokud nemáte nainstalovanou Javu a Maven, můžete bezpečně přejít k další části , vytvořit soubor Dockeru. V této části používáte Docker ke stažení Javy a Maven a k provádění sestavení za vás.

mvn clean package

Poznámka

Tento příkaz jsme použili mvn clean package k ilustraci provozních problémů, kdy se nepoužívaly buildy Dockeru s více fázemi, které probereme v dalším kroku. Tento krok je opět volitelný. V obou směrech můžete bezpečně pokračovat bez spuštění příkazu Maven.

Pokud byl proces úspěšný, Maven úspěšně vytvořil systém pro rezervaci letů ve formě artefaktu webové aplikace pro rezervaci letenek AirlinesReservationSample-0.0.1-SNAPSHOT.war, jak je ukázáno v následujícím výstupu:

[INFO] Building war: $PROJECT_PATH/containerize-and-deploy-Java-app-to-Azure/Project/Airlines/target/AirlinesReservationSample-0.0.1-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  11.776 s
[INFO] Finished at: 2024-11-15T09:33:26+09:00
[INFO] ------------------------------------------------------------------------

Představte si, že jste vývojář v Javě a právě jste vytvořili AirlinesReservationSample-0.0.1-SNAPSHOT.war. Dalším krokem je pravděpodobně spolupráce s provozními inženýry, kteří tento artefakt nasadí na místní server nebo virtuální počítač. Aby se aplikace úspěšně spustila a běžela, musí být servery a virtuální počítače dostupné a nakonfigurované s požadovanými závislostmi. Tento proces je náročný a časově náročný, zejména na vyžádání, když se zvyšuje zatížení vaší aplikace. U kontejnerů se tyto výzvy zmírňují.

Vytvoření souboru Dockerfile

Teď jste připraveni vytvořit soubor Dockerfile. Soubor Dockerfile je textový dokument, který obsahuje všechny příkazy, které by uživatel spustil na příkazovém řádku pro sestavení image kontejneru. Každá image je vrstva, která se dá uložit do mezipaměti kvůli efektivitě. Vrstvy se vrství na sebe.

Například letový rezervační systém pro rezervace leteckých společností musí být nasazený a spuštěný uvnitř aplikačního serveru. Aplikační server není zabalený uvnitř AirlinesReservationSample-0.0.1-SNAPSHOT.war. Je to externí závislost potřebná pro spuštění aplikace AirlinesReservationSample-0.0.1-SNAPSHOT.war , naslouchání a zpracování požadavků HTTP, správa uživatelských relací a usnadnění rezervací letů. Pokud jste použili tradiční nekontenerizované nasazení, inženýři provozu by nainstalovali a nakonfigurovali aplikační server na nějakém fyzickém serveru nebo virtuálním počítači, než by na něj nasadili AirlinesReservationSample-0.0.1-SNAPSHOT.war. Tito provozní inženýři by také museli zajistit, aby sada JDK používaná na vašem počítači – což se mvn clean package používá ke kompilaci souboru WAR – ve skutečnosti odpovídala stejnému JRE používanému aplikačním serverem. Správa těchto závislostí je náročná a časově náročná.

Pomocí souboru Dockerfile můžete napsat pokyny nebo vrstvy potřebné k automatickému dosažení tohoto cíle tak, že postupným vrstvením kroků zajistíte, aby systém rezervace letenek obsahoval všechny závislosti potřebné k nasazení v prostředí runtime Dockeru. Toto řešení je působivé, když pracujete se škálováním na vyžádání v neplánovaných intervalech. Každá vrstva používá mezipaměť Dockeru, která obsahuje stav image kontejneru v každém instrukčním milníku, optimalizaci výpočetního času a opětovného použití. Pokud se vrstva nemění, použijí se vrstvy uložené v mezipaměti. Mezi běžné případy použití vrstev v mezipaměti patří modul runtime Java, aplikační server a další závislosti webové aplikace Flight Booking System for Airline Reservations. Pokud a když se verze změní na dříve uložené vrstvě v mezipaměti, vytvoří se nová položka uložená v mezipaměti.

Následující diagram znázorňuje vrstvy image kontejneru. Po spuštění příkazů v souboru Dockerfile se vytvoří vrstvy. Horní vrstva je systém letových rezervací pro čtení a zápis pro webovou aplikační vrstvu Airline Reservations. Tato vrstva je postavená na předchozích vrstvách pouze pro čtení.

Diagram znázorňující vrstvy Dockeru

Docker má koncept vícefázových sestavení, což je funkce, která umožňuje vytvořit menší image kontejneru s lepším ukládáním do mezipaměti a menšími nároky na zabezpečení, což v průběhu času umožňuje zvýšenou optimalizaci a údržbu souboru Dockerfile. Můžete například oddělit fázi sestavení kontejneru pro kompilaci a sestavení aplikace z fáze pro spuštění aplikace. Tato funkce umožňuje kopírovat pouze artefakty vygenerované během sestavování do produkční kontejnerové image, což snižuje dopad. Vzhledem k tomu, že image kontejnerů se ukládají do mezipaměti, pokud nedojde k žádným změnám, dají se image v mezipaměti opakovaně používat, což snižuje náklady a dobu stahování ze sítě.

Služby vystavené v produkčním prostředí musí být pečlivě spravovány kvůli zabezpečení. Produkční prostředí proto používá a provozuje zabezpečenou image kontejneru. V tomto příkladu se používá obrázek CBL-Mariner, který poskytla společnost Microsoft.

CBL-Mariner Linux je jednoduchý operační systém, který obsahuje pouze balíčky potřebné pro cloudové prostředí. Můžete ho přizpůsobit prostřednictvím vlastních balíčků a nástrojů tak, aby vyhovoval požadavkům vaší aplikace. CBL-Mariner prochází ověřovacími testy Azure a je kompatibilní s agenty Azure. Microsoft sestavuje a testuje CBL-Mariner pro různé případy použití, od služeb Azure až po výkon infrastruktury IoT. Jedná se o interně doporučenou distribuci Linuxu pro použití s cloudovými službami Microsoftu a souvisejícími produkty.

Poznámka

Microsoft poskytuje image kontejnerů svázané s OpenJDK, včetně Ubuntu, CBL-Mariner, a distroless obrázků. Obrázek distroless má nejmenší velikost obrázku, ale spuštění Tomcat na něm je náročné. Aby bylo dosaženo lehké konstrukce, distroless image odebere mnoho příkazů a nástrojů, včetně shellu, což znamená, že nemůžete zavolat catalina.sh k spuštění Tomcatu. Tato distroless image je vhodná pro spouštění spustitelných souborů JAR, jako jsou ty, které se používají se spring bootem nebo Quarkus.

V následujícím příkladu se stejná verze sady Microsoft Build openJDK používá v fázi sestavení i v poslední fázi. Tento přístup zajišťuje, že vytvoříte zdrojový kód se stejnou verzí JDK, kterou používá nasazení služby Tomcat, což pomáhá vyhnout se neočekávanému chování kvůli neshodám verzí.

Následující obrázek znázorňuje sestavení s více fázemi a to, co se děje v jednotlivých fázích na základě příkazů zadaných v souboru Dockerfile:

Diagram znázorňující sestavení Dockeru s více fázemi

Ve stupni 0 se Tomcat stáhne a rozbalí do adresáře určeného proměnnou prostředí na obrazu Ubuntu. Proměnná TOMCAT_VERSION určuje verzi Tomcatu, která se má stáhnout. Pokud je vydána nová verze Tomcat, měli byste aktualizovat číslo verze, protože nová image se načte pouze při změně čísla verze. Jinak se použije image uložená v mezipaměti. Stažený soubor Tomcat se zkopíruje do cílového prostředí pro použití.

Ve fázi 1 se Maven nainstaluje na image Ubuntu a vytvořený zdrojový kód a konfigurační soubory se zkopírují před sestavením projektu Maven. Každá vrstva se ukládá do mezipaměti, takže vrstva obrazu operačního systému a Maven vrstva využívají mezipaměť. Pokud se aktualizují konfigurační soubory, soubory zdrojového kódu nebo webový adresář, vrstvy od změn se znovu sestaví. Pokud se sestavení úspěšně dokončí bez chyb během kompilace, vygeneruje se v cílovém adresáři artefakt s názvem AirlinesReservationSample-0.0.1-SNAPSHOT.war. Tento artefakt se zkopíruje do cílového prostředí pro použití.

V poslední fázi se zabezpečená CBL-Mariner image poskytovaná Microsoftem používá ke kopírování artefaktů sestavení Tomcat a Java z fáze 0 a fáze 1. Uživatel app vlastní všechny soubory používané v projektu a aplikace je také spuštěna jako uživatel app místo s oprávněními root. Toto nastavení zajišťuje, že image kontejneru se dá bezpečně provozovat bez udělení zbytečných oprávnění. Nakonec se vystaví číslo portu 8080 a skript catalina.sh se spustí, aby se spustil Tomcat. Když se spustí na místní ploše Dockeru, můžete k němu přistupovat přes adresu URL http://localhost:8080/AirlinesReservationSample.

V kořenové složce vašeho projektu containerize-and-deploy-Java-app-to-Azure/Project/Airlines použijte následující příkaz k vytvoření souboru s názvem Dockerfile:

vi Dockerfile

Do souboru Dockerfile přidejte následující obsah a pak ho uložte a ukončete. Pokud chcete soubor uložit a ukončit, stiskněte esc, zadejte :wq! a stiskněte Enter.

############################################
# Tomcat Intall stage
############################################
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS tomcat

ENV CATALINA_HOME=/usr/local/tomcat

# Configure Tomcat Version (Be sure to use the latest version)
ENV TOMCAT_VERSION=10.1.33

# Install Tomcat and required packages
RUN apt-get update ; \
    apt-get install -y curl ; \
    curl -O https://downloads.apache.org/tomcat/tomcat-10/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz ; \
    tar xzf apache-tomcat-${TOMCAT_VERSION}.tar.gz ; \
    mv apache-tomcat-${TOMCAT_VERSION} ${CATALINA_HOME} ; \
    rm apache-tomcat-${TOMCAT_VERSION}.tar.gz && \
    apt-get remove --purge -y curl && \
    apt-get autoremove -y && \
    apt-get clean

############################################
# Build stage (Compiles with Java 17)
############################################
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS build

WORKDIR /build

# Install Maven
RUN apt-get update && apt-get install -y maven && mvn --version

# Copy source code
COPY pom.xml .
COPY src ./src
COPY web ./web

# Build the project
RUN mvn clean package

############################################
# Package final stage
############################################
FROM mcr.microsoft.com/openjdk/jdk:17-mariner

# Configure the location of the Tomcat installation
ENV CATALINA_HOME=/usr/local/tomcat
# Configure the path to the Tomcat binaries
ENV PATH=$CATALINA_HOME/bin:$PATH

# This is the user that runs the Tomcat process
USER app

# Copy the Tomcat installation from the Tomcat stage
COPY --chown=app:app --from=tomcat ${CATALINA_HOME} ${CATALINA_HOME}
# Copy the Tomcat configuration files
COPY --chown=app:app tomcat-users.xml ${CATALINA_HOME}/conf
# Copy the compiled WAR file from the build stage
COPY --chown=app:app --from=build /build/target/*.war ${CATALINA_HOME}/webapps/AirlinesReservationSample.war

# Expose the default Tomcat port
EXPOSE 8080
# Start Tomcat
CMD ["catalina.sh", "run"]

Poznámka

Volitelně můžete použít soubor Dockerfile_Solution v kořenovém adresáři projektu, který obsahuje potřebný obsah.

Soubor Dockerfile je rozdělený do tří fází, které jsou popsány v následujících tabulkách:

  • Fáze instalace služby Tomcat:

    Příkaz Dockeru Popis
    FROM FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS tomcat nastaví základní image na Microsoft Build of OpenJDK 17 v Ubuntu a pojmenuje tuto fázi tomcat. Tady je nainstalovaný Tomcat.
    ENV ENV CATALINA_HOME=/usr/local/tomcat nastaví proměnnou prostředí pro instalační adresář Tomcat.
    ENV ENV TOMCAT_VERSION=10.1.33 nastaví verzi tomcat, která se má nainstalovat. Podle potřeby by se měla aktualizovat na nejnovější verzi.
    RUN Příkaz RUN aktualizuje seznam balíčků, nainstaluje curl, stáhne zadanou verzi Tomcatu, extrahuje ji, přesune ji do zadaného adresáře a vyčistí nepotřebné soubory a balíčky. Tím se zajistí, že obrázek zůstane odlehčený.
  • Fáze sestavení, která se zkompiluje pomocí Javy 17:

    Příkaz Dockeru Popis
    FROM FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu AS build nastaví základní image na Microsoft Build of OpenJDK 17 v Ubuntu a pojmenuje tuto fázi build. Tato fáze se používá k kompilaci aplikace v Javě.
    WORKDIR WORKDIR /build nastaví pracovní adresář uvnitř kontejneru na /build, kde se zdrojový kód zkopíruje a zkompiluje.
    RUN RUN apt-get update && apt-get install -y maven && mvn --version nainstaluje Maven, nástroj pro automatizaci sestavení používaný pro projekty Java a ověří jeho instalaci.
    COPY COPY pom.xml . zkopíruje konfigurační soubor Mavenu do pracovního adresáře. Tento soubor je nezbytný pro sestavení projektu.
    COPY COPY src ./src zkopíruje adresář zdrojového kódu do kontejneru. Tady se nachází kód aplikace v Javě.
    COPY COPY web ./web zkopíruje adresář webových prostředků do kontejneru. To zahrnuje prostředky webové aplikace potřebné pro sestavení.
    RUN RUN mvn clean package spustí proces sestavení Maven, který zkompiluje aplikaci Java a zabalí ji do souboru WAR.
  • Poslední fáze balíčku:

    Příkaz Dockeru Popis
    FROM FROM mcr.microsoft.com/openjdk/jdk:17-mariner nastaví základní obraz na Microsoft Build of OpenJDK 17 na CBL-Mariner, který se používá pro závěrečné nasazení aplikace.
    ENV ENV CATALINA_HOME=/usr/local/tomcat nastaví proměnnou prostředí pro instalační adresář Tomcat, podobně jako ve fázi instalace.
    ENV ENV PATH=$CATALINA_HOME/bin:$PATH přidá do systému PATHadresář Bin Tomcat, který umožňuje snadné spuštění příkazů Tomcat.
    USER USER app určuje uživatele, pod kterým běží proces Tomcat, což zvyšuje zabezpečení tím, že neběží jako uživatel root.
    COPY COPY --chown=app:app --from=tomcat ${CATALINA_HOME} ${CATALINA_HOME} zkopíruje instalaci Tomcat z tomcat fáze a nastaví vlastnictví pro app uživatele.
    COPY COPY --chown=app:app tomcat-users.xml ${CATALINA_HOME}/conf zkopíruje konfigurační soubor uživatele Tomcat do kontejneru a nastaví vlastnictví uživatele app .
    COPY COPY --chown=app:app --from=build /build/target/*.war ${CATALINA_HOME}/webapps/AirlinesReservationSample.war zkopíruje zkompilovaný soubor WAR z build fáze do adresáře webapps Tomcat a nastaví vlastnictví uživatele app .
    EXPOSE EXPOSE 8080 zpřístupňuje port 8080, výchozí port pro Tomcat, který umožňuje externí přístup k aplikaci.
    CMD CMD ["catalina.sh", "run"] určuje příkaz, který má spustit Tomcat při spuštění kontejneru.

Další informace o konstrukci souboru Dockerfile naleznete v referenčních informacích k souboru Dockerfile.