Migrieren von Tomcat-Anwendungen zu Azure-Container-Apps

In diesem Handbuch wird beschrieben, was Sie beachten sollten, wenn Sie eine vorhandene Tomcat-Anwendung migrieren möchten, die auf Azure Container Apps (ACA) ausgeführt werden soll.

Vor der Migration

Führen Sie vor Beginn einer Migration die in den folgenden Abschnitten beschriebenen Schritte zur Bewertung und Bestandsermittlung aus, um eine erfolgreiche Migration zu gewährleisten.

Bestand: Externe Ressourcen

Externe Ressourcen, z. B. Datenquellen, JMS-Nachrichtenbroker und andere, werden per JNDI (Java Naming and Directory Interface) eingefügt. Für einige dieser Ressourcen ist unter Umständen eine Migration oder erneute Konfiguration erforderlich.

Innerhalb Ihrer Anwendung

Untersuchen Sie die Datei META-INF/context.xml. Suchen Sie im <Context>-Element nach <Resource>-Elementen.

Auf den Anwendungsservern

Untersuchen Sie die Dateien $CATALINA_BASE/conf/context.xml und $CATALINA_BASE/conf/server.xml sowie die XML-Dateien, die in Verzeichnissen der Art $CATALINA_BASE/conf/[Engine-Name]/[Hostname] enthalten sind.

In context.xml-Dateien werden JNDI-Ressourcen im <Context>-Element der obersten Ebene mithilfe von <Resource>-Elementen beschrieben.

In server.xml-Dateien werden JNDI-Ressourcen im <GlobalNamingResources>-Element mithilfe von <Resource>-Elementen beschrieben.

Datenquellen

Datenquellen sind JNDI-Ressourcen, für die das type-Attribut auf javax.sql.DataSource festgelegt ist. Dokumentieren Sie für jede Datenquelle die folgenden Informationen:

  • Wie lautet der Name der Datenquelle?
  • Wie ist der Verbindungspool konfiguriert?
  • Wo ist die JAR-Datei mit den JDBC-Treibern zu finden?

Weitere Informationen finden Sie in der Tomcat-Dokumentation unter Anleitung zur JNDI-Datenquelle.

Alle anderen externen Ressourcen

Es würde den Rahmen dieses Leitfadens sprengen, jede mögliche externe Abhängigkeit zu dokumentieren. Ihr Team ist dafür verantwortlich, zu überprüfen, dass nach der Migration die Anforderungen aller externen Abhängigkeiten Ihrer Anwendung abgedeckt werden können.

Bestand: Geheimnisse

Kennwörter und sichere Zeichenfolgen

Überprüfen Sie alle Eigenschaften und Konfigurationsdateien auf den Produktionsservern auf Geheimniszeichenfolgen und Kennwörter. Überprüfen Sie unbedingt server.xml und context.xml in $CATALINA_BASE/conf. Unter Umständen finden Sie in Ihrer Anwendung auch Konfigurationsdateien mit Kennwörtern oder Anmeldeinformationen. Dies können Dateien wie META-INF/context.xml und für Spring Boot-Anwendungen application.properties oder application.yml sein.

Ermitteln, ob und wie das Dateisystem verwendet wird

Für jegliche Nutzung des Dateisystems auf dem Anwendungsserver sind erneute Konfigurationen oder in selteneren Fällen auch Architekturänderungen erforderlich. Es kann sein, dass für Sie einige bzw. alle folgenden Szenarien zutreffen.

Schreibgeschützter statischer Inhalt

Falls mit Ihrer Anwendung derzeit statischer Inhalt bereitgestellt wird, benötigen Sie dafür einen anderen Speicherort. Sie können beispielsweise erwägen, statischen Inhalt in Azure Blob Storage zu verschieben und Azure CDN hinzuzufügen, um global eine sehr hohe Downloadgeschwindigkeit zu erzielen. Weitere Informationen finden Sie unter Hosten von statischen Websites in Azure StorageundSchnellstart: Integrieren eines Azure-Speicherkontos in Azure CDN. Sie können den statischen Inhalt auch direkt in einer App im Azure Spring Apps Enterprise-Plan bereitstellen. Weitere Informationen finden Sie unter Bereitstellen statischer Webdateien.

Dynamisch veröffentlichter statischer Inhalt

Wenn Ihre Anwendung statischen Inhalt zulässt, der von Ihrer Anwendung hochgeladen bzw. produziert wird, nach der Erstellung aber unveränderlich ist, können Sie Azure Blob Storage und Azure CDN wie oben beschrieben nutzen. Hierbei können Sie auch eine Azure-Funktion zum Verarbeiten von Uploads und der CDN-Aktualisierung verwenden. Eine entsprechende Beispielimplementierung finden Sie unter Hochladen und CDN-Vorabladen von statischem Inhalt mit Azure Functions. Sie können den statischen Inhalt auch direkt in einer App im Azure Spring Apps Enterprise-Plan bereitstellen. Weitere Informationen finden Sie unter Bereitstellen statischer Webdateien.

Identifizieren eines Mechanismus für Sitzungspersistenz

Untersuchen Sie die context.xml-Dateien in Ihrer Anwendung und der Tomcat-Konfiguration, um den verwendeten Manager für Sitzungspersistenz zu ermitteln. Suchen Sie nach dem <Manager>-Element, und notieren Sie sich den Wert des className-Attributs.

Tomcats integrierte PersistentManager-Implementierungen, z. B. StandardManager oder FileStore, sind nicht für die Verwendung mit einer verteilten, skalierten Plattform wie ACA konzipiert. ACA kann das Lastenausgleich zwischen mehreren Instanzen laden und jede Instanz jederzeit transparent neu starten, sodass das Beibehalten des veränderbaren Zustands für ein Dateisystem nicht empfohlen wird.

Ist Sitzungspersistenz erforderlich, müssen Sie eine andere PersistentManager-Implementierung verwenden, bei der in einen externen Datenspeicher geschrieben wird, z. B. VMware Tanzu-Sitzungs-Manager mit Redis Cache.

Sonderfälle

Bestimmte Produktionsszenarien erfordern möglicherweise mehr Änderungen oder erzwingen mehr Einschränkungen. Szenarien dieser Art sind zwar eher selten, aber Sie sollten trotzdem sicherstellen, dass sie für Ihre Anwendung entweder nicht zutreffen oder korrekt behoben werden.

Ermitteln, ob für die Anwendung geplante Aufträge benötigt werden

Geplante Aufträge, z. B. Quartz Scheduler-Aufgaben oder cron-Aufträge, können für Tomcat-Bereitstellungen in Containern nicht verwendet werden. Wenn Ihre Anwendung horizontal hochskaliert wird, wird ein geplanter Auftrag unter Umständen mehrmals pro geplantem Zeitraum ausgeführt. Diese Situation kann unerwünschte Konsequenzen haben.

Inventarisieren Sie alle geplanten Aufträge innerhalb oder außerhalb des Anwendungsservers.

Ermitteln, ob Ihre Anwendung betriebssystemspezifischen Code enthält

Wenn Ihre Anwendung Code mit Abhängigkeiten vom Hostbetriebssystem enthält, müssen Sie ihn umgestalten, um diese Abhängigkeiten zu beseitigen. Beispielsweise müssen Sie ggf. alle Vorkommen von / oder \ in Dateisystempfaden durch File.Separator oder Paths.get ersetzen.

Ermitteln, ob MemoryRealm genutzt wird

Für MemoryRealm wird eine persistente XML-Datei benötigt. Auf ACA müssen Sie diese Datei dem Containerimage hinzufügen oder in freigegebenen Speicher hochladen, der containern zur Verfügung gestellt wird. (Weitere Informationen finden Sie unter Abschnitt zum Identifizieren des Sitzungspersistenzmechanismus .) Der pathName Parameter muss entsprechend geändert werden.

Gehen Sie wie folgt vor, um zu ermitteln, ob MemoryRealm derzeit verwendet wird: Untersuchen Sie Ihre server.xml- und context.xml-Dateien, und suchen Sie nach <Realm>-Elementen, für die das className-Attribut auf org.apache.catalina.realm.MemoryRealm festgelegt ist.

Direktes Testen

Bevor Sie Containerimages erstellen, migrieren Sie Ihre Anwendung zu JDK und Tomcat, die Sie für ACA verwenden möchten. Führen Sie für Ihre Anwendung gründliche Tests durch, um die Kompatibilität und Leistung sicherzustellen.

Parametrisieren der Konfiguration

Bei der Migrationsvorbereitung haben Sie in server.xml- und context.xml-Dateien ggf. Geheimnisse und externe Abhängigkeiten identifiziert, z. B. Datenquellen. Ersetzen Sie für alle hierbei identifizierten Elemente den Benutzernamen, das Kennwort, die Verbindungszeichenfolge und die URL durch eine Umgebungsvariable.

Angenommen, die context.xml-Datei enthält das folgende 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$$"
/>

In diesem Fall können Sie die Änderungen vornehmen, die im folgenden Beispiel angegeben sind:

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

Migration

Hinweis

Einige Tomcat-Bereitstellungen verfügen ggf. über mehrere Anwendungen, die auf einem einzelnen Tomcat-Server ausgeführt werden. Falls dies für Ihre Bereitstellung zutrifft, empfehlen wir Ihnen dringend, jede Anwendung in einem separaten Pod auszuführen. Auf diese Weise können Sie die Ressourcenverwendung für jede Anwendung optimieren und gleichzeitig die Komplexität und Kopplung minimieren.

Vorbereiten der Bereitstellungsartefakte

Klonen Sie das Tomcat für Container schnellstart GitHub-Repository. Dieses Repository enthält eine Dockerfile- und Tomcat-Konfigurationsdateien mit vielen empfohlenen Optimierungen. In den folgenden Schritten erläutern wir Änderungen, die Sie wahrscheinlich an diesen Dateien vornehmen müssen, bevor Sie das Containerimage erstellen und in ACA bereitstellen.

Hinzufügen von JNDI-Ressourcen

Bearbeiten Sie server.xml , um die Ressourcen hinzuzufügen, die Sie in den Schritten vor der Migration vorbereitet haben, z. B. Datenquellen, wie im folgenden Beispiel gezeigt:

<!-- 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>

Weitere Anweisungen zu Datenquellen finden Sie in der Tomcat-Dokumentation in den folgenden Abschnitten der Anleitung zur JNDI-Datenquelle:

Erstellen und Pushen des Images

Die einfachste Möglichkeit zum Erstellen und Hochladen des Images in die Azure Container Registry (ACR) für die Verwendung durch ACA besteht darin, den az acr build Befehl zu verwenden. Für diesen Befehl ist es nicht erforderlich, dass Docker auf Ihrem Computer installiert ist. Wenn Sie z. B. über die Dockerfile-Datei aus dem Tomcat-container-Schnellstart-Repository und dem Anwendungspaket petclinic.war im aktuellen Verzeichnis verfügen, können Sie das Containerimage in ACR mit dem folgenden Befehl erstellen:

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

Sie können den Parameter --build-arg APP_FILE... weglassen, wenn Ihre WAR-Datei den Namen ROOT.war hat. Sie können den Parameter --build-arg SERVER_XML... weglassen, wenn die XML-Datei des Servers den Namen server.xml hat. Beide Dateien müssen sich in demselben Verzeichnis wie die Dockerfile befinden.

Alternativ können Sie docker CLI verwenden, um das Image lokal mithilfe der folgenden Befehle zu erstellen. Dieser Ansatz kann das Testen und Optimieren des Images vor der ersten Bereitstellung unter ACR vereinfachen. Hierfür muss allerdings die Docker-CLI installiert und der Docker-Daemon ausgeführt werden.

# 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"

# You can now access your application with a browser at http://localhost:8080.

# Sign in to ACR.
sudo az acr login --name $acrName

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

Weitere Informationen finden Sie unter Erstellen und Speichern von Containerimages mit Azure Container Registry.

Bereitstellen von Azure Container Apps

Im folgenden Befehl ist eine Beispielbereitstellung gezeigt:

az containerapp create \
    --resource-group <RESOURCE_GROUP> \
    --name <APP_NAME> \
    --environment <ENVIRONMENT_NAME> \
    --image <IMAGE_NAME> \
    --target-port 8080 \
    --ingress 'external' \
    --registry-server <REGISTRY_SERVER> \
    --min-replicas 1

Eine ausführlichere Schnellstartanleitung finden Sie in der Schnellstartanleitung: Bereitstellen Ihrer ersten Container-App.

Nach der Migration

Nachdem Sie Ihre Anwendung zu ACA migriert haben, sollten Sie überprüfen, ob sie wie erwartet funktioniert. Als Nächstes können Sie sich über unsere Empfehlungen informieren, mit denen Sie Ihre Anwendung cloudnativer gestalten können.

Empfehlungen

  • Entwerfen und implementieren Sie eine Strategie für Geschäftskontinuität und Notfallwiederherstellung. Bei unternehmenskritischen Anwendungen sollten Sie erwägen, eine Bereitstellungsarchitektur mit mehreren Regionen zu verwenden. Weitere Informationen finden Sie unter Bewährte Methoden für Geschäftskontinuität und Notfallwiederherstellung in Azure Kubernetes Service (AKS).

  • Sehen Sie sich die Elemente in der Datei logging.properties an. Erwägen Sie, einen Teil der Protokollierungsausgabe zu entfernen bzw. zu reduzieren, um die Leistung zu verbessern.

  • Erwägen Sie die Überwachung der Codecachegröße und das Hinzufügen der Parameter -XX:InitialCodeCacheSize und -XX:ReservedCodeCacheSize der Variablen in der JAVA_OPTS Dockerfile-Datei, um die Leistung weiter zu optimieren. Weitere Informationen finden Sie in der Oracle-Dokumentation unter Codecache-Optimierung.

  • Fügen Sie zur schnellen Erkennung und Behandlung von Anomalien ggf. Azure Monitor-Warnungsregeln und -Aktionsgruppen hinzu.

  • Erwägen Sie, die Bereitstellung von Azure Container Apps in einer anderen Region für niedrigere Latenz und höhere Zuverlässigkeit und Fehlertoleranz zu replizieren. Verwenden Sie Azure Traffic Manager für den Lastenausgleich zwischen Bereitstellungen oder Azure Front Door, um SSL-Abladung und Web Application Firewall mit DDoS-Schutz hinzuzufügen.

  • Sollte keine Georeplikation benötigt werden, können Sie eine Azure Application Gateway-Instanz verwenden, um SSL-Abladung und Web Application Firewall mit DDoS-Schutz hinzuzufügen.