Tomcat サーバーの移行計画をカスタマイズする

移行の準備で作成した移行計画ファイルを確認し、移行を実行する前にファイルをカスタマイズします。移行計画の詳細は、ソースからワークロード コンテナ アーティファクトを抽出する際に使用されます。

このセクションでは、移行の内容と、移行を実行してデプロイ アーティファクトを生成する前に考慮すべきカスタマイズについて説明します。

始める前に

このトピックでは、すでに移行を準備し、移行計画ファイルが作成されていることを前提としています。

移行計画を編集する

ファイル システムをコピーして分析すると、指定した出力パス(ANALYSIS_OUTPUT_PATH/config.yaml)に新しく作成されたディレクトリに移行計画が作成されます。

必要に応じて移行計画を編集し、変更を保存します。

移行計画の詳細とコメントを確認して、必要に応じて情報を追加します。特に、次のセクションに関する編集を検討してください。

Docker イメージを指定する

移行計画では、Tomcat のバージョン、Java のバージョン、Java ベンダーに基づいて Docker コミュニティ イメージタグを生成します。

  • Tomcat バージョン: Tomcat バージョンが検出され、メジャー バージョンに変換されます(マイナー バージョンはサポートされていません)。Tomcat のバージョンを検出できない場合、baseImage.name には空の文字列が含まれます。
  • Java のバージョン: Java のバージョンは、java-version パラメータにより変わります。デフォルトでは 11 に設定されています。
  • Java ベンダー: Java ベンダーが定数 temurin に設定されます。

たとえば、Tomcat バージョン 9.0、Java バージョン 11、Java ベンダー temurin 用に生成された Docker コミュニティ イメージタグは tomcat:9.0-jre11-temurin です。

移行計画では、baseImage.name フィールドは、コンテナ イメージのベースとして使用される Docker イメージのタグになります。

ソース VM で検出された元の Tomcat バージョンと Java バージョンは、初期検出によって生成された discovery-report.yaml に設定されます。

Docker コミュニティ イメージを変更する場合や、独自の Docker イメージを指定する場合は、移行計画の baseImage.name を次の形式で変更します。

tomcatServers:
    - name: latest
      . . .
      images:
        - name: tomcat-latest
          . . .
          baseImage:
            name: BASE_IMAGE_NAME

BASE_IMAGE_NAME は、コンテナ イメージのベースとして使用する Docker イメージに置き換えます。

Tomcat のインストール パスを更新する

移行プロセス中に、ターゲット イメージにデフォルト以外の CATALINA_HOME パスがある場合は、カスタムの CATALINA_HOME パスを指定できます。移行計画でターゲット catalinaHome フィールドを直接編集します。

tomcatServers:
  - name: latest
    . . .
    images:
      - name: tomcat-latest
        . . .
        baseImage:
          name: BASE_IMAGE_NAME
          catalinaHome: PATH

PATH は、Tomcat のインストール パスに置き換えます。

ユーザーとグループをカスタマイズする

移行プロセス中に、ターゲット イメージが root:root とは異なるユーザーとグループで実行される場合は、アプリケーションを実行するカスタム ユーザーとグループを指定できます。移行計画でユーザーとグループを直接編集します。

tomcatServers:
  - name: latest
    . . .
    images:
      - name: tomcat-latest
        . . .
        userName: USERNAME
        groupName: GROUP_NAME

次のように置き換えます。

  • USERNAME: 使用するユーザー名
  • GROUP_NAME: 使用するグループ名

SSL を構成する

新しい Tomcat 移行を作成すると、検出プロセスにより、検出されたアプリケーションに対してサーバーをスキャンします。

検出後、移行計画に次のフィールドが自動的に入力されます。

  • excludeFiles: 移行から除外するファイルとディレクトリの一覧を表示します。

    デフォルトでは、検出中に検出されたすべての機密性の高いパスと証明書がこのフィールドに自動的に追加され、移行から除外されます。このリストからパスを削除すると、ファイルまたはディレクトリがコンテナ イメージにアップロードされます。コンテナ イメージからファイルまたはディレクトリを除外するには、このリストにパスを追加します。

  • sensitiveDataPaths: 検出プロセスで検出されるすべての機密パスと証明書が一覧表示されます。

    証明書をリポジトリにアップロードするには、includeSensitiveData フィールドを true に設定します。

    # Sensitive data which will be filtered out of the container image.
    # If includeSensitiveData is set to true the sensitive data will be mounted on the container.
    
    includeSensitiveData: true
    tomcatServers:
    - name: latest
      catalinaBase: /opt/tomcat/latest
      catalinaHome: /opt/tomcat/latest
      # Exclude files from migration.
      excludeFiles:
      - /usr/local/ssl/server.pem
      - /usr/home/tomcat/keystore
      - /usr/home/tomcat/truststore
      images:
      - name: tomcat-latest
        ...
        # If set to true, sensitive data specified in sensitiveDataPaths will be uploaded to the artifacts repository.
        sensitiveDataPaths:
        - /usr/local/ssl/server.pem
        - /usr/home/tomcat/keystore
        - /usr/home/tomcat/truststore
    

    移行が完了すると、アーティファクト リポジトリのシークレット ファイル secrets.yaml にシークレットが追加されます。

ウェブアプリのロギング

Migrate to Containers では、CATALINA_HOME にある log4j v2logbacklog4j v1.x のロギングをサポートしています。

Migrate to Containers では、ログ構成を修正した追加のアーカイブ ファイルが作成され、すべてのファイル形式のアペンダーがコンソールのアペンダーに変換されます。このアーカイブの内容は、ログの収集を有効にする場合や、ログ収集ソリューション(Google Cloud Logging など)にストリーミングを行う場合のリファレンスとして使用できます。

メモリ割り当て

移行プロセス中に、個々のコンテナに移行されるアプリケーションにメモリの上限を指定できます。移行計画で、次の形式を使用してメモリの上限を直接編集します。

tomcatServers:
    - name: latest
      . . .
      images:
        - name: tomcat-latest
          . . .
          resources:
            memory:
              limit: 2048M
              requests: 1280M

limit の推奨値は Xmx の 200%(Java の最大ヒープサイズ)です。requests の推奨値は Xmx の 150% です。

Xmx の値を表示するには、次のコマンドを実行します。

ps aux | grep catalina

移行計画でメモリの上限が定義されている場合、移行の成功後に他のアーティファクトとともに生成された Dockerfile に宣言が反映されます。

FROM tomcat:8.5-jdk11-openjdk

# Add JVM environment variables for tomcat
ENV CATALINA_OPTS="${CATALINA_OPTS} -XX:MaxRAMPercentage=50.0 -XX:InitialRAMPercentage=50.0 -XX:+UseContainerSupport <additional variables>"

この設定では、初期サイズと最大サイズが上限値の 50% 以下と定義されます。これにより、Tomcat Java ヒープの割り当てサイズを Pod のメモリ上限に合わせて変更できます。

Tomcat 環境変数を設定する

移行の成功後に他のアーティファクトとともに生成された Dockerfile で CATALINA_OPTS を設定する場合は、最初に移行計画に catalinaOpts フィールドに追加します。次の例は、更新された catalinaOpts フィールドを示しています。

tomcatServers:
    - name: latest
      . . .
      images:
        - name: tomcat-latest
          . . .
          resources:
            . . .
          catalinaOpts: "-Xss10M"

Migrate to Containers は、Dockerfile の catalinaOpts データを解析します。次の例は、解析の出力を示しています。

FROM 8.5-jdk11-openjdk-slim

## setenv.sh script detected.
## Modify env variables on the script and add definitions to the migrated
## tomcat server, if needed (less recommended than adding env variables directly
## to CATALINA_OPTS) by uncomment the line below
#ADD --chown=root:root setenv.sh /usr/local/tomcat/bin/setenv.sh

# Add JVM environment variables for the tomcat server
ENV CATALINA_OPTS="${CATALINA_OPTS} -XX:MaxRAMPercentage=50.0 -XX:InitialRAMPercentage=50.0 -Xss10M"

Tomcat 環境変数を設定する際に、Tomcat サーバーの /bin フォルダにある setenv.sh スクリプトを使用できます。Tomcat の環境変数の詳細については、Tomcat のドキュメントをご覧ください。

Tomcat 環境変数の設定に setenv.sh を使用する場合は、Dockerfile を編集する必要があります。

Tomcat 正常性プローブを設定する

マネージド コンテナのダウンタイムと準備完了ステータスは、Tomcat ウェブサーバーの移行計画でプローブを指定することによりモニタリングできます。正常性プローブによるモニタリングは、移行されたコンテナのダウンタイムを減らし、モニタリングを改善する効果があります。

不明なヘルス状態は、可用性の低下、可用性モニタリングの誤判定、データ損失を引き起こす可能性があります。正常性プローブがなければ、kubelet は、コンテナの健全性を想定することしかできず、準備ができていないコンテナ インスタンスにトラフィックを送信する可能性があります。これにより、トラフィックが失われる場合があります。kubelet は、フリーズされたコンテナを検出できず、コンテナは再起動されません。

正常性プローブは、コンテナの起動時に小さなスクリプト ステートメントを実行します。このスクリプトは、成功したプローブの種類をチェックします。これは、使用されるプローブのタイプによって定義されます。期間は移行計画の periodSeconds フィールドで定義されます。これらのスクリプトは、手動で実行または定義できます。

kubelet のプローブの詳細については、Kubernetes ドキュメントの liveness プローブ, readiness プローブ、startup プローブの構成をご覧ください。

構成可能なプローブには 2 つのタイプがありますが、どちらのプローブも probe-v1-core リファレンスで定義された Probe-v1-core で、container-v1-core の対応フィールドと同じ機能を共有します。

  • livenessProbe: livenessProbe は、コンテナを再起動するタイミングを把握するために使用します。

  • readinessProbe: readinessProbe は、コンテナがトラフィックの受信を開始する準備が整うタイミングを認識するために使用します。プローブが成功した場合にのみ Pod へのトラフィックの送信を開始するには、readinessProbe を指定します。readinessProbe は livenessProbe と同様に機能する場合もありますが、仕様の readinessProbe は、Pod がトラフィックを受信せずに起動し、プローブが成功した後にのみトラフィックの受信を開始することを示します。

調査後、プローブ構成が移行計画に追加されます。プローブは、次の例に示すようにデフォルトの構成で使用できます。プローブを無効にするには、YAML から probes セクションを削除します。

tomcatServers:
- name: latest
  images:
  - name: tomcat-latest
    ports:
    - 8080
    probes:
      livenessProbe:
        tcpSocket:
          port: 8080
      readinessProbe:
        tcpSocket:
          port: 8080

この移行計画は、既存の Tomcat HTTP エンドポイントを使用するように変更できます。

tomcatServers:
- name: latest
  images:
  - name: tomcat-latest
    ports:
    - 8080
    probes:
      livenessProbe:
       httpGet:
          path: /healthz
          port: 8080
          httpHeaders:
          - name: Custom-Header
            value: Awesome
        initialDelaySeconds: 3
        periodSeconds: 3
      readinessProbe:
        httpGet:
        tcpSocket:
          port: 8080

プローブを使用してコンテナを確認するには、事前定義された 4 つの方法があります。各プローブでは、次の 4 つのメカニズムのいずれか 1 つのみを定義する必要があります。

  • exec: コンテナ内で指定されたコマンドを実行します。終了ステータス コードが 0 の場合、正常に実行されたとみなされます。
  • grpc: gRPC を使用してリモート プロシージャ コールを実行します。gRPC プローブはアルファ版の機能です。
  • httpGet: 指定されたポートとパスにある Pod の IP アドレスに対して HTTP GET リクエストを実行します。ステータス コードが 200 以上 400 未満の場合、リクエストが正常に終了したとみなされます。
  • tcpSocket: 指定されたポートにある Pod の IP アドレスに対して TCP チェックを実行します。ポートが開いている場合、チェックが正常に終了したとみなされます。

デフォルトでは、移行計画によって tcpSocket プローブ方式が有効になります。別のプローブ方式を使用するには、移行計画を手動で構成します。また、移行計画を使用してカスタム コマンドとスクリプトを定義することもできます。

デフォルトの readinessProbe を使用しながら、readinessProbe に外部依存関係を追加するには、exec readinessProbe と、ロジックを実装するスクリプトを定義します。

Tomcat クラスタリング構成を確認する

Tomcat クラスタリングは、すべての Tomcat ノードにセッション情報をレプリケートするために使用されます。これにより、任意のバックエンド アプリケーション サーバーを呼び出すことができます。クライアント セッション情報を失うことはありません。クラスタリング構成の詳細については、Tomcat ドキュメントのクラスタリング / セッション レプリケーションの方法をご覧ください。

Tomcat クラスタリング クラスは SimpleTcpListener と呼ばれ、ピアの検出にマルチキャスト ハートビート メッセージを使用します。Cloud 環境はマルチキャストをサポートしていないため、可能であれば、クラスタリング構成を変更するか、削除する必要があります。

ロードバランサが、バックエンドの Tomcat サーバーへのスティッキー セッションを実行して維持するように構成されている場合、server.xml Engine 構成で構成された jvmRoute プロパティを使用できます。

移行元の環境で、サポートされていないクラスタリング構成を使用している場合は、server.xml ファイルを変更して構成を無効にするか、サポートされている構成を使用します。

  • Tomcat v8.5 以上: Tomcat バージョン 8.5 でクラスタリングを無効にする必要があります。クラスタリングを無効にするには、server.xml<Cluster … /> セクションをコメントアウトする必要があります。
  • Tomcat v9 以降: Tomcat バージョン 9 以降では、KubernetesMembershipService を使用して Cluster クラスを有効にできます。KubernetesMembershipService は Kubernetes 固有のクラスであり、ピアの検出に Kubernetes API を使用します。

    • Kubernetes プロバイダ: Kubernetes プロバイダの構成例を次に示します。

      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
      <Channel className="org.apache.catalina.tribes.group.GroupChannel">
      <Membership className="org.apache.catalina.tribes.membership.cloud.CloudMembershipService" membershipProviderClassName="org.apache.catalina.tribes.membership.cloud.KubernetesMembershipProvider"/>
      </Channel>
      </Cluster>
      
    • DNS プロバイダ: DNSMembershipProvider を使用して、ピア検出に DNS API を使用します。DNS プロバイダの構成例を次に示します。

      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
      <Channel className="org.apache.catalina.tribes.group.GroupChannel">
      <Membership className="org.apache.catalina.tribes.membership.cloud.CloudMembershipService" membershipProviderClassName="org.apache.catalina.tribes.membership.cloud.DNSMembershipProvider"/>
      </Channel>
      </Cluster>
      
    • jvmRoute: ロードバランサが jvmRoute の値に依存している場合は、値を static から POD 名の使用に変更する必要があります。これにより、セッション Cookie に POD 名の接尾辞を追加するように Tomcat が構成されます。これは、フロントエンド ロードバランサで使用され、トラフィックを適切な Tomcat POD に転送できます。server.xml ファイルの値を次のように変更します。

      <Engine name="Catalina" defaultHost="localhost" jvmRoute="${HOSTNAME}">
      

Tomcat プロキシ構成を確認する

Tomcat がリバース プロキシの背後で実行されるように構成されている場合、または server.xmlConnector セクションでいくつかのプロキシ構成設定を使用している場合は、Kubernetes で実行するように移行した後も同じプロキシ構成が適用されていることを確認する必要があります。

実用的にコンテナ化された Tomcat アプリケーションを実行するには、リバース プロキシ構成に対して次のいずれかの構成変更を選択します。

  • プロキシ構成を無効にする: 移行されたアプリケーションがリバース プロキシの外部で実行されなくなった場合は、コネクタ構成から proxyNameproxyPort を削除することで、プロキシ構成を無効にできます。
  • プロキシを移行する: プロキシ VM を移行し、既存の Tomcat 構成をすべて保持します。
  • リバース プロキシを置き換えるように Ingress を構成する: リバース プロキシにカスタム ロジックまたは高度なロジックが実装されていない場合は、移行した Tomcat アプリケーションを公開するように Ingress リソースを構成できます。このプロセスでは移行前と同じ FQDN を使用します。Ingress を構成するには、Tomcat Kubernetes Service が type: Nodeport であることを確認する必要があります。Ingress の構成例を次に示します。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-tomcat-ingress
    spec:
      rules:
      - host: APP_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-tomcat-service
                port:
                  name: my-tomcat-port
    
  • Cloud Load Balancing を使用して Cloud Service Mesh を構成する: GKE Enterprise を使用している場合は、Cloud Service Mesh を使用してアプリケーションを公開することもできます。サービス メッシュ アプリケーションの公開の詳細については、エッジからメッシュへ: GKE Ingress を介したサービス メッシュ アプリケーションの公開をご覧ください。

Java プロキシ構成を確認する

コンテナに移行する場合は、新しい環境でプロキシ サーバーの可用性を確認する必要があります。プロキシ サーバーが使用できない場合は、次のいずれかのプロキシの構成変更を選択します。

  • プロキシを無効にする: 元のプロキシが使用されなくなった場合は、プロキシ構成を無効にします。すべてのプロキシ設定を setenv.sh スクリプト、または Tomcat サーバーで維持されている構成ファイルから削除します。
  • プロキシ設定を変更する: Kubernetes 環境で別の下り(外向き)プロキシを使用している場合は、setenv.sh などのファイルでプロキシ設定を変更して、新しいプロキシを指定できます。

次のステップ