Migrowanie aplikacji Tomcat do kontenerów w usłudze Azure Kubernetes Service (AKS)
W tym przewodniku opisano, na co należy zwrócić uwagę, aby przeprowadzić migrację istniejącej aplikacji serwera Tomcat w celu uruchomienia jej w usłudze Azure Kubernetes Service (AKS).
Przed migracją
Aby zapewnić pomyślną migrację, przed rozpoczęciem wykonaj kroki oceny i spisu opisane w poniższych sekcjach.
Utworzenie spisu zasobów zewnętrznych
Zasoby zewnętrzne, takie jak źródła danych, brokery komunikatów JMS i inne, są wstrzykiwane za pośrednictwem interfejsu Java Naming and Directory Interface (JNDI). Niektóre takie zasoby mogą wymagać migracji lub ponownej konfiguracji.
W aplikacji
Sprawdź plik META-INF/context.xml. Poszukaj elementów <Resource>
wewnątrz elementu <Context>
.
Na serwerach aplikacji
Sprawdź pliki $CATALINA_BASE/conf/context.xml i $CATALINA_BASE/conf/server.xml oraz pliki .xml w katalogach $CATALINA_BASE/conf/[nazwa-aparatu]/[nazwa-hosta].
W plikach context.xml zasoby JNDI będą opisywane przez elementy <Resource>
w elemencie <Context>
najwyższego poziomu.
W plikach server.xml zasoby JNDI będą opisywane przez elementy <Resource>
w elemencie <GlobalNamingResources>
.
Źródła danych
Źródła danych to zasoby JNDI z atrybutem type
ustawionym na javax.sql.DataSource
. Dla każdego źródła danych należy udokumentować następujące informacje:
- Jaka jest nazwa źródła danych?
- Jaka jest konfiguracja puli połączeń?
- Gdzie mogę znaleźć plik JAR sterownika JDBC?
Aby uzyskać więcej informacji, zobacz przewodnik JNDI Datasource How-To (Źródło danych JNDI — porady) w dokumentacji serwera Tomcat.
Wszystkie inne zasoby zewnętrzne
Nie jest możliwe udokumentowanie każdej możliwej zależności zewnętrznej w tym przewodniku. Twój zespół odpowiada za sprawdzenie, czy każda zależność zewnętrzna aplikacji może być spełniona po migracji.
Utworzenie spisu wpisów tajnych
Hasła i bezpieczne ciągi
Sprawdź wszystkie pliki właściwości i konfiguracji na serwerach produkcyjnych pod kątem wszelkich ciągów wpisów tajnych i haseł. Sprawdź pliki server.xml i context.xml w katalogu $CATALINA_BASE/conf. Możesz również znaleźć pliki konfiguracji zawierające hasła lub poświadczenia wewnątrz aplikacji. Mogą one obejmować plik META-INF/context.xml oraz, w przypadku aplikacji Spring Boot, pliki application.properties lub application.yml.
Określanie, czy i jak jest używany system plików
Każde użycie systemu plików na serwerze aplikacji będzie wymagało ponownej konfiguracji lub, w rzadkich przypadkach, zmiany architektury. Można zidentyfikować niektóre lub wszystkie z następujących scenariuszy.
Zawartość statyczna tylko do odczytu
Jeśli aplikacja aktualnie obsługuje zawartość statyczną, potrzebna jest dodatkowa lokalizacja. Warto rozważyć przeniesienie zawartości statycznej do usługi Azure Blob Storage i dodanie usługi Azure CDN, aby zapewnić błyskawiczne pobieranie na całym świecie. Aby uzyskać więcej informacji, zobacz Hostowanie statycznej witryny internetowej w usłudze Azure Storage i Szybki start: integrowanie konta usługi Azure Storage z usługą Azure CDN.
Dynamicznie publikowana zawartość statyczna
Jeśli aplikacja zezwala na zawartość statyczną, która została przekazana/utworzona przez aplikację, ale pozostaje niezmienna po jej utworzeniu, możesz użyć usług Azure Blob Storage i Azure CDN, jak opisano powyżej, oraz usługi Azure Function do obsługiwania przekazywania i odświeżania usługi CDN. Udostępniliśmy przykładową implementację do użycia w temacie Przekazywanie zawartości statycznej i jej wstępne ładowanie w usłudze CDN za pomocą usługi Azure Functions.
Zawartość dynamiczna lub wewnętrzna
Na potrzeby plików często zapisywanych i odczytywanych przez aplikację (na przykład plików danych tymczasowych) lub plików statycznych, które są widoczne tylko dla aplikacji, możesz zainstalować udziały plików usługi Azure Storage jako trwałe woluminy. Aby uzyskać więcej informacji, zobacz Tworzenie i używanie woluminu w usłudze Azure Files w usłudze Azure Kubernetes Service (AKS).
Określanie mechanizmu trwałości sesji
Aby zidentyfikować używanego menedżera trwałości sesji, sprawdź pliki context.xml w aplikacji i konfiguracji serwera Tomcat. Poszukaj elementu <Manager>
, a następnie zanotuj wartość atrybutu className
.
Wbudowane na serwerze Tomcat implementacje aplikacji PersistentManager, na przykład StandardManager czy FileStore, nie są przeznaczone do użycia z rozproszoną, skalowaną platformą, taką jak usługa Kubernetes. Usługa AKS może równoważyć obciążenie między kilkoma zasobnikami i w dowolnym momencie w niewidoczny sposób uruchomić ponownie dowolny zasobnik, więc nie zaleca się utrwalania modyfikowalnego stanu w systemie plików.
Jeśli wymagana jest trwałość sesji, należy użyć alternatywnej PersistentManager
implementacji, która będzie zapisywać w zewnętrznym magazynie danych, takim jak VMware Tanzu Session Manager z pamięcią podręczną Redis Cache. Aby uzyskać więcej informacji, zobacz Korzystanie z usługi Redis jako pamięci podręcznej sesji na serwerze Tomcat.
Przypadki szczególne
Niektóre scenariusze produkcyjne mogą wymagać dodatkowych zmian lub wprowadzać dodatkowe ograniczenia. Chociaż takie scenariusze mogą być rzadko spotykane, ważne jest, aby upewnić się, że nie dotyczą aplikacji lub są prawidłowo obsługiwane.
Określanie, czy aplikacja korzysta z zaplanowanych zadań
Nie można używać zaplanowanych zadań, takich jak zadania Quartz Scheduler lub cron, z konteneryzowanymi wdrożeniami usługi Tomcat. Jeśli aplikacja jest skalowana w poziomie, jedno zaplanowane zadanie może być uruchamiane więcej niż jeden raz w zaplanowanym okresie. Ta sytuacja może prowadzić do niezamierzonych konsekwencji.
Utwórz spis wszystkich zaplanowanych zadań, wewnątrz lub na zewnątrz serwera aplikacji.
Określanie, czy aplikacja zawiera kod właściwy dla systemu operacyjnego
Jeśli aplikacja zawiera dowolny kod uwzględniający system operacyjny, w którym jest uruchomiona aplikacja, należy refaktoryzować aplikację, aby NIE POLEGAŁA na bazowym systemie operacyjnym. Na przykład może być konieczne zastąpienie wszystkich przypadków użycia elementów /
lub \
w ścieżkach systemu plików za pomocą elementów File.Separator
lub Path.get
.
Określanie, czy jest używana klasa MemoryRealm
Klasa MemoryRealm wymaga utrwalonego pliku XML. W usłudze Kubernetes ten plik musi zostać dodany do obrazu kontenera lub przekazany do udostępnionego magazynu, który jest dostępny dla kontenerów. Należy odpowiednio zmodyfikować parametr pathName
.
Aby ustalić, czy klasa MemoryRealm
jest aktualnie używana, sprawdź, czy w plikach server.xml i context.xml znajdują się elementy <Realm>
, których atrybut className
jest ustawiony na org.apache.catalina.realm.MemoryRealm
.
Określanie, czy jest używane śledzenie sesji SSL
W przypadku konteneryzowanych wdrożeń sesje SSL są zwykle odciążane poza kontenerem aplikacji, najczęściej przez kontroler ruchu przychodzącego. Jeśli aplikacja wymaga śledzenia sesji SSL, upewnij się, że ruch SSL jest bezpośrednio przesyłany do kontenera aplikacji.
Określanie, czy jest używana klasa AccessLogValve
W przypadku użycia klasy AccessLogValve parametr directory
należy ustawić na zainstalowany udział plików usługi Azure Files lub jeden z jego podkatalogów.
Testowanie w miejscu
Przed utworzeniem obrazów kontenerów dokonaj migracji aplikacji do zestawu JDK i serwera Tomcat, których zamierzasz używać w usłudze AKS. Dokładnie przetestuj swoją aplikację, aby zapewnić jej zgodność i wydajność.
Parametryzacja konfiguracji
Podczas wstępnej migracji w plikach server.xml i context.xml prawdopodobnie zostały zidentyfikowane klucze tajne i zależności zewnętrzne, takie jak źródła danych. W przypadku każdego zidentyfikowanego w ten sposób elementu zastąp wszelkie nazwy użytkownika, hasła, parametry połączenia lub adresy URL zmienną środowiskową.
Uwaga
Firma Microsoft zaleca korzystanie z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Przepływ uwierzytelniania opisany w tej procedurze, taki jak bazy danych, pamięci podręczne, komunikaty lub usługi sztucznej inteligencji, wymaga bardzo wysokiego stopnia zaufania w aplikacji i niesie ze sobą ryzyko, które nie występują w innych przepływach. Użyj tego przepływu tylko wtedy, gdy bardziej bezpieczne opcje, takie jak tożsamości zarządzane dla połączeń bez hasła lub bez kluczy, nie są opłacalne. W przypadku operacji maszyny lokalnej preferuj tożsamości użytkowników dla połączeń bez hasła lub bez klucza.
Na przykład załóżmy, że plik context.xml zawiera następujący 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="{password}"
/>
W takim przypadku można go zmienić w sposób pokazany w następującym przykładzie:
<Resource
name="jdbc/dbconnection"
type="javax.sql.DataSource"
url="${postgresdb.connectionString}"
driverClassName="org.postgresql.Driver"
username="${postgresdb.username}"
password="${postgresdb.password}"
/>
Migracja
Z wyjątkiem pierwszego kroku („Aprowizacja rejestru kontenerów i usługi AKS”) zalecamy wykonanie poniższych czynności osobno dla każdej aplikacji (plik WAR), którą chcesz migrować.
Uwaga
Niektóre wdrożenia produktu Tomcat mogą mieć wiele aplikacji uruchomionych na jednym serwerze Tomcat. Jeśli tak jest w tym wdrożeniu, zdecydowanie zalecamy uruchomienie każdej aplikacji w oddzielnym zasobniku. Pozwala to zoptymalizować wykorzystanie zasobów dla każdej aplikacji przy jednoczesnym zminimalizowaniu złożoności i sprzężenia klas.
Aprowizacja rejestru kontenerów i usługi AKS
Utwórz rejestr kontenerów i klaster usługi Azure Kubernetes, którego nazwa główna usługi ma rolę czytelnika w rejestrze. Upewnij się, że wybrano odpowiedni model sieci dopasowany do wymagań w zakresie łączności sieciowej klastra.
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
Przygotowanie komputera do wdrożenia
Sklonuj repozytorium GitHub z przewodnika szybkiego startu „Tomcat w kontenerach”. Repozytorium zawiera pliki konfiguracji Dockerfile i Tomcat z wieloma zalecanymi optymalizacjami. W poniższych krokach przedstawimy zmiany, które prawdopodobnie trzeba będzie wprowadzić w tych plikach przed skompilowaniem obrazu kontenera i wdrożeniem go do usługi AKS.
Otwieranie portów dla klastrowania, jeśli jest konieczne
Jeśli zamierzasz używać klastrowania Tomcat w usłudze AKS, upewnij się, że wymagane zakresy portów są uwidocznione w pliku Dockerfile. Aby określić adres IP serwera w pliku server.xml, należy użyć wartości ze zmiennej, która jest inicjowana przy uruchamianiu kontenera pod adresem IP zasobnika.
Alternatywnie stan sesji można utrwalić w lokalizacji alternatywnej, aby był dostępny w różnych replikach.
Aby ustalić, czy aplikacja używa klastrowania, poszukaj elementu <Cluster>
wewnątrz elementów <Host>
lub <Engine>
w pliku server.xml.
Dodawanie zasobów JNDI
Edytuj server.xml , aby dodać zasoby przygotowane w krokach przed migracją, takich jak źródła danych, jak pokazano w poniższym przykładzie:
Uwaga
Firma Microsoft zaleca korzystanie z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Przepływ uwierzytelniania opisany w tej procedurze, taki jak bazy danych, pamięci podręczne, komunikaty lub usługi sztucznej inteligencji, wymaga bardzo wysokiego stopnia zaufania w aplikacji i niesie ze sobą ryzyko, które nie występują w innych przepływach. Użyj tego przepływu tylko wtedy, gdy bardziej bezpieczne opcje, takie jak tożsamości zarządzane dla połączeń bez hasła lub bez kluczy, nie są opłacalne. W przypadku operacji maszyny lokalnej preferuj tożsamości użytkowników dla połączeń bez hasła lub bez klucza.
<!-- 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>
Aby uzyskać dodatkowe instrukcje dotyczące źródła danych, zapoznaj się z następującymi sekcjami przewodnika JNDI Datasource How-To (Źródło danych JNDI — porady) w dokumentacji serwera Tomcat:
Kompilacja i wypychanie obrazu
Najprostszym sposobem kompilowania i przekazywania obrazu do usługi Azure Container Registry (ACR) do użycia przez usługę AKS jest zastosowanie polecenia az acr build
. To polecenie nie wymaga, aby platforma Docker była zainstalowana na komputerze. Na przykład jeśli masz powyższy plik Dockerfile oraz pakiet aplikacji petclinic.war w bieżącym katalogu, możesz utworzyć obraz kontenera w usłudze ACR przy użyciu jednego kroku:
az acr build \
--image "${acrName}.azurecr.io/petclinic:{{.Run.ID}}" \
--registry $acrName \
--build-arg APP_FILE=petclinic.war \
--build-arg=prod.server.xml .
Możesz pominąć parametr --build-arg APP_FILE...
, jeśli plik WAR ma nazwę ROOT.war. Możesz pominąć parametr --build-arg SERVER_XML...
, jeśli plik XML serwera ma nazwę server.xml. Oba pliki muszą znajdować się w tym samym katalogu co plik Dockerfile.
Można też użyć interfejsu wiersza polecenia platformy Docker, aby utworzyć obraz lokalnie. Takie podejście może uprościć testowanie i udoskonalanie obrazu przed początkowym wdrożeniem w usłudze ACR. Jednak wymaga instalacji interfejsu wiersza polecenia platformy Docker i uruchomienia demona platformy Docker.
# 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"
Aby uzyskać więcej informacji, zobacz moduł Learn dotyczący tworzenia i przechowywania obrazów kontenerów na platformie Azure.
Aprowizacja publicznego adresu IP
Jeśli aplikacja ma być dostępna spoza sieci wewnętrznej lub wirtualnej, będzie wymagany publiczny, statyczny adres IP. Ten adres IP powinien być aprowizowany wewnątrz grupy zasobów węzła klastra.
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}."
Wdrażanie w usłudze AKS
Twórz i stosuj pliki Kubernetes YAML. Jeśli tworzysz zewnętrzny moduł równoważenia obciążenia (do aplikacji lub kontrolera ruchu przychodzącego), upewnij się, że adres IP aprowizowany w poprzedniej sekcji zostanie podany jako LoadBalancerIP
.
Uwzględnij zewnętrzne parametry jako zmienne środowiskowe. Nie dołączaj wpisów tajnych (takich jak hasła, klucze interfejsu API i parametry połączenia JDBC). Wpisy tajne znajdują się w sekcji Konfiguracja usługi KeyVault FlexVolume.
Konfigurowanie magazynu trwałego
Jeśli aplikacja wymaga magazynu trwałego, należy skonfigurować co najmniej jeden wolumin trwały.
Możesz chcieć utworzyć wolumin trwały przy użyciu usługi Azure Files zainstalowanej w katalogu dzienników Tomcat (/tomcat_logs), aby zachowywać dzienniki centralnie. Aby uzyskać więcej informacji, zobacz Dynamiczne tworzenie i korzystanie z trwałego woluminu za pomocą usługi Azure Files w usłudze Azure Kubernetes Service (AKS).
Konfigurowanie usługi KeyVault FlexVolume
Utwórz usługę Azure KeyVault i wypełnij wszystkie niezbędne wpisy tajne. Następnie skonfiguruj usługę KeyVault FlexVolume, aby udostępnić te wpisy tajne w zasobnikach.
Aby zaimportować certyfikaty do lokalnego magazynu kluczy w kontenerze, należy zmodyfikować skrypt uruchamiania (startup.sh w repozytorium GitHub Tomcat w kontenerach).
Uwaga
Firma Microsoft zaleca korzystanie z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Przepływ uwierzytelniania opisany w tej procedurze, taki jak bazy danych, pamięci podręczne, komunikaty lub usługi sztucznej inteligencji, wymaga bardzo wysokiego stopnia zaufania w aplikacji i niesie ze sobą ryzyko, które nie występują w innych przepływach. Użyj tego przepływu tylko wtedy, gdy bardziej bezpieczne opcje, takie jak tożsamości zarządzane dla połączeń bez hasła lub bez kluczy, nie są opłacalne. W przypadku operacji maszyny lokalnej preferuj tożsamości użytkowników dla połączeń bez hasła lub bez klucza.
Migrowanie zaplanowanych zadań
Aby wykonać zaplanowane zadania w klastrze usługi AKS, zdefiniuj zadania cron wedle potrzeby.
Po migracji
Po przeprowadzeniu migracji aplikacji do usługi AKS należy sprawdzić, czy działa ona zgodnie z oczekiwaniami. Po wykonaniu tych czynności skorzystaj z naszych zaleceń, które mogą sprawić, że aplikacja będzie bardziej natywna w chmurze.
Rozważ dodanie nazwy DNS do adresu IP przydzielonego do kontrolera ruchu przychodzącego lub modułu równoważenia obciążenia aplikacji. Aby uzyskać więcej informacji, zobacz Używanie protokołu TLS z kontrolerem ruchu przychodzącego w usłudze Azure Kubernetes Service (AKS).
Rozważ dodanie do swojej aplikacji elementu chart programu HELM. Wykres HELM umożliwia parametryzację wdrożenia aplikacji w celu używania i dostosowywania aplikacji przez bardziej różnorodnych klientów.
Zaprojektuj i zaimplementuj strategię DevOps. Aby zachować niezawodność przy jednoczesnym zwiększaniu szybkości tworzenia rozwiązań, rozważ automatyzację wdrożeń i testowania przy użyciu usługi Azure Pipelines.
Włącz monitorowanie platformy Azure dla klastra, aby umożliwić zbieranie dzienników kontenerów, śledzenie użycia i korzystanie z innych funkcji.
Rozważ ujawnienie metryk właściwych dla aplikacji za pośrednictwem systemu Prometheus. Prometheus to struktura metryk typu open source, szeroko przyjęta w społeczności Kubernetes. Wycinanie metryk systemu Prometheus można skonfigurować w usłudze Azure Monitor zamiast hostować własny serwer Prometheus w celu włączenia agregacji metryk z aplikacji i umożliwienia automatycznego reagowania na nietypowe warunki lub ich eskalowania.
Zaprojektuj i zaimplementuj strategię ciągłości działania i odzyskiwania po awarii. W przypadku aplikacji o krytycznym znaczeniu rozważ zastosowanie architektury wdrażania w wielu regionach.
Zapoznaj się z zasadami obsługi wersji platformy Kubernetes. To użytkownik ponosi odpowiedzialność za aktualizowanie klastra usługi AKS, aby mieć pewność, że zawsze korzysta z obsługiwanej wersji.
Wszyscy członkowie zespołu odpowiedzialni za administrowanie klastrami i programowanie aplikacji powinni zapoznać się z odpowiednimi najlepszymi rozwiązaniami dotyczącymi usługi AKS.
Oceń elementy w pliku logging.properties. Rozważ wyeliminowanie lub zredukowanie niektórych danych wyjściowych rejestrowania, aby zwiększyć wydajność.
Rozważ monitorowanie rozmiaru pamięci podręcznej kodu i dodanie parametrów
-XX:InitialCodeCacheSize
oraz-XX:ReservedCodeCacheSize
do zmiennejJAVA_OPTS
w pliku Dockerfile, aby zwiększyć wydajność.