Migrera Tomcat-program till containrar i Azure Kubernetes Service

I den här guiden beskrivs vad du bör känna till när du vill migrera ett befintligt Tomcat-program som ska köras i en Azure Kubernetes Service-behållare (AKS).

Före migrering

För att säkerställa en lyckad migrering slutför du de utvärderings- och inventeringssteg som beskrivs i följande avsnitt innan du börjar.

Inventera externa resurser

Externa resurser som datakällor, JMS asynkron meddelandekö och andra matas via Java-namngivnings- och kataloggränssnittet (JNDI). Vissa resurser kan kräva migrering eller omkonfiguration.

I ditt program

Granska filen META-INF/context.xml. Leta efter <Resource>-element i <Context>-elementet.

På programservrar

Granska filerna $CATALINA_BASE/conf/context.xml och $CATALINA_BASE/conf/server.xml samt de .xml-filer som hittas i $CATALINA_BASE/conf/[engine-name]/[host-name]-katalogerna.

I context.xml-filer kommer JNDI-resurser att beskrivas av de <Resource>-element i toppnivåelementet <Context>.

I server.xml-filer kommer JNDI-resurser att beskrivas av de <Resource>-element i toppnivåelementet <GlobalNamingResources>.

Datakällor

Datakällor är JNDI-resurser med attributet type inställt på javax.sql.DataSource. För varje datakälla, dokumenterar du följande information:

  • What is the datakällans namn?
  • Vad är konfigurationen för anslutningspoolen?
  • Var hittar jag JAR-filen för JDBC-drivrutinen?

Mer information finns i avsnittet om JNDI-datakällor i Tomcat-dokumentationen.

Alla andra externa resurser

Det är inte möjligt att dokumentera alla möjliga externa beroenden i den här guiden. Det är ditt teams ansvar att kontrollera att du kan uppfylla varje externt beroende för ditt program efter migreringen.

Inventera hemligheter

Lösenord och säkra strängar

Kontrollera alla egenskaper och konfigurationsfiler på produktionsservrarna efter hemlighetssträngar och lösenord. Se till att kontrollera server.xml och context.xml i $CATALINA_BASE/conf. Du kan även hitta konfigurationsfiler som med lösenord eller autentiseringsuppgifter i ditt program. De kan inkludera META-INF/context.xml, och för Spring Boot-program, application.properties- eller application.yml-filer.

Kontrollera om och hur filsystemet används

All användning av programserverns filsystem kräver omkonfiguration eller, i sällsynta fall, arkitektoniska ändringar. Du kanske känner igen några eller alla av följande scenarier.

Skrivskyddat statiskt innehåll

Om ditt program för tillfället hanterar statiskt innehåll behöver du en alternativ plats för det. Du kanske kan tänka dig att flytta det statiska innehållet till Azure Blob Storage och lägga till Azure CDN för blixtsnabba nedladdningar globalt. Mer information finns i Värd för statiska webbplatser i Azure Storage och snabbstart: Integrera ett Azure Storage-konto med Azure CDN. Du kan också distribuera det statiska innehållet direkt till en app i Azure Spring Apps Enterprise-planen. Mer information finns i Distribuera webbstatiska filer.

Dynamiskt publicerat statiskt innehåll

Om ditt program tillåter att statiskt innehåll laddas upp/skapas av ditt program, men inte kan ändras efter att det har skapats, så kan du använda Azure Blob Storage och Azure CDN enligt beskrivningen ovan, med en Azure-funktion för hantering av överföringar och CDN-uppdateringar. Vi har tillhandahållit en exempelimplementering som du kan använda i Överföra och CDN-för inläsa statiskt innehåll med Azure Functions. Du kan också distribuera det statiska innehållet direkt till en app i Azure Spring Apps Enterprise-planen. Mer information finns i Distribuera webbstatiska filer.

Dynamiskt eller internt innehåll

För filer som ofta skrivs och läses av ditt program (till exempel temporära datafiler) eller statiska filer som endast är synliga för ditt program kan du montera Azure Storage-resurser som beständiga volymer. Mer information finns i Skapa och använd en permanent volym dynamiskt med Azure-filer i Azure Kubernetes Service.

Identifiera mekanism för beständig session

Om du vill identifiera vilken funktion för beständig session som används kan du granska context.xml-filerna i program- och Tomcat-konfigurationen. Leta efter elementet <Manager> och anteckna värdet för attributet className.

Tomcats inbyggda PersistentManager-implementeringar, till exempel StandardManager eller FileStore, är inte utformade för användning med en distribuerad, skalad plattform som Kubernetes. AKS kan belastningsutjämna mellan flera poddar och starta om alla poddar när som helst med insyn, vilket gör att föränderligt tillstånd till ett filsystem inte rekommenderas.

Om sessionspersistence krävs måste du använda en alternativ PersistentManager implementering som skriver till ett externt datalager, till exempel VMware Tanzu Session Manager med Redis Cache. Mer information finns i Använda Redis som sessioncache med Tomcat.

Särskilda fall

Vissa produktionsscenarier kan kräva ytterligare ändringar eller införa ytterligare begränsningar. Sådana scenarier kan vara ovanliga, men det är viktigt att se till att de antingen inte är tillämpliga för ditt program eller korrekt lösta.

Avgör om programmet är beroende av schemalagda uppgifter

Schemalagda uppgifter, t. ex. Quartz Scheduler-uppgifter eller cron-jobb, kan inte användas med Tomcat-distributioner i behållare. Om ditt program skalas ut kan ett schemalagt jobb köras mer än en gång per schemalagd period. Den här situationen kan leda till oönskade konsekvenser.

Inventera schemalagda jobb, inuti eller utanför programservern.

Ta reda på om ditt program innehåller en operativsystemsspecifik kod

Om programmet innehåller kod som är anpassad för det operativsystem som ditt program körs på måste programmet omstruktureras för att inte förlita sig på det underliggande operativsystemet. Till exempel kan all användning av / eller \ i filsystemsökvägarna behöva ersättas med File.Separator eller Path.get.

Avgör om MemoryRealm används

MemoryRealm- kräver en sparad XML-fil. På Kubernetes måste den här filen läggas till i behållaravbildningen eller överföras till delad lagring som görs tillgänglig för behållare. Parametern pathName måste anpassas till detta.

Du kan ta reda på om MemoryRealm används just nu genom att granska filerna server.xml och context.xml och söka efter <Realm> element där className-attributet är inställt på org.apache.catalina.realm.MemoryRealm.

Ta reda på om SSL-sessionshantering används

I behållardistributioner avlastas vanligtvis SSL-sessioner utanför programbehållaren, oftast genom ingångsstyrenheten. Om ditt program kräver SSL-sessionshantering kontrollerar du att SSL-trafiken skickas vidare till programbehållaren direkt.

Fastställ om AccessLogValve används

Om AccessLogValve används ska directory-parametern anges som en monterad Azure-filresurs eller någon av dess underkataloger.

Testning på plats

Innan du skapar behållaravbildningar ska du migrera ditt program till det JDK och Tomcat som du tänker använda på AKS. Testa programmet noggrant för att säkerställa kompatibilitet och prestanda.

Parameterisera konfigurationen

I förväg har du förmodligen identifierat hemligheter och externa beroenden, till exempel datakällor, i filerna Server.xml och context.xml. Ersätt eventuella användarnamn, lösenord, anslutningssträngar eller URL:er med en miljövariabel för varje objekt som identifieras på detta sätt.

Anta till exempel att filen context.xml innehåller följande element:

<Resource
    name="jdbc/dbconnection"
    type="javax.sql.DataSource"
    url="jdbc:postgresql://postgresdb.contoso.com/wickedsecret?ssl=true"
    driverClassName="org.postgresql.Driver"
    username="postgres"
    password="t00secure2gue$$"
/>

I det här fallet kan du ändra det som visas i följande exempel:

<Resource
    name="jdbc/dbconnection"
    type="javax.sql.DataSource"
    url="${postgresdb.connectionString}"
    driverClassName="org.postgresql.Driver"
    username="${postgresdb.username}"
    password="${postgresdb.password}"
/>

Migrering

Med undantag för det första steget ("etablera behållarregister och AKS") rekommenderar vi att du följer stegen nedan individuellt för varje program (WAR-fil) som du vill migrera.

Kommentar

Vissa Tomcat-distributioner kan ha flera program som körs på en enda Tomcat-Server. Om detta är fallet i distributionen rekommenderar vi starkt att du kör varje program i en separat pod. På så sätt kan du optimera resursanvändningen för varje program samtidigt som du minimerar komplexiteten och antalet kopplingar.

Etablera behållarregister och AKS

Skapa ett behållarregister och ett Azure Kubernetes-kluster vars tjänsthuvudnamn har rollen läsare i registret. Se till att välja en lämplig nätverksmodell för klustrets nätverkskrav.

az group create \
    --resource-group $resourceGroup \
    --location eastus
az acr create \
    --resource-group $resourceGroup \
    --name $acrName \
    --sku Standard
az aks create \
    --resource-group $resourceGroup \
    --name $aksName \
    --attach-acr $acrName \
    --network-plugin azure

Förbereda distributionsartefakter

Klona GitHub-lagringsplatsen Snabbstart för Tomcat på containers. Den innehåller en Dockerfile och Tomcat-konfigurationsfiler med ett antal rekommenderade optimeringar. I stegen nedan beskriver vi de ändringar som du sannolikt behöver göra i de här filerna innan du skapar containeravbildningen och distribuerar till AKS.

Öppna portar för klustring, om det behövs

Om du tänker använda Tomcat-klustring på AKS kontrollerar du att de portintervall som krävs visas i Dockerfile. För att ange serverns IP-adress i server.xml måste du använda ett värde från en variabel som initieras vid containerstarten till poddens IP-adress.

Alternativt kan sessionstillstånd bevaras till en alternativ plats så att det är tillgängligt mellan repliker.

Du kan ta reda på om ditt program använder kluster genom att leta efter elementet <Cluster> inuti elementen <Host> eller <Engine> i filen server.xml.

Lägg till JNDI-resurser

Redigera server.xml för att lägga till de resurser som du har förberett i stegen inför migreringen, till exempel datakällor.

Till exempel:

<!-- Global JNDI resources
      Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml"
               />

    <!-- Migrated datasources here: -->
    <Resource
        name="jdbc/dbconnection"
        type="javax.sql.DataSource"
        url="${postgresdb.connectionString}"
        driverClassName="org.postgresql.Driver"
        username="${postgresdb.username}"
        password="${postgresdb.password}"
    />
    <!-- End of migrated datasources -->
</GlobalNamingResources>

Mer information om datakällor finns i följande avsnitt om JNDI-datakällor i Tomcat-dokumentationen:

Kompilera och överföra avbildningen

Det enklaste sättet att kompilera och ladda upp avbildningen till Azure Container Registry (ACR) som används av AKS är att använda kommandot az acr build. Det här kommandot kräver inte att Docker är installerat på datorn. Om du till exempel har den Dockerfile som beskrivs ovan och programpaketet petclinic.war i den aktuella katalogen kan du kompilera containeravbildningen i ACR med ett enda steg:

az acr build \
    --image "${acrName}.azurecr.io/petclinic:{{.Run.ID}}" \
    --registry $acrName \
    --build-arg APP_FILE=petclinic.war \
    --build-arg=prod.server.xml .

Du kan utelämna parametern --build-arg APP_FILE... om WAR-filen heter ROOT.war. Du kan utelämna parametern --build-arg SERVER_XML... om serverns XML-fil heter server.xml. Båda filerna måste finnas i samma katalog som Dockerfile.

Du kan också använda Docker-kommandoradsgränssnitt för att kompilera avbildningen lokalt. Den här metoden kan förenkla testningen och förfina avbildningen före den första distributionen till ACR. Dock kräver det att Docker-kommandoradsgränssnittet installeras och att Docker-daemon körs.

# Build the image locally
sudo docker build . --build-arg APP_FILE=petclinic.war -t "${acrName}.azurecr.io/petclinic:1"

# Run the image locally
sudo docker run -d -p 8080:8080 "${acrName}.azurecr.io/petclinic:1"

# Your application can now be accessed with a browser at http://localhost:8080.

# Log into ACR
sudo az acr login --name $acrName

# Push the image to ACR
sudo docker push "${acrName}.azurecr.io/petclinic:1"

Mer information finns i Learn-modulen för att skapa och lagra containeravbildningar i Azure.

Distribuera en offentlig IP-adress

Om ditt program ska vara tillgängligt utanför dina interna eller virtuella nätverk krävs en offentlig statisk IP-adress. Den här IP-adressen bör etableras i klustrets resursgrupp för noden.

export nodeResourceGroup=$(az aks show \
    --resource-group $resourceGroup \
    --name $aksName \
    --query 'nodeResourceGroup' \
    --output tsv)
export publicIp=$(az network public-ip create \
    --resource-group $nodeResourceGroup \
    --name applicationIp \
    --sku Standard \
    --allocation-method Static \
    --query 'publicIp.ipAddress' \
    --output tsv)
echo "Your public IP address is ${publicIp}."

Distribuera till AKS

Skapa och använd dina Kubernetes YAML-fil(er). Om du skapar en extern lastbalanserare (oavsett om det är ditt program eller en ingångskontroll) måste du ange IP-adressen som etablerades i föregående avsnitt som LoadBalancerIP.

Ta med externa parametrar som miljövariabler. Ta inte med hemligheter (till exempel lösenord, API-nycklar och JDBC-anslutningssträngar). Hemligheter beskrivs i avsnittet Konfigurera FlexVolume för nyckelvalv.

Konfigurera beständig lagring

Om programmet kräver icke-flyktig lagring kan du konfigurera en eller flera Beständiga volymer.

Du kanske vill skapa en Beständig volym med Azure Files som monteras i loggkatalogen Tomcats (/tomcat_logs) för att förvara loggarna centralt. Mer information finns i Skapa och använd en permanent volym dynamiskt med Azure-filer i Azure Kubernetes Service (AKS).

Konfigurera KeyVault FlexVolume

Skapa ett Azure-valv och fyll i alla nödvändiga hemligheter. Konfigurera sedan ett FlexVolume-nyckelvalv för att göra dessa hemligheter tillgängliga för poddar.

Du måste ändra startskriptet (startup.sh i Tomcat på containrarna GitHub-lagringsplats) för att importera certifikaten till det lokala nyckelarkivet på behållaren.

Migrera schemalagda jobb

Om du vill köra schemalagda jobb på ditt AKS-kluster definierar du Cron-jobb efter behov.

Efter migreringen

Nu när du har migrerat ditt program till AKS bör du kontrollera att det fungerar som förväntat. När du har gjort det har vi några rekommendationer för dig som kan göra ditt program lämpligare för molnet.

  • Överväg att lägga till ett DNS-namn till den IP-adress som allokerats till din ingångskontrollant eller programlastbalanserare. Mer information finns i Skapa en ingresskontrollant med en statisk offentlig IP-adress i AKS.

  • Överväg att lägga till HELM-diagram för ditt program. Med ett Helm-diagram kan du parameterisera programdistributionen för användning och anpassning av en mer varierande uppsättning kunder.

  • Utforma och implementera en DevOps-strategi. För att bibehålla tillförlitligheten samtidigt som du ökar din utvecklingshastighet bör du överväga att automatisera distributioner och testning med Azure-pipelines.

  • Aktivera Azure-övervakning för klustret för att tillåta insamling av containerloggar, spåra användning och så vidare.

  • Överväg att exponera programspecifika mått via Prometheus. Prometheus är ett ramverk med öppen källkod som ofta används av Kubernetes-communityn. Du kan konfigurera Prometheus-statistik i Azure Monitor i stället för att vara värd för din egen Prometheus-Server. Detta aktiverar måttaggregering från dina program och automatiserade svar på eller eskalering av avvikande tillstånd.

  • Utforma och implementera en strategi för affärskontinuitet och haveriberedskap. För verksamhetskritiska program bör du överväga en distributionsarkitektur för flera regioner.

  • Granska Kubernetes-versionens stödprincip. Det är ditt ansvar att fortsätta att uppdatera AKS-klustret för att säkerställa att den alltid kör en version som stöds.

  • Se till att alla teammedlemmar som ansvarar för klusteradministration och programutveckling läser igenom de relevanta metodtipsen för AKS.

  • Utvärdera objekten i filen logging.properties. Överväg att ta bort eller minska några av loggningsresultatet för att förbättra prestandan.

  • Överväg att övervaka kodens cache-storlek och lägga till parametrarna -XX:InitialCodeCacheSize och -XX:ReservedCodeCacheSize till JAVA_OPTS-variabeln i Dockerfile för att ytterligare optimera prestandan.