自定义 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 映像标记。

在来源虚拟机上检测到的原始 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
    

    迁移完成后,Secret 会添加到工件代码库中 Secret 文件 secrets.yaml 中。

Webapps 日志记录

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 会将 catalinaOpts 数据解析为 Dockerfile。以下示例展示了解析的输出:

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"

您还可以使用 setenv.sh 脚本设置 Tomcat 环境变量,该脚本位于 Tomcat 服务器上的 /bin 文件夹中。如需详细了解 Tomcat 环境变量,请参阅 Tomcat 文档

如果您选择使用 setenv.sh 来设置 Tomcat 环境变量,则需要修改 Dockerfile。

设置 Tomcat 健康状况探测

您可以通过在 Tomcat Web 服务器的迁移计划中指定探测来监控代管式容器的停机时间和就绪状态。健康探测监控有助于减少迁移后的容器的停机时间,并更好地进行监控。

未知的健康状况可能导致可用性降级、误报的可用性监控以及潜在的数据丢失。如果没有健康状况探测,kubelet 只能假设容器的健康状况并可能将流量发送到尚未就绪的容器实例。这可能会导致流量丢失。kubelet 可能也无法检测到处于冻结状态的容器,并且不会重启这些容器。

健康探测通过在容器启动时运行小型脚本语句来执行。该脚本会在每个周期检查成功条件(由使用的探测类型定义)。周期由迁移计划中的 periodSeconds 字段定义。您可以手动运行或定义这些脚本。

如需详细了解 kubelet 探测,请参阅 Kubernetes 文档中的配置活跃性、就绪性和启动探测

有两种类型的探测可供配置,两种探测都是在 probe-v1-core 参考文档中定义的 probe-v1-core,并且与 container-v1-core 的对应字段共享相同的功能。

  • 活跃性探测:活跃性探测用于了解何时重启容器。

  • 就绪性探测:就绪性探测用于了解容器何时准备好开始接受流量。如需仅在探测成功时开始将流量发送到 Pod,请指定就绪性探测。就绪性探测的作用可能类似于活跃性探测,但规范中的就绪性探测表示 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

使用探测检查容器有四种预定义的方法。每个探测必须定义以下四种机制之一:

  • exec:在容器内执行指定的命令。如果退出状态代码为 0,则执行会被视为成功。
  • grpc:使用“gRPC”执行远程过程调用。“gRPC”探测是一项 Alpha 版功能。
  • httpGet:在指定端口和路径上对 Pod 的 IP 地址执行 HTTP GET 请求。如果状态代码大于或等于 200 且小于 400,则请求会被视为成功。
  • tcpSocket:在指定端口上对 Pod 的 IP 地址执行 TCP 检查。如果该端口打开,则诊断会被视为成功。

默认情况下,迁移计划启用 tcpSocket 探测方法。通过手动迁移计划配置来使用其他探测方法。 您还可以通过迁移计划来定义自定义命令和脚本。

如需为就绪性探测添加外部依赖项,同时使用默认活跃性探测,请定义 exec 就绪性探测以及实现逻辑的脚本。

验证 Tomcat 集群配置

Tomcat 集群用于跨所有 Tomcat 节点复制会话信息,这可让您调用任何后端应用服务器并且不会丢失客户端会话信息。如需详细了解集群配置,请参阅 Tomcat 文档中的集群/会话复制方法指南

Tomcats 集群类称为 SimpleTcpListener,它使用多播检测信号消息进行对等发现。云环境不支持多播,因此您必须在可能的情况下更改集群配置或移除集群配置。

当负载均衡器配置为运行和维护与后端 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 值时,该值应从静态值更改为使用 POD 名称。这会将 Tomcat 配置为使用 POD 名称向会话 Cookie 添加后缀。前端负载均衡器可以使用它将流量定向到正确的 Tomcat POD。更改 server.xml 文件中的值以使用以下值:

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

验证 Tomcat 代理配置

如果 Tomcat 配置为在反向代理后面运行,或者使用 server.xmlConnector 部分中的多个代理配置设置,则您必须验证相同的代理配置在迁移后是否仍适用于在 Kubernetes 中运行。

如需运行正常的容器化 Tomcat 应用,请选择反向代理配置的以下配置更改之一:

  • 停用代理配置:如果迁移后的应用不再在反向代理后面运行,您可以通过从连接器配置中移除 proxyNameproxyPort 来停用代理配置。
  • 迁移代理:迁移代理虚拟机并保留所有现有 Tomcat 配置。
  • 配置 Ingress 以替换反向代理:如果未为反向代理实现任何自定义或复杂的逻辑,则可以配置 Ingress 资源来公开迁移后的 Tomcat 应用。此过程使用迁移前使用的 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 配置 Anthos Service Mesh:如果您使用的是 GKE Enterprise,则可以选择使用 Anthos Service Mesh 来公开应用。如需详细了解如何公开服务网格应用,请参阅从边缘到网格:通过 GKE Ingress 公开服务网格应用

验证 Java 代理配置

迁移到容器时,您必须验证代理服务器在新环境中的可用性。如果代理服务器不可用,请选择对代理进行以下某一项配置更改:

  • 停用代理:如果原始代理不再使用,则停用代理配置。从 setenv.sh 脚本或者 Tomcat 服务器上维护所有代理设置的配置文件中移除这些设置。
  • 更改代理设置:如果您的 Kubernetes 环境使用其他出站流量代理,则您可以在 setenv.sh 或其他文件中更改代理设置,以指向新代理。

后续步骤