將 Tomcat 應用程式遷移至 Azure Kubernetes Service 上的容器

本指南說明當您想要移轉現有的Tomcat應用程式以在 Azure Kubernetes Service 上執行時應該注意的事項。

移轉前

若要確保成功移轉,請先完成下列各節所述的評量和清查步驟。

清查外部資源

外部資源,例如數據源、JMS 訊息代理程式,以及其他資源會透過 Java 命名和目錄介面 (JNDI) 插入。 某些這類資源可能需要移轉或重新設定。

在您的應用程式內

檢查 META-INF/context.xml 檔案。 尋找 <Resource> 元素內的 <Context> 元素。

在應用程式伺服器上

檢查 $CATALINA_BASE/conf/context.xml$CATALINA_BASE/conf/server.xml 檔案,以及 $CATALINA_BASE/conf/[engine-name]/[host-name] 目錄中找到的 .xml 檔案。

在context.xml檔案中,最上層<Context>元素內的元素將會描述 <Resource> JNDI資源。

在 server.xml 檔案中,JNDI 資源將由 元素內的<GlobalNamingResources>元素描述<Resource>

資料來源

資料來源是 JNDI 資源, type 屬性設定為 javax.sql.DataSource。 針對每個數據源,記載下列資訊:

  • 數據源名稱為何?
  • 什麼是聯機集區設定?
  • 哪裡可以找到 JDBC 驅動程式 JAR 檔案?

如需詳細資訊,請參閱 Tomcat檔中的JNDI資料源操作說明

所有其他外部資源

在本指南中記載每個可能的外部相依性並不可行。 您的小組有責任確認您可以在移轉後滿足應用程式的每個外部相依性。

清查秘密

密碼和安全字串

檢查生產伺服器上的所有屬性和組態檔,以取得任何秘密字串和密碼。 請務必在 $CATALINA_BASE/conf 中檢查 server.xmlcontext.xml 您也可以在應用程式內找到包含密碼或認證的組態檔。 這可能包括 META-INF/context.xml,以及 Spring Boot 應用程式、 application.propertiesapplication.yml 檔案。

判斷文件系統是否使用和方式

應用程式伺服器上的檔案系統使用方式都需要重新設定,或在某些情況下,架構變更。 您可以識別下列部分或所有案例。

唯讀靜態內容

如果您的應用程式目前提供靜態內容,您將需要其替代位置。 您可能想要考慮將靜態內容移至 Azure Blob 儲存體,並新增 Azure CDN 以進行全球閃電快速下載。 如需詳細資訊,請參閱 Azure 儲存體 中的靜態網站裝載和快速入門:整合 Azure 記憶體帳戶與 Azure CDN。 您也可以直接將靜態內容部署到 Azure Spring Apps 企業版方案中的應用程式。 如需詳細資訊,請參閱 部署Web靜態檔案

動態發佈的靜態內容

如果您的應用程式允許應用程式上傳/產生的靜態內容,但在應用程式建立後是不可變的,您可以使用如上所述 Azure Blob 儲存體 和 Azure CDN,搭配 Azure 函式來處理上傳和 CDN 重新整理。 我們在使用 Azure Functions 上傳和 CDN 預先載入靜態內容時,提供了範例實作。 您也可以直接將靜態內容部署到 Azure Spring Apps 企業版方案中的應用程式。 如需詳細資訊,請參閱 部署Web靜態檔案

動態或內部內容

對於應用程式經常寫入和讀取的檔案(例如暫存數據檔),或只有應用程式可見的靜態檔案,您可以將 Azure 儲存體 共用掛接為永續性磁碟區。 如需詳細資訊,請參閱在 Azure Kubernetes Service 中動態建立和使用永續性磁碟區與 Azure 檔案儲存體。

識別會話持續性機制

若要識別正在使用中的會話持續性管理員,請檢查 應用程式和 Tomcat 組態中的 context.xml 檔案。 尋找 <Manager> 項目,然後記下 屬性的值 className

Tomcat 的內建 PersistentManager 實作,例如 StandardManagerFileStore 不是專為搭配分散式、縮放平臺使用而設計,例如 Kubernetes。 AKS 可能會在數個 Pod 之間進行負載平衡,並隨時以透明方式重新啟動任何 Pod,不建議將可變狀態保存到文件系統。

如果需要會話持續性,您必須使用替代 PersistentManager 實作來寫入外部數據存放區,例如具有 Redis 快取的 VMware Tanzu 會話管理員。 如需詳細資訊,請參閱 搭配 Tomcat 使用 Redis 作為會話快取。

特殊情況

某些生產案例可能需要額外的變更,或施加額外的限制。 雖然這類案例可能不常發生,但請務必確保它們無法套用至您的應用程式或正確解決。

判斷應用程式是否依賴排程的作業

排程的作業,例如讓排程器工作或cron作業無法與容器化Tomcat部署搭配使用。 如果您的應用程式相應放大,每個排程期間可能會執行一次以上的排程工作。 這種情況可能會導致非預期的後果。

清查應用程式伺服器內部或外部的任何排程工作。

判斷您的應用程式是否包含 OS 特定程式代碼

如果您的應用程式包含任何可容納應用程式執行之作業系統的程式代碼,則您的應用程式必須重構為 NOT 依賴基礎 OS。 例如,檔案系統路徑中的任何 使用 /\ 可能需要取代為 File.SeparatorPath.get

判斷是否使用MemoryRealm

MemoryRealm 需要保存的 XML 檔案。 在 Kubernetes 上,此檔案必須新增至容器映像,或上傳至 可供容器使用的共享記憶體。 pathName參數必須據以修改。

若要判斷目前是否 MemoryRealm 使用,請檢查您的 server.xmlcontext.xml 檔案,並搜尋 <Realm>className 屬性設定為 org.apache.catalina.realm.MemoryRealm的專案。

判斷是否使用 SSL 工作階段追蹤

在容器化部署中,SSL 會話通常會從應用程式容器外卸除,通常是由輸入控制器卸除。 如果您的應用程式需要 SSL 會話追蹤,請確定 SSL 流量會直接傳遞至應用程式容器。

判斷是否使用 AccessLogValve

如果使用 AccessLogValvedirectory參數應該設定為掛接 Azure 檔案儲存體 共用或其子目錄之一。

就地測試

建立容器映像之前,請先將應用程式移轉至您想要在 AKS 上使用的 JDK 和 Tomcat。 徹底測試您的應用程式,以確保相容性和效能。

參數化組態

在移轉前,您可能會在 server.xmlcontext.xml 檔案中識別秘密和外部相依性,例如數據源。 因此,針對所識別的每個專案,將任何使用者名稱、密碼、連接字串 或URL取代為環境變數。

例如,假設 context.xml 檔案包含下列元素:

<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$$"
/>

在此情況下,您可以變更它,如下列範例所示:

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

遷移

除了第一個步驟(「布建容器登錄和 AKS」之外,我們建議您針對您想要移轉的每個應用程式個別遵循下列步驟。

注意

某些 Tomcat 部署可能會有多個應用程式在單一 Tomcat 伺服器上執行。 如果您的部署是這種情況,強烈建議您在個別 Pod 中執行每個應用程式。 這可讓您優化每個應用程式的資源使用率,同時將複雜度和結合度降至最低。

布建容器登錄和 AKS

建立容器登錄和 Azure Kubernetes 叢集,其服務主體在登錄上具有讀取者角色。 請務必 為叢集的網路需求選擇適當的網路模型

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

準備部署成品

複製 Tomcat On Containers 快速入門 GitHub 存放庫。 其中包含一些建議優化功能的 Dockerfile 和 Tomcat 組態檔。 在下列步驟中,我們概述您可能需要對這些檔案所做的修改,再建置容器映像並部署至 AKS。

視需要開啟叢集的埠

如果您想要在 AKS 上使用 Tomcat 叢集 ,請確定 Dockerfile 中會公開必要的埠範圍。 若要在 server.xml指定伺服器 IP 位址,請務必使用容器啟動時初始化之變數的值至 Pod 的 IP 位址。

或者,會話狀態可以 保存至替代位置 ,以便跨複本使用。

若要判斷您的應用程式是否使用叢集,請在 server.xml 檔案中<Host>尋找 <Cluster><Engine> 元素內的 專案。

新增 JNDI 資源

編輯 server.xml 以新增您在移轉前步驟中準備的資源,例如數據源。

例如:

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

如需其他資料來源指示,請參閱 Tomcat 檔中 JNDI 資料來源操作 說明的下列各節

組建並推送映像

建置映射並將其上傳至 Azure Container Registry (ACR) 以供 AKS 使用的最簡單方式是使用 az acr build 命令。 此命令不需要在您的電腦上安裝 Docker。 例如,如果您的上述 Dockerfile 和目前目錄中的應用程式套件 petclinic.war ,您可以使用一個步驟在 ACR 中建置容器映射:

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

如果您的 WAR 檔案名為 ROOT.war --build-arg APP_FILE... 您可以省略 參數。 如果您的伺服器 XML 檔案命名 為 server.xml --build-arg SERVER_XML... 您可以省略 參數。 這兩個檔案必須位於與 Dockerfile 相同的目錄中。

或者,您可以使用 Docker CLI 在本機建置映射。 這種方法可以簡化在初始部署至 ACR 之前測試和精簡映射。 不過,它需要安裝 Docker CLI 並執行 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"

如需詳細資訊,請參閱在 Azure 中建置和儲存容器映射的 Learn 課程模組

布建公用 IP 位址

如果您的應用程式可從內部或虛擬網路外部存取,則需要公用靜態 IP 位址。 此 IP 位址應該布建在叢集的節點資源群組內。

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}."

部署到 AKS

建立並套用 Kubernetes YAML 檔案。 。 如果您要建立外部負載平衡器(無論是您的應用程式還是輸入控制器),請務必提供上一節中布建的 IP 位址作為 LoadBalancerIP

將外部化參數納入 為環境變數 。 請勿包含秘密(例如密碼、API 金鑰和 JDBC 連接字串)。 設定 KeyVault FlexVolume 一節涵蓋 秘密。

設定永續性儲存體

如果您的應用程式需要非揮發性儲存體,請設定一或多個 永續性磁片區

您可能想要使用掛接至 Tomcat 記錄目錄 ( //tomcat_logs ) Azure 檔案儲存體來建立永續性磁片區,以集中保留記錄。 如需詳細資訊,請參閱 在 Azure Kubernetes Service 中動態建立和使用永續性磁片區搭配Azure 檔案儲存體。

設定 KeyVault FlexVolume

建立 Azure KeyVault 並填入所有必要的秘密。 然後,設定 KeyVault FlexVolume ,讓 Pod 能夠存取這些秘密。

您必須修改啟動腳本( startup.sh 容器 上的 Tomcat GitHub 存放庫中),才能將憑證匯入容器上的本機密鑰存放區。

移轉排程的工作

若要在 AKS 叢集上執行排程的工作,請視需要定義 Cron 作業

移轉後

既然您已將應用程式移轉至 AKS,您應該確認它如預期般運作。 完成之後,我們有一些建議可讓您的應用程式更原生雲端。

  • 請考慮將 DNS 名稱新增至配置給輸入控制器或應用程式負載平衡器的 IP 位址。 如需詳細資訊,請參閱 在 AKS 中使用靜態公用 IP 位址建立輸入控制器。

  • 請考慮 為您的應用程式 新增 HELM 圖表。 Helm 圖表可讓您將應用程式部署參數化,以供一組更多樣化的客戶使用和自訂。

  • 設計和實作 DevOps 策略。 若要在提高開發速度的同時維護可靠性,請考慮 使用 Azure Pipelines 將部署和測試自動化。

  • 啟用 叢集 的 Azure 監視,以允許收集容器記錄、追蹤使用率等等。

  • 請考慮透過 Prometheus 公開應用程式特定計量。 Prometheus 是 Kubernetes 社群中廣泛採用的開放原始碼計量架構。 您可以在 Azure 監視器 中設定 Prometheus 計量,而不是裝載自己的 Prometheus 伺服器,以啟用應用程式的計量匯總,以及自動回應或呈報異常狀況。

  • 設計和實作商務持續性和災害復原策略。 針對任務關鍵性應用程式,請考慮 多區域部署架構

  • 檢閱 Kubernetes 版本支援原則 。 您必須繼續 更新 AKS 叢集 ,以確保它一律執行支援的版本。

  • 讓負責叢集管理和應用程式開發的所有小組成員檢閱相關的 AKS 最佳做法

  • 評估 logging.properties 檔案中的 專案。 請考慮排除或減少一些記錄輸出以改善效能。

  • 請考慮 監視程式碼快取大小 ,並將 參數 -XX:InitialCodeCacheSize-XX:ReservedCodeCacheSize 新增至 JAVA_OPTS Dockerfile 中的變數,以進一步優化效能。