Personalizar o plano de migração dos servidores Tomcat

Confira o arquivo do plano de migração que foi gerado ao criar a migração. Personalize-o antes de realizar a migração. Os detalhes do plano de migração são usados para extrair da origem os artefatos de contêiner da carga de trabalho.

Nesta seção, você vai conferir uma descrição do conteúdo da migração e dos tipos de personalizações disponíveis para executá-la e gerar artefatos de implantação.

Antes de começar

Para seguir este tópico, é necessário criar uma migração e ter o arquivo do plano de migração.

Editar o plano de migração

Depois de copiar o sistema de arquivos e analisá-lo, encontre o plano de migração no novo diretório criado no caminho de saída especificado: ANALYSIS_OUTPUT_PATH/config.yaml.

Edite o plano de migração conforme necessário e salve as alterações.

Confira os detalhes e os comentários de orientação do plano de migração para acrescentar informações que você acredita serem necessárias. Mais especificamente, considere editar as seguintes seções:

Especificar a imagem Docker

No plano de migração, uma tag de imagem Docker da comunidade é gerada com base na versão do Tomcat, na versão do Java e no fornecedor do Java.

  • Versão do Tomcat: a versão do Tomcat é detectada e convertida para uma versão principal (as secundárias não são aceitas). Se não for possível detectar uma versão do Tomcat, baseImage.name vai conter uma string vazia.
  • Versão do Java: depende do parâmetro java-version. Ela é definida como 11 por padrão.
  • Fornecedor do Java: é definido como uma constante temurin.

Por exemplo, a tag de imagem Docker da comunidade gerada para o Tomcat 9.0, o Java 11 e o fornecedor do Java temurin é tomcat:9.0-jre11-temurin.

No plano de migração, o campo baseImage.name representa a tag de imagem Docker usada como base para a imagem de contêiner.

As versões originais do Tomcat e do Java detectadas na VM de origem estão contidas em discovery-report.yaml, que é gerado pela descoberta inicial.

Para alterar a imagem Docker da comunidade ou fornecer sua própria, modifique o baseImage.name no plano de migração usando o seguinte formato:

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

Substitua BASE_IMAGE_NAME pela imagem Docker que você quer usar como base para a imagem de contêiner.

Atualizar o caminho de instalação do Tomcat

Durante o processo de migração, se a imagem de destino tiver um caminho CATALINA_HOME não padrão, será possível especificar um caminho CATALINA_HOME personalizado. Edite o campo de destino catalinaHome diretamente no plano de migração:

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

Substitua PATH pelo caminho de instalação do Tomcat.

Personalizar usuários e grupos

Durante o processo de migração, se a imagem de destino for executada com um usuário e um grupo diferentes de root:root, será possível especificar um usuário e um grupo personalizados para a execução do aplicativo. Edite o usuário e o grupo diretamente no plano de migração:

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

Substitua:

  • USERNAME: o nome de usuário que você quer usar.
  • GROUP_NAME: o nome de grupo que você quer usar.

Configurar SSL

Quando você cria uma migração do Tomcat, um processo de descoberta compara o servidor com os diferentes aplicativos descobertos.

Após a descoberta, os seguintes campos são preenchidos automaticamente no plano de migração:

  • excludeFiles: listar os arquivos e diretórios que serão excluídos da migração.

    Por padrão, todos os caminhos e certificados sensíveis localizados durante a descoberta são adicionados automaticamente a esse campo e excluídos da migração. Se você remover um caminho dessa lista, o arquivo ou diretório será enviado para a imagem de contêiner. Para excluir um arquivo ou diretório da imagem de contêiner, adicione o caminho a essa lista.

  • sensitiveDataPaths: listar todos os caminhos e certificados sensíveis localizados pelo processo de descoberta.

    Para enviar os certificados ao repositório, defina o campo includeSensitiveData como 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
    

    Após a conclusão da migração, os secrets serão adicionados ao arquivo de segredos secrets.yaml no repositório de artefatos.

Geração de registros de web apps

O Migrate to Containers permite a geração de registros com log4j v2, logback e log4j v1.x, que residem em CATALINA_HOME.

O Migrate to Containers cria um arquivo extra com configurações de registro modificadas e converte todos os anexos de tipo de arquivo em anexos do console. É possível usar o conteúdo desse arquivo como referência para ativar a coleta de registros e fazer streaming para uma solução do tipo (como o Google Cloud Logging).

Alocação de memória

Durante o processo de migração, é possível especificar os limites de memória dos aplicativos migrados para contêineres individuais. Edite os limites de memória diretamente no plano de migração usando o seguinte formato:

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

O valor recomendado para limit é 200% de Xmx, que é o tamanho máximo de heap do Java. O valor recomendado para requests é 150% de Xmx.

Para conferir o valor de Xmx, execute este comando:

ps aux | grep catalina

Se os limites de memória tiverem sido definidos no plano de migração, o Dockerfile gerado com outros artefatos após a migração vai refletir sua declaração:

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

Isso define o tamanho inicial e máximo como 50% do valor limite. Além disso, é permitido que o tamanho da alocação de heap do Java para Tomcat seja alterado de acordo com qualquer alteração no limite de memória do pod.

Configurar as variáveis de ambiente do Tomcat

Para definir CATALINA_OPTS no Dockerfile gerado com outros artefatos após a migração, primeiro faça a adição ao campo catalinaOpts no plano de migração. Neste exemplo, confira um campo catalinaOpts atualizado:

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

O Migrate to Containers analisa os dados de catalinaOpts no Dockerfile. Este exemplo mostra a saída da análise:

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"

Também é possível definir variáveis de ambiente do Tomcat usando o script setenv.sh, que está na pasta /bin do servidor do Tomcat. Para mais informações sobre as variáveis de ambiente do Tomcat, consulte a documentação do Tomcat.

Se você optar por usar setenv.sh para definir variáveis de ambiente do Tomcat, edite o Dockerfile.

Configurar as sondagens de integridade do Tomcat

É possível monitorar a inatividade e o status de prontidão dos contêineres gerenciados especificando as sondagens no plano de migração do servidor da Web do Tomcat. O monitoramento da sondagem de integridade pode ajudar a reduzir a inatividade dos contêineres migrados e oferecer um monitoramento melhor.

Os estados de integridade desconhecidos podem gerar degradação de disponibilidade, monitoramento de disponibilidade com falsos positivos e possível perda de dados. Sem uma sondagem de integridade, o kubelet só pode pressupor a integridade de um contêiner e enviar o tráfego para uma instância de contêiner que não está pronta. Isso pode causar perda de tráfego. O kubelet também pode não detectar contêineres que estejam no estado travado e não os reinicia.

Para realizar uma sondagem de integridade, é preciso executar uma pequena instrução de script quando o contêiner é iniciado. O script verifica em cada período se há condições de sucesso, ou seja, aquelas definidas pelo tipo de sondagem usada. O período é definido no plano de migração por um campo periodSeconds. É possível executar ou definir esses scripts manualmente.

Para saber mais sobre as sondagens do kubelet, consulte Configurar sondagens de atividade, prontidão e inicialização na documentação do Kubernetes.

Há dois tipos de sondagens disponíveis para configuração. Ambas são probe-v1-core definidas na referência de probe-v1-core e compartilham a mesma função que os campos correspondentes de container-v1-core.

  • Sondagem de atividade: é usada para saber quando reiniciar um contêiner.

  • Sondagem de prontidão: é usada para saber quando um contêiner está pronto para começar a aceitar tráfego. Especifique uma sondagem de prontidão para começar a enviar tráfego a um pod somente quando a sondagem for bem-sucedida. Uma sondagem de prontidão pode atuar de maneira semelhante a uma de atividade, mas uma sondagem de prontidão nas especificações indica que um pod começa sem receber tráfego e só o recebe depois que a sondagem é concluída.

Após a descoberta, a configuração da sondagem é adicionada ao plano de migração. As sondagens podem ser usadas com a configuração padrão, conforme mostrado no exemplo a seguir. Para desativar as sondagens, remova a seção probes do arquivo YAML.

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

É possível alterar o plano de migração para usar um endpoint HTTP atual do 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

Há quatro maneiras predefinidas de verificar um contêiner usando uma sondagem. Cada sondagem precisa definir exatamente um destes quatro mecanismos:

  • exec: executa um comando especificado no contêiner. A execução é considerada bem-sucedida quando o código de status de saída é 0.
  • grpc: executa uma chamada de procedimento remoto com gRPC. As sondagens gRPC são um recurso Alfa.
  • httpGet: faz uma solicitação GET HTTP para o endereço IP do pod em uma porta e em um caminho especificados. A solicitação é considerada bem-sucedida quando o código de status é maior ou igual a 200 e menor que 400.
  • tcpSocket: executa uma verificação TCP no endereço IP do pod em uma porta especificada. O diagnóstico é considerado bem-sucedido quando a porta está aberta.

Por padrão, um plano de migração ativa o método de sondagem tcpSocket. Use a configuração manual do plano de migração para utilizar um método de sondagem diferente. Também é possível definir comandos e scripts personalizados no plano de migração.

Para adicionar dependências externas à sondagem de prontidão e usar a sondagem de atividade padrão, defina uma sondagem de prontidão executiva e um script que implemente essa lógica.

Verificar a configuração de clustering do Tomcat

O clustering do Tomcat é usado para replicar informações de sessão em todos os nós do Tomcat, o que permite chamar qualquer um dos servidores de aplicativos de back-end sem perder as informações da sessão do cliente. Para saber mais sobre a configuração do clustering, consulte Instruções de replicação de clustering/sessão na documentação do Tomcat.

A classe de clustering do Tomcat é chamada de SimpleTcpListener e usa mensagens de pulsação multicast para a descoberta de apps semelhantes. Os ambientes do Cloud não aceitam multicast. Por isso, é preciso alterar ou remover a configuração de clustering, quando possível.

Quando um balanceador de carga é configurado para executar e manter uma sessão fixa no servidor de back-end do Tomcat, ele pode usar a propriedade jvmRoute definida na configuração Engine do server.xml.

Se o ambiente de origem estiver usando uma configuração de clustering não permitida, modifique o arquivo server.xml para desativar essa configuração ou usar uma configuração aceita.

  • Tomcat v8.5 ou mais recente: o clustering precisa estar desativado no Tomcat 8.5. Para desativar o clustering, você precisa comentar a seção <Cluster … /> em server.xml.
  • Tomcat v9 ou mais recente: é possível ativar a classe Cluster usando KubernetesMembershipService. KubernetesMembershipService é uma classe específica do Kubernetes, que usa as APIs do Kubernetes para a descoberta de apps semelhantes.

    • Provedor do Kubernetes: confira abaixo um exemplo de configuração de um provedor do 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>
      
    • Provedor de DNS: use DNSMembershipProvider para utilizar as APIs de DNS na descoberta de apps semelhantes. Confira este exemplo de configuração para um provedor 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: quando o balanceador de carga depende de um valor jvmRoute, o valor precisa ser alterado de estático para fazer uso do nome do pod. Isso configura o Tomcat para adicionar um sufixo ao cookie de sessão com o nome do pod. Esse valor pode ser usado pelo balanceador de carga de front-end para direcionar o tráfego para o pod correto do Tomcat. Mude o valor no arquivo server.xml para usar o seguinte:

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

Verificar a configuração de proxy do Tomcat

Se o Tomcat estiver configurado para ser executado com a proteção de um proxy reverso ou com várias configurações de proxy na seção Connector de server.xml, você vai precisar verificar se as mesmas configurações de proxy ainda são aplicáveis depois da migração para execução no Kubernetes.

Para executar um aplicativo conteinerizado e funcional do Tomcat, escolha uma das mudanças de configuração abaixo na configuração do proxy reverso:

  • Desativar configuração do proxy: se o aplicativo migrado não for mais executado com a proteção de um proxy reverso, desative a configuração do proxy removendo proxyName e proxyPort da configuração do conector.
  • Migrar o proxy: migre a VM do proxy e retenha todas as configurações atuais do Tomcat.
  • Configurar o Ingress para substituir o proxy reverso: se nenhuma lógica personalizada ou sofisticada tiver sido implementada para o proxy reverso, será possível configurar um recurso de Ingress para expor o aplicativo migrado do Tomcat. Esse processo usa o mesmo FQDN anterior à migração. Para configurar um Ingress, verifique se o serviço do Kubernetes do Tomcat é do type: Nodeport. Confira um exemplo de configuração de 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 um Cloud Service Mesh com o Cloud Load Balancing: ao usar o GKE Enterprise, é possível optar por expor o aplicativo usando o Cloud Service Mesh. Para saber como expor aplicativos da malha de serviço, consulte Da borda à malha: como expor aplicativos da malha de serviço usando o Ingress do GKE.

Verificar a configuração de proxy do Java

Ao fazer a migração para contêineres, é preciso verificar a disponibilidade dos servidores proxy no novo ambiente. Se o servidor proxy não estiver disponível, escolha uma destas mudanças de configuração:

  • Desativar proxy: se o proxy original não estiver mais em uso, desative a configuração dele. Remova todas as configurações de proxy do script setenv.sh ou do arquivo de configuração em que elas são mantidas no servidor Tomcat.
  • Alterar as configurações do proxy: se o ambiente do Kubernetes usar um proxy de saída diferente, altere as configurações de proxy em setenv.sh ou em outro arquivo para apontar para o novo proxy.

A seguir