Personaliza el plan de migración para servidores de Tomcat

Debes revisar el archivo del plan de migración que se generó cuando se creó la migración. Personaliza el archivo antes de ejecutar la migración. Los detalles de tu plan de migración se usan para extraer los artefactos de contenedor de la carga de trabajo de la fuente.

En esta sección, se describe el contenido de la migración y los tipos de personalizaciones que puedes tener en cuenta antes de ejecutar la migración y generar artefactos de implementación.

Antes de comenzar

En este tema, se supone que ya creaste una migración y que tienes el archivo del plan de migración.

Edita el plan de migración

Después de copiar el sistema de archivos y analizarlo, puedes encontrar el plan de migración en el directorio nuevo que se crea en la ruta de salida especificada: ANALYSIS_OUTPUT_PATH/config.yaml.

Edita el plan de migración según sea necesario y guarda los cambios.

Revisa los detalles de tu plan de migración y los comentarios guías para agregar información según sea necesario. En particular, considera las ediciones en las siguientes secciones.

Especifica la imagen de Docker

En el plan de migración, generamos una etiqueta de imagen de la comunidad de Docker basada en la versión de Tomcat, la versión de Java y el proveedor de Java.

  • Versión de Tomcat: la versión de Tomcat se detecta y se convierte en una versión principal (no se admiten versiones secundarias). Si no detectamos una versión de Tomcat, baseImage.name contiene una cadena vacía.
  • Versión de Java: la versión de Java depende del parámetro java-version. Se configura de forma predeterminada en 11.
  • Proveedor de Java: el proveedor de Java se establece en una constante: temurin.

Por ejemplo, la etiqueta de imagen de la comunidad de Docker generada para la versión 9.0 de Tomcat, la versión 11 de Java y el proveedor de Java temurin es tomcat:9.0-jre11-temurin.

En el plan de migración, el campo baseImage.name representa la etiqueta de imagen de Docker que se usa como base de la imagen del contenedor.

Las versiones originales de Tomcat y Java detectadas en la VM de origen se encuentran en discovery-report.yaml, que se genera a través del descubrimiento inicial.

Si deseas cambiar la imagen de la comunidad de Docker o proporcionar tu propia imagen de Docker, puedes modificar el baseImage.name en tu plan de migración con el siguiente formato:

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

Reemplaza BASE_IMAGE_NAME por la imagen de Docker que deseas usar como base de la imagen de contenedor.

Actualiza la ruta de instalación de Tomcat

Durante el proceso de migración, si tu imagen de destino tiene una ruta de acceso CATALINA_HOME no predeterminada, puedes especificar una ruta de acceso CATALINA_HOME personalizada. Edita el campo catalinaHome de destino directamente en tu plan de migración:

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

Reemplaza PATH por la ruta de instalación de Tomcat.

Personaliza el usuario y el grupo

Durante el proceso de migración, si la imagen de destino se ejecuta con un usuario y un grupo diferentes de root:root, puedes especificar un usuario y un grupo personalizados en los que deseas que se ejecute la aplicación. Edita el usuario y el grupo directamente en tu plan de migración:

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

Reemplaza lo siguiente:

  • USERNAME: El nombre de usuario que deseas usar
  • GROUP_NAME: el nombre del grupo que deseas usar

Configura SSL

Cuando creas una migración nueva de Tomcat, un proceso de descubrimiento analiza el servidor en busca de las diferentes aplicaciones que se detectan.

Después de la detección, los siguientes campos se propagan de forma automática en el plan de migración:

  • excludeFiles: enumera los archivos y directorios que se excluirán de la migración.

    Según la configuración predeterminada, todas las rutas de acceso y los certificados sensibles ubicados durante la detección se agregan automáticamente a este campo y se excluyen de la migración. Si quitas una ruta de acceso de esta lista, el archivo o directorio se subirá a la imagen del contenedor. Para excluir un archivo o un directorio de la imagen de contenedor, agrega la ruta de acceso a esta lista.

  • sensitiveDataPaths: Enumera todas las rutas de acceso sensibles y los certificados ubicados en el proceso de descubrimiento.

    Para subir los certificados al repositorio, establece el campo includeSensitiveData en 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
    

    Una vez que se completa la migración, los Secrets se agregan al archivo de Secrets secrets.yaml en el repositorio de artefactos.

Registro de apps web

Migrate to Containers admite el registro con log4j v2, logback y log4j v1.x que residen en CATALINA_HOME.

Migrate to Containers crea un archivo adicional con opciones de configuración de registro modificadas y convierte todos los adjuntadores de tipos de archivos en adjuntadores de consola. Puedes usar el contenido de este archivo como referencia para habilitar la recopilación de registros y transmitir a una solución de recopilación de registros (como Google Cloud Logging).

Asignación de memoria:

Durante el proceso de migración, puedes especificar los límites de memoria de las aplicaciones migradas a contenedores individuales. Edita los límites de memoria directamente en tu plan de migración con el siguiente formato:

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

El valor recomendado para limit es del 200% de Xmx, que es el tamaño máximo del montón de Java. El valor recomendado para requests es del 150% de Xmx.

Para ver el valor de Xmx, ejecuta el siguiente comando:

ps aux | grep catalina

Si se definieron límites de memoria en tu plan de migración, el Dockerfile que se generó junto con otros artefactos después de una migración exitosa refleja tu declaración:

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

Esto define el tamaño inicial y máximo como un 50% del valor límite. Esto permite que el tamaño de la asignación de montón de Tomcat para Java cambie según cualquier cambio con el límite de memoria del Pod.

Configura variables de entorno Tomcat

Si deseas configurar CATALINA_OPTS en tu Dockerfile que se genera junto con otros artefactos después de una migración exitosa, primero puedes agregar información al campo catalinaOpts en el plan de migración. En el siguiente ejemplo, se muestra un campo catalinaOpts actualizado:

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

Migrate to Containers analiza los datos de catalinaOpts en el Dockerfile. En el siguiente ejemplo, se muestra el resultado del análisis:

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"

También puedes configurar variables de entorno de Tomcat con la secuencia de comandos setenv.sh, que se encuentra en la carpeta /bin del servidor de Tomcat. Para obtener más información sobre las variables de entorno de Tomcat, consulta la documentación de Tomcat.

Si eliges usar setenv.sh para configurar las variables de entorno de Tomcat, debes editar el Dockerfile.

Configura sondeos de estado de Tomcat

Puedes supervisar el tiempo de inactividad y el estado de preparación de los contenedores administrados si especificas sondeos en el plan de migración del servidor web de Tomcat. La supervisión del sondeo de estado puede ayudar a reducir el tiempo de inactividad de los contenedores migrados y proporcionar una mejor supervisión.

Los estados desconocidos pueden causar una degradación de la disponibilidad, una supervisión de disponibilidad falso positivo y una posible pérdida de datos. Sin un sondeo de estado, kubelet solo puede suponer el estado de un contenedor y puede enviar tráfico a una instancia de contenedor que no esté lista. Esto puede provocar la pérdida de tráfico. Es posible que kubelet tampoco detecte los contenedores que están en estado inmovilizado y no los reinicia.

Un sondeo de estado ejecuta una declaración con una secuencia de comandos pequeña cuando se inicia el contenedor. La secuencia de comandos verifica las condiciones correctas, que se definen según el tipo de sondeo que se usa, en cada período. El período se define en el plan de migración mediante un campo periodSeconds. Puedes ejecutar o definir estas secuencias de comandos de forma manual.

Para obtener más información sobre los sondeos de kubelet, consulta Configura sondeos de funcionamiento, inicio y preparación en la documentación de Kubernetes.

Hay dos tipos de sondeos disponibles para configurar, ambos sondeos son probe-v1-core definido en la referencia de probe-v1-core, y comparten la misma función que los campos correspondientes de container-v1-core.

  • Sondeo de funcionamiento: los sondeos de funcionamiento se usan para saber cuándo reiniciar un contenedor.

  • Sondeo de preparación: los sondeos de preparación se usan para saber cuándo un contenedor está listo para comenzar a aceptar tráfico. Para comenzar a enviar tráfico a un Pod solo cuando un sondeo es correcto, especifica un sondeo de preparación. Un sondeo de preparación puede actuar de manera similar a un sondeo en funcionamiento, pero un sondeo de preparación en las especificaciones indica que un Pod se iniciará sin recibir tráfico y solo comenzará a recibir tráfico después de que el sondeo tenga éxito.

Después de la detección, la configuración del sondeo se agrega al plan de migración. Los sondeos se pueden usar en la configuración predeterminada, como se muestra en el siguiente ejemplo. Para desactivar los sondeos, quita la sección probes del archivo YAML.

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

Puedes cambiar este plan de migración para usar un extremo HTTP de Tomcat existente.

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

Hay cuatro formas predefinidas de verificar un contenedor mediante un sondeo. Cada sondeo debe definir exactamente uno de estos cuatro mecanismos:

  • exec: ejecuta un comando especificado dentro del contenedor. La ejecución se considera exitosa si el código de estado de salida es 0.
  • grpc: realiza una llamada de procedimiento remoto con “gRPC”. Los sondeos de "gRPC" son una función Alfa.
  • httpGet: realiza una solicitud GET HTTP a la dirección IP del Pod en un puerto y una ruta específicos. La solicitud se considera exitosa si el código de estado es mayor o igual que 200 y menor que 400.
  • tcpSocket: realiza una verificación de TCP en la dirección IP del Pod en un puerto especificado. El diagnóstico se considera correcto si el puerto está abierto.

De forma predeterminada, un plan de migración habilita el método de sondeo tcpSocket. Usa la configuración manual de tu plan de migración para usar diferentes métodos de sondeo. También puedes definir comandos y secuencias de comandos personalizados a través del plan de migración.

Si deseas agregar dependencias externas para el sondeo de preparación, mientras usas el sondeo en funcionamiento predeterminado, define un sondeo de preparación en ejecución y una secuencia de comandos que implemente la lógica.

Verifica la configuración del agrupamiento en clústeres de Tomcat

El agrupamiento en clústeres de Tomcat se usa para replicar la información de la sesión en todos los nodos de Tomcat, lo que te permite llamar a cualquiera de los servidores de aplicaciones de backend y no perder la información de las sesiones de clientes. Para obtener más información sobre la configuración de agrupamiento en clústeres, consulta el instructivo de replicación de clústeres o de sesión en la documentación de Tomcat.

La clase de agrupamiento en clústeres de Tomcat se llama SimpleTcpListener, que usa mensajes de señal de monitoreo de funcionamiento de multidifusión para el descubrimiento de pares. Los entornos de nube no admiten multicast, por lo que debes cambiar la configuración del agrupamiento en clústeres o quitarla cuando sea posible.

Cuando un balanceador de cargas está configurado para ejecutar y mantener una sesión fija en el servidor de Tomcat de backend, puede usar la propiedad jvmRoute configurada en la configuración Engine de server.xml.

Si tu entorno de origen usa una configuración de agrupamiento en clústeres no compatible, modifica el archivo server.xml para inhabilitar la configuración o usa una configuración compatible.

  • Tomcat v8.5 o versiones posteriores: el agrupamiento en clústeres debe estar inhabilitado en Tomcat versión 8.5. Para inhabilitar el agrupamiento en clústeres, debes marcar como comentario la sección <Cluster … /> en server.xml.
  • Tomcat v9 o versiones posteriores: en Tomcat 9 o versiones posteriores, puedes habilitar la clase Cluster con KubernetesMembershipService. KubernetesMembershipService es una clase específica de Kubernetes que usa las APIs de Kubernetes para el descubrimiento de pares.

    • Proveedor de Kubernetes: la siguiente es una configuración de muestra para un proveedor de 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>
      
    • Proveedor de DNS: usa DNSMembershipProvider para usar las APIs de DNS para el descubrimiento de pares. La siguiente es una configuración de muestra para un proveedor de 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:: cuando el balanceador de cargas depende de un valor jvmRoute, el valor debe cambiarse de estático a usar el nombre del POD. Esto configura Tomcat para agregar un sufijo a la cookie de sesión con el nombre de POD. El balanceador de cargas de frontend puede usarlo para dirigir el tráfico al POD de Tomcat correcto. Cambia el valor en el archivo server.xml para usar lo siguiente:

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

Verifica la configuración del proxy de Tomcat

Si Tomcat está configurado para ejecutarse detrás de un proxy inverso o con varias opciones de configuración de proxy en la sección Connector de server.xml, debes verificar que las mismas configuraciones de proxy sigan siendo aplicables luego de la migración para ejecutarse en Kubernetes.

Para ejecutar una aplicación Tomcat funcional alojada en contenedores, elige uno de los siguientes cambios de configuración en la configuración de proxy inverso:

  • Inhabilita la configuración del proxy: si la aplicación migrada ya no se ejecuta detrás de un proxy inverso, puedes inhabilitar la configuración del proxy si quitas proxyName y proxyPort de la configuración del conector.
  • Migra el proxy: migra la VM del proxy y conserva todas las configuraciones existentes de Tomcat.
  • Configura Ingress para reemplazar el proxy inverso: si no se implementó ninguna lógica personalizada o sofisticada para el proxy inverso, puedes configurar un recurso de Ingress para exponer la aplicación migrada de Tomcat. En este proceso, se usa el mismo FQDN que se usó antes de la migración. Para configurar un Ingress, debes verificar que el Service de Kubernetes de Tomcat sea de type: Nodeport. A continuación, se muestra una configuración de muestra de un 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
    
  • Configura Cloud Service Mesh con Cloud Load Balancing: si usas GKE Enterprise, puedes optar por exponer tu aplicación con Cloud Service Mesh. Para obtener más información sobre la exposición de aplicaciones de la malla de servicios, consulta Del perímetro a la malla: Exposición de aplicaciones de la malla de servicios a través de Ingress de GKE.

Verifica la configuración del proxy de Java

Cuando migres a contenedores, debes verificar la disponibilidad de tus servidores proxy en tu entorno nuevo. Cuando el servidor proxy no esté disponible, elige uno de los siguientes cambios de configuración en el proxy:

  • Inhabilita el proxy: si el proxy original ya no está en uso, inhabilita la configuración del proxy. Quita toda la configuración del proxy de la secuencia de comandos setenv.sh o del archivo de configuración en el que se mantienen en tu servidor de Tomcat.
  • Cambia la configuración del proxy: si el entorno de Kubernetes usa un proxy de salida diferente, puedes cambiar la configuración del proxy en setenv.sh, o en otro archivo, para que apunte al proxy nuevo.

¿Qué sigue?