Personalizar el plan de migración de servidores Tomcat

Debes revisar el archivo del plan de migración que se ha generado al crear una 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 del contenedor de la carga de trabajo del origen.

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 empezar

En este tema se da por hecho que ya has creado una migración y tienes el archivo del plan de migración.

Editar el plan de migración

Una vez que haya copiado el sistema de archivos y lo haya analizado, podrá encontrar el plan de migración en el nuevo directorio 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.

Consulta los detalles del plan de migración y los comentarios para añadir información según sea necesario. En concreto, te recomendamos que hagas cambios en las siguientes secciones.

Especificar 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: se detecta la versión de Tomcat 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. Esta opción está activada (11) de forma predeterminada.
  • Proveedor de Java: el proveedor de Java se define como 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 la imagen de Docker que se usa como base de la imagen de contenedor.

Las versiones originales de Tomcat y Java detectadas en la VM de origen se incluyen en el archivo discovery-report.yaml que genera la detección inicial.

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

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

Sustituye BASE_IMAGE_NAME por la imagen de Docker que quieras usar como base de la imagen de contenedor.

Actualizar la ruta de instalación de Tomcat

Durante el proceso de migración, si la imagen de destino tiene una ruta CATALINA_HOME no predeterminada, puedes especificar una ruta 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

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

Personalizar usuarios y grupos

Durante el proceso de migración, si la imagen de destino se ejecuta con un usuario y un grupo diferentes a root:root, puedes especificar un usuario y un grupo personalizados con los que quieras 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

Haz los cambios siguientes:

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

Configurar SSL

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

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

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

    De forma predeterminada, todas las rutas y los certificados sensibles que se encuentren durante la detección se añadirán automáticamente a este campo y se excluirán de la migración. Si quitas una ruta de esta lista, el archivo o el directorio se subirá a la imagen del contenedor. Para excluir un archivo o un directorio de la imagen del contenedor, añade la ruta a esta lista.

  • sensitiveDataPaths: muestra todas las rutas y los certificados sensibles que se han encontrado durante el proceso de descubrimiento.

    Para subir los certificados al repositorio, asigna el valor true al campo includeSensitiveData:

    # 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 completada la migración, los secretos se añaden al archivo de secretos secrets.yaml en el repositorio de artefactos.

Registro de aplicaciones web

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

Migrate to Containers crea un archivo adicional con configuraciones de registro modificadas y convierte todos los appenders de tipo de archivo en appenders de consola. Puedes usar el contenido de este archivo como referencia para habilitar la recogida de registros y enviarlos a una solución de recogida de registros (como Google Cloud Logging).

Asignación de memoria

Durante el proceso de migración, puede 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 el 200% de Xmx, que es el tamaño máximo del montículo de Java. El valor recomendado para requests es el 150% de Xmx.

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

ps aux | grep catalina

Si se han definido límites de memoria en tu plan de migración, el Dockerfile que se ha generado junto con otros artefactos después de una migración correcta reflejará 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>"

De esta forma, el tamaño inicial y máximo será el 50% del valor límite. De esta forma, el tamaño de asignación del montículo Java de Tomcat puede cambiar en función de los cambios en el límite de memoria del pod.

Definir variables de entorno de Tomcat

Si quieres definir CATALINA_OPTS en el Dockerfile que se ha generado junto con otros artefactos después de una migración correcta, primero puedes añadirlo al campo catalinaOpts de tu 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 tus datos de catalinaOpts y los añade a tu 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 puede definir variables de entorno de Tomcat mediante la secuencia de comandos setenv.sh, que se encuentra en la carpeta /bin de su servidor Tomcat. Para obtener más información sobre las variables de entorno de Tomcat, consulta la documentación de Tomcat.

Si decides usar setenv.sh para definir las variables de entorno de Tomcat, tendrás que editar el archivo Dockerfile.

Definir comprobaciones de estado de Tomcat

Puede monitorizar el tiempo de inactividad y el estado de sus contenedores gestionados especificando sondas en su plan de migración del servidor web Tomcat. La monitorización de las sondas de estado puede ayudar a reducir el tiempo de inactividad de los contenedores migrados y proporcionar una mejor monitorización.

Los estados de salud desconocidos pueden provocar una degradación de la disponibilidad, una monitorización de la disponibilidad con falsos positivos y una posible pérdida de datos. Sin una sonda de estado, kubelet solo puede asumir el estado de un contenedor y podría enviar tráfico a una instancia de contenedor que no esté lista. Esto puede provocar una pérdida de tráfico. Es posible que Kubelet tampoco detecte los contenedores que estén en estado inactivo y no los reinicie.

Una sonda de estado funciona ejecutando una pequeña instrucción de script cuando se inicia el contenedor. La secuencia de comandos comprueba si se cumplen las condiciones, que se definen por el tipo de sonda utilizada, cada periodo. El periodo se define en el plan de migración mediante el campo periodSeconds. Puedes ejecutar o definir estas secuencias de comandos manualmente.

Para obtener más información sobre las comprobaciones de kubelet, consulta Configurar comprobaciones de vivacidad, preparación e inicio en la documentación de Kubernetes.

Hay dos tipos de sondas que se pueden configurar. Ambas se definen como probe-v1-core en la referencia de probe-v1-core y comparten la misma función que los campos correspondientes de container-v1-core.

  • Comprobación de actividad: las comprobaciones de actividad se usan para saber cuándo reiniciar un contenedor.

  • Sondeo de disponibilidad: los sondeos de disponibilidad se usan para saber cuándo un contenedor está listo para empezar a aceptar tráfico. Para empezar a enviar tráfico a un Pod solo cuando una sonda se complete correctamente, especifica una sonda de preparación. Una sonda de preparación puede actuar de forma similar a una sonda de vivacidad, pero una sonda de preparación en las especificaciones indica que un pod se inicia sin recibir tráfico y solo empieza a recibir tráfico después de que la sonda se complete correctamente.

Una vez descubierto, la configuración de la sonda se añade al plan de migración. Las sondas se pueden usar en su configuración predeterminada, como se muestra en el siguiente ejemplo. Para desactivar las sondas, elimina 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 endpoint HTTP de Tomcat.

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 comprobar un contenedor mediante una sonda. Cada sonda debe definir exactamente uno de estos cuatro mecanismos:

  • exec: ejecuta un comando especificado dentro del contenedor. La ejecución se considera correcta si el código de estado de salida es 0.
  • grpc: realiza una llamada a procedimiento remoto mediante `gRPC`. Las comprobaciones `gRPC` son una función alfa.
  • httpGet: realiza una solicitud HTTP GET en la dirección IP del pod en un puerto y una ruta especificados. La solicitud se considera correcta si el código de estado es igual o superior a 200 e inferior a 400.
  • tcpSocket: realiza una comprobación 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 otros métodos de sondeo. También puedes definir comandos y secuencias de comandos personalizados a través del plan de migración.

Para añadir dependencias externas a la sonda de disponibilidad mientras usas la sonda de actividad predeterminada, define una sonda de disponibilidad exec y una secuencia de comandos que implemente la lógica.

Verificar la configuración de clústeres de Tomcat

La agrupación 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 sin perder la información de la sesión del cliente. Para obtener más información sobre la configuración de clústeres, consulta el artículo Clustering/Session Replication How-To (Cómo configurar clústeres o replicación de sesiones) en la documentación de Tomcat.

La clase de clúster de Tomcat se llama SimpleTcpListener, que usa mensajes de latido de multicast para detectar los peers. Los entornos de nube no admiten multidifusión, por lo que debes cambiar la configuración de clústeres o eliminarla, si es posible.

Cuando un balanceador de carga se configura para ejecutar y mantener una sesión persistente en el servidor Tomcat backend, puede usar la propiedad jvmRoute configurada en el archivo server.xml Engine.

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

  • Tomcat v8.5 o versiones posteriores: el clúster debe estar inhabilitado en la versión 8.5 de Tomcat. Para inhabilitar la agrupación, debes comentar la sección <Cluster … /> en server.xml.
  • Tomcat 9 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 peers.

    • Proveedor de Kubernetes: a continuación se muestra una configuración de ejemplo 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 el DNSMembershipProvider para usar las APIs de DNS para el descubrimiento de peers. A continuación, se muestra un ejemplo de configuración de 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: si tu balanceador de carga se basa en un valor de jvmRoute, el valor debe cambiar de estático a usar el nombre del POD. De esta forma, se configura Tomcat para que añada un sufijo a la cookie de sesión con el nombre del POD. El balanceador de carga del frontend puede usarlo para dirigir el tráfico al POD de Tomcat correcto. Cambie el valor del archivo server.xml para usar lo siguiente:

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

Verificar la configuración del proxy de Tomcat

Si Tomcat está configurado para ejecutarse detrás de un proxy inverso o con varios ajustes de configuración de proxy en la sección Connector de server.xml, debe verificar que las mismas configuraciones de proxy sigan siendo aplicables una vez que se haya migrado para ejecutarse en Kubernetes.

Para ejecutar una aplicación Tomcat funcional en un contenedor, elige uno de los siguientes cambios de configuración del proxy inverso:

  • Inhabilitar 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 quitando proxyName y proxyPort de la configuración del conector.
  • Migra el proxy: migra la VM del proxy y conserva todas las configuraciones de Tomcat.
  • Configura Ingress para sustituir el proxy inverso: si no se ha implementado ninguna lógica personalizada o sofisticada para tu proxy inverso, puedes configurar un recurso Ingress para exponer tu aplicación Tomcat migrada. Este proceso usa el mismo FQDN que se usó antes de la migración. Para configurar un Ingress, debes verificar que tu servicio de Tomcat Kubernetes sea de type: Nodeport. A continuación, se muestra un ejemplo de configuración 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
    
  • Configurar Cloud Service Mesh con Cloud Load Balancing: si usas GKE Enterprise, puedes exponer tu aplicación con Cloud Service Mesh. Para obtener más información sobre cómo exponer aplicaciones de malla de servicios, consulta el artículo Del perímetro a la malla: exponer aplicaciones en una malla de servicios a través de Ingress de GKE.

Verificar la configuración del proxy de Java

Al migrar a contenedores, debes verificar la disponibilidad de tus servidores proxy en tu nuevo entorno. Si el servidor proxy no está disponible, elige uno de los siguientes cambios de configuración del proxy:

  • Inhabilitar el proxy: si el proxy original ya no se usa, inhabilita la configuración del proxy. Elimina todos los ajustes de proxy del script setenv.sh o del archivo de configuración en el que se mantienen en tu servidor Tomcat.
  • Cambiar la configuración del proxy: si tu entorno de Kubernetes usa un proxy de salida diferente, puedes cambiar la configuración del proxy en setenv.sh u otro archivo para que apunte al nuevo proxy.

Siguientes pasos