Migrar aplicativos do WebLogic Server para o WildFly no Serviço Kubernetes do Azure

Este guia descreve o que você deve estar ciente quando deseja migrar um aplicativo WebLogic Server existente para ser executado no WildFly em um contêiner do Serviço Kubernetes do Azure.

Pré-migração

Para garantir uma migração bem-sucedida, antes de começar, conclua as etapas de avaliação e inventário descritas nas seções a seguir.

Se você não puder atender aos requisitos de pré-migração, consulte o guia de migração complementar:

Fazer o inventário da capacidade do servidor

Documente o hardware (memória, CPU, disco) do(s) servidor(es) de produção atual e as contagens médias e de pico de solicitações e a utilização de recursos. Independentemente do caminho de migração que escolher, vai precisar destas informações. É útil, por exemplo, para ajudar a orientar a seleção do tamanho das VMs em seu pool de nós, a quantidade de memória a ser usada pelo contêiner e quantas CPUs compartilham as necessidades do contêiner.

É possível redimensionar pools de nós no AKS. Para saber como, consulte Redimensionar pools de nós no Serviço Kubernetes do Azure (AKS).

Inventariar todos os segredos

Antes do advento das tecnologias de "configuração como serviço", como o Azure Key Vault, não havia um conceito bem definido de "segredos". Em vez disso, tínhamos um conjunto díspar de definições de configuração que, efetivamente, funcionavam como aquilo a que hoje chamamos "segredos". Com os servidores de aplicações, como o WebLogic Server, esses segredos estão em muitos ficheiros de configuração e arquivos de configuração diferentes. Procure segredos e palavras-passe nas propriedades e nos ficheiros de configuração do servidor ou servidores de produção. Não se esqueça de verificar weblogic.xml nos seus WARs. Também poderá encontrar ficheiros de configuração com palavras-passe ou credenciais dentro da aplicação. Para obter mais informações, veja Conceitos básicos do Azure Key Vault.

Inventariar todos os certificados

Documente todos os certificados utilizados para os pontos finais SSL públicos. Pode ver todos os certificados no servidor ou servidores de produção com o comando seguinte:

keytool -list -v -keystore <path to keystore>

Inventariar recursos do JNDI

Inventariar todos os recursos do JNDI. Por exemplo, as origens de dados como as bases de dados podem ter associado um nome do JNDI que permite que o JPA vincule corretamente instâncias de EntityManager a uma base de dados específica. Para obter mais informações sobre os recursos do JNDI e as bases de dados, veja WebLogic Server Data Sources (Origens de Dados do WebLogic Server) na documentação da Oracle. Outros recursos não relacionados com o JNDI, como os mediadores de mensagens do JMS, podem exigir migração ou reconfiguração. Para obter mais informações sobre a configuração JMS, consulte Oracle WebLogic Server 12.2.1.4.0.

Determinar se é utilizada a replicação de sessões

Se a sua aplicação depender da replicação de sessões, com ou sem o Oracle Coherence*Web, tem duas opções:

  • Refatorize a sua aplicação para utilizar uma base de dados para a gestão de sessões.
  • Refatorize a sua aplicação para externalizar a sessão para o Serviço de Redis do Azure. Para obter mais informações, veja Azure Cache for Redis (Cache do Azure para Redis).

Documentar origens de dados

Se a sua aplicação utilizar bases de dados, terá de recolher as seguintes informações:

  • Qual é o nome da origem de dados?
  • Qual é a configuração do conjunto de ligações?
  • Onde posso obter o ficheiro JAR do controlador JDBC?

Para obter mais informações sobre os controladores JDBC no WebLogic, veja Using JDBC Drivers with WebLogic Server (Utilizar Controladores JDBC com o WebLogic Server).

Determinar se o WebLogic foi personalizado

Determine quais das seguintes personalizações foram feitas e capture as que o foram.

  • Os scripts de arranque foram alterados? Esses scripts incluem setDomainEnv, commEnv, startWebLogic e stopWebLogic.
  • São transmitidos parâmetros específicos para a JVM?
  • Foram adicionados JARs ao classpath do servidor?

Determinar se é necessária uma ligação ao local

Se a sua aplicação precisar de aceder a um dos seus serviços no local, tem de aprovisionar um dos serviços de conectividade do Azure. Para obter mais informações, veja Ligar uma rede no local ao Azure. Em alternativa, tem de refatorizar a aplicação para utilizar as APIs publicamente disponíveis que os seus recursos no local expõem.

Determinar se os Tópicos ou Filas do Java Message Service (JMS) estão a ser utilizados

Se a sua aplicação utilizar Filas ou Tópicos do JMS, tem de os migrar para um servidor JMS alojado externamente. O Azure Service Bus e o Advanced Message Queuing Protocol (AMQP) podem ser uma excelente estratégia de migração para quem utiliza o JMS. Para obter mais informações, consulte Usar o Java Message Service 1.1 com o Azure Service Bus Standard e AMQP 1.0.

Se tiverem sido configurados arquivos persistentes do JMS, tem de capturar a respetiva configuração e aplicá-la após a migração.

Determinar se está a utilizar bibliotecas Shared Java EE criadas e personalizadas por si.

Se utilizar a funcionalidade de biblioteca Shared Java EE, tem duas opções:

  • Refatorizar o código da aplicação para remover todas as dependências nas bibliotecas e, ao invés, incorporar a funcionalidade diretamente na aplicação.
  • Adicionar as bibliotecas ao classpath do servidor.

Determinar se os conjuntos OSGi são utilizados

Se utilizar conjuntos OSGi adicionados ao servidor WebLogic, tem de adicionar os ficheiros JAR equivalentes diretamente à aplicação Web.

Determinar se a aplicação contem código de SO específico

Se seu aplicativo contiver qualquer código com dependências no sistema operacional host, você precisará refatorá-lo para remover essas dependências. Por exemplo, talvez seja necessário substituir qualquer uso de ou \ em caminhos do sistema de / arquivos por File.Separator ou Paths.get se seu aplicativo estiver sendo executado no Windows.

Determinar se o Oracle Service Bus está a ser utilizado

Se a sua aplicação utilizar o Oracle Service Bus (OSB), tem de capturar a forma como este é configurado. Para obter mais informações, veja About the Oracle Service Bus Installation (Sobre a Instalação do Oracle Service Bus).

Determinar se a sua aplicação é composta por vários WARs

Se a sua aplicação for composta por vários WARs, deve tratar cada um desses WARs como aplicações separadas e seguir este guia para cada qual individualmente.

Determinar se a sua aplicação está empacotada como EAR

Se a sua aplicação estiver empacotada como um ficheiro EAR, confirme que examina os ficheiros application.xml e weblogic-application.xml e capture as respetivas configurações.

Nota

Se você quiser ser capaz de dimensionar cada um de seus aplicativos Web independentemente para melhor uso de seus recursos do Serviço Kubernetes do Azure, você deve dividir o EAR em aplicativos Web separados.

Identificar todos os processos e daemons externos em execução nos servidores de produção

Se tiver processos em execução fora do servidor de aplicações, como daemons de monitorização, terá de eliminar ou migrá-los para outro local.

Verificar se a versão de Java suportada funciona corretamente

Usar o WildFly no Serviço Kubernetes do Azure requer uma versão específica do Java, portanto, você precisará confirmar se seu aplicativo é executado corretamente usando essa versão suportada.

Nota

Esta validação é particularmente importante se o seu servidor atual estiver a ser executado num JDK não suportado (como Oracle JDK ou IBM OpenJ9).

Para obter a sua versão atual do Java, inicie sessão no servidor de produção e execute o comando seguinte:

java -version

Veja os Requisitos para obter orientação quanto à versão que deve utilizar para executar o WildFly.

Determinar se a aplicação depende de trabalhos agendados

Trabalhos agendados, como tarefas do Agendador de Quartzo ou trabalhos cron do Unix, NÃO devem ser usados com o Serviço Kubernetes do Azure (AKS). O Azure Kubernetes Service não o impedirá de implementar uma aplicação que contenha tarefas agendadas no seu interior. Contudo, se a sua aplicação estiver ampliada, a mesma tarefa agendada pode ser executada mais de uma vez por período agendado. Esta situação pode provocar consequências não intencionais.

Para executar trabalhos agendados no seu cluster do AKS, defina o CronJobs do Kubernetes conforme for necessário. Para obter mais informações, veja Executar Tarefas Automatizadas com um CronJob.

Determinar se a WebLogic Scripting Tool é usada

Se você usa atualmente a WebLogic Scripting Tool (WLST) para executar a implantação, precisará avaliar o que ela está fazendo. Se o WLST estiver alterando quaisquer parâmetros (tempo de execução) do seu aplicativo como parte da implantação, verifique se esses parâmetros estão em conformidade com uma das seguintes opções:

  • Os parâmetros são externalizados como configurações do aplicativo.
  • Os parâmetros são incorporados em seu aplicativo.
  • Os parâmetros estão usando a CLI do JBoss durante a implantação.

Se o WLST estiver fazendo mais do que o mencionado acima, você terá algum trabalho extra a fazer durante a migração.

Determinar se a aplicação utiliza APIs específicas do WebLogic

Se a sua aplicação utilizar APIs específicas do WebLogic, terá de refatorizá-la para remover essas dependências. Por exemplo, se tiver utilizado uma classe mencionada na Referência da API de Java para o Oracle WebLogic Server, utilizou uma API específica do WebLogic na sua aplicação. Você precisaria refatorar para remover a referência.

Determinar se a aplicação utiliza Entity Beans ou EJB 2.x-style CMP Beans

Se a sua aplicação utilizar Entity Beans ou EJB 2.x-style CMP Beans

Determinar se a funcionalidade Java EE Application Client está a ser utilizada

Se tiver aplicações cliente que se ligam à sua aplicação (servidor) com a funcionalidade Java EE Application Client, terá de as refatorizar a ambas para que utilizem APIs HTTP.

Determinar se foi utilizado um plano de implementação

Se seu aplicativo foi implantado usando um plano de implantação, avalie o que o plano de implantação está fazendo. Se o plano de implementação for uma implementação direta, poderá implementar a sua aplicação Web sem alterações. Se o plano de implantação for mais elaborado, determine se você pode usar a CLI do JBoss para configurar corretamente seu aplicativo como parte da implantação. Se não for possível usar a CLI do JBoss, refatore seu aplicativo de tal forma que um plano de implantação não seja mais necessário.

Determinar se os temporizadores EJB estão a ser utilizados

Se a sua aplicação utilizar temporizadores EJB, tem de confirmar que o código do temporizador EJB pode ser acionado por cada instância do WildFly de forma independente. Esta validação é necessária porque, no cenário de implementação do Azure Kubernetes Service, cada temporizador EJB será acionado na sua própria instância do WildFly.

Determinar se e como é que o sistema de ficheiros é utilizado

Qualquer uso do sistema de arquivos no servidor de aplicativos requer reconfiguração ou, em casos raros, alterações na arquitetura. O sistema de arquivos pode ser usado por módulos compartilhados WebLogic ou pelo código do seu aplicativo. Você pode identificar alguns ou todos os cenários descritos nas seções a seguir.

Conteúdo estático só de leitura

Se a sua aplicação servir conteúdo estático atualmente, precisa de uma localização alternativa para o mesmo. Pode considerar mover o conteúdo estático para o Armazenamento de Blobs do Azure e adicionar a CDN do Azure para obter transferências super-rápidas a nível global. Para obter mais informações, consulte Hospedagem de site estático no Armazenamento do Azure e Guia de início rápido: integrar uma conta de armazenamento do Azure com a CDN do Azure.

Conteúdo estático publicado dinamicamente

Se a sua aplicação permitir conteúdo estático carregado/produzido pela mesma, mas que é imutável após a criação, pode utilizar o Armazenamento de Blobs do Azure e a CDN do Azure conforme descrito acima, com uma função das Funções do Azure que lide com os carregamentos e as atualizações da CDN. Disponibilizamos uma implementação de exemplo que pode utilizar, em Uploading and CDN-preloading static content with Azure Functions (Carregamento e pré-carregamento da CDN de conteúdo estático com as Funções do Azure).

Conteúdo dinâmico ou interno

Para os ficheiros que são frequentemente escritos e lidos pela sua aplicação (tais como ficheiros de dados temporários) ou os ficheiros estáticos que só estão visíveis para a sua aplicação, pode montar partilhas do Armazenamento do Microsoft Azure sob a forma de volumes persistentes. Para obter mais informações, consulte Criar e usar um volume com Arquivos do Azure no Serviço Kubernetes do Azure (AKS).

Determinar se há conectores JCA a ser utilizados

Se a aplicação utilizar conectores JCA, terá de validar se o conector JCA pode ser utilizado no WildFly. Se a implementação JCA estiver associada ao WebLogic, terá de refatorizar a aplicação para remover essa dependência. Se puder ser utilizado, terá de adicionar os JARs ao classpath do servidor e colocar os ficheiros de configuração necessários na localização correta nos diretórios do servidor do WildFly para que estejam disponíveis.

Determinar se a aplicação utiliza um Adaptador de Recursos

Se a sua aplicação precisar de um Adaptador de Recursos (RA), tem de ser compatível com o WildFly. Determine se o RA funciona bem numa instância autónoma do WildFly ao implementá-lo no servidor e configurá-lo corretamente. Se o RA funcionar devidamente, terá de adicionar os JARs ao classpath do servidor da imagem do Docker e pôr os ficheiros de configuração necessários na localização correta nos diretórios do servidor do WildFly para que estejam disponíveis.

Determinar se o JAAS está a ser utilizado

Se a sua aplicação utilizar o JAAS, tem de capturar a forma como este é configurado. Se estiver a utilizar uma base de dados, pode convertê-la num domínio JAAS no WildFly. Se for uma implementação personalizada, terá de confirmar se pode ser utilizada no WildFly.

Determinar se a colocação em clusters do WebLogic é utilizada

O mais provável é que tenha desenvolvido a sua aplicação em múltiplos servidores WebLogic para obter elevada disponibilidade. O Serviço Kubernetes do Azure é capaz de escalar, mas se você usou a API de Cluster WebLogic, precisará refatorar seu código para eliminar o uso dessa API.

Fazer testes no local

Antes de criar as imagens do contentor, migre a aplicação para as versões do JDK e do WildFly que pretende utilizar no AKS. Teste a aplicação de forma minuciosa para garantir a compatibilidade e o desempenho.

Migração

Aprovisionar o Azure Container Service e o Azure Kubernetes Service

Utilize os comandos seguintes para criar um registo de contentores e um cluster do Azure Kubernetes com um Principal de Serviço que tenha a função Leitor no registo. Certifique-se de que escolhe o modelo de rede adequado para os requisitos de rede do seu cluster.

az group create \
    --resource-group $resourceGroup \
    --location eastus
az acr create \
    --resource-group $resourceGroup \
    --name $acrName \
    --sku Standard
az aks create \
    --resource-group $resourceGroup \
    --name $aksName \
    --attach-acr $acrName \
    --network-plugin azure

Criar uma imagem do Docker para o WildFly

Para criar um Dockerfile, tem de seguir os seguintes pré-requisitos:

  • Um JDK suportado.
  • Uma instalação do WildFly.
  • As opções de runtime do JVM.
  • Uma forma de transmitir variáveis de ambiente (se aplicável).

Depois, pode seguir os passos descritos nas secções abaixo, sempre que aplicável. Pode utilizar o repositório WildFly Container Quickstart como ponto de partida para o Dockerfile e a aplicação Web.

  1. Configurar o FlexVolume do KeyVault
  2. Configurar origens de dados
  3. Configurar recursos do JNDI
  4. Rever a configuração do WildFly

Configurar o FlexVolume do KeyVault

Crie um cofre do Azure KeyVault e preencha todos os segredos necessários. Para obter mais informações, consulte Guia de início rápido: definir e recuperar um segredo do Cofre da Chave do Azure usando a CLI do Azure. Em seguida, configure um KeyVault FlexVolume para tornar esses segredos acessíveis a pods.

Também terá de atualizar o script de arranque utilizado para fazer o bootstrap do WildFly. Esse script tem de importar os certificados para o arquivo de dados que o WildFly utiliza antes de iniciar o servidor.

Configurar origens de dados

Para configurar o WildFly para aceder a uma origem de dados, tem de adicionar o controlador JAR do JDBC à imagem do Docker e, em seguida, executar os comandos da CLI JBoss adequados. Estes comandos têm de configurar a origem de dados ao compilar a imagem do Docker.

Os passos seguintes disponibilizam instruções para PostgreSQL, MySQL e SQL Server.

  1. Transfira o controlador do JDBC para PostgreSQL, MySQL ou SQL Server.

    Descompacte o arquivo transferido para obter o ficheiro .jar do controlador.

  2. Crie um ficheiro com um nome como module.xml e adicione o markup seguinte. Substitua o marcador de posição <module name> (incluindo as chavetas) por org.postgres para PostgreSQL, com.mysql para MySQL ou com.microsoft para SQL Server. Substitua <JDBC .jar file path> pelo nome do ficheiro .jar do passo anterior, incluindo o caminho completo para a localização na qual vai guardar o ficheiro de imagem do Docker; por exemplo, /opt/database.

    <?xml version="1.0" ?>
    <module xmlns="urn:jboss:module:1.1" name="<module name>">
        <resources>
           <resource-root path="<JDBC .jar file path>" />
        </resources>
        <dependencies>
            <module name="javax.api"/>
            <module name="javax.transaction.api"/>
        </dependencies>
    </module>
    
  3. Crie um ficheiro com um nome como datasource-commands.cli e adicione o código seguinte. Substitua <JDBC .jar file path> pelo valor que utilizou no passo anterior. Substitua <module file path> pelo nome e o caminho do ficheiro do passo anterior; por exemplo, /opt/database/module.xml.

    PostgreSQL

    batch
    module add --name=org.postgres --resources=<JDBC .jar file path> --module-xml=<module file path>
    /subsystem=datasources/jdbc-driver=postgres:add(driver-name=postgres,driver-module-name=org.postgres,driver-class-name=org.postgresql.Driver,driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource)
    data-source add --name=postgresDS --driver-name=postgres --jndi-name=java:jboss/datasources/postgresDS --connection-url=$DATABASE_CONNECTION_URL --user-name=$DATABASE_SERVER_ADMIN_FULL_NAME --password=$DATABASE_SERVER_ADMIN_PASSWORD --use-ccm=true --max-pool-size=5 --blocking-timeout-wait-millis=5000 --enabled=true --driver-class=org.postgresql.Driver --exception-sorter-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter --jta=true --use-java-context=true --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker
    reload
    run batch
    shutdown
    

    MySQL

    batch
    module add --name=com.mysql --resources=<JDBC .jar file path> --module-xml=<module file path>
    /subsystem=datasources/jdbc-driver=mysql:add(driver-name=mysql,driver-module-name=com.mysql,driver-class-name=com.mysql.cj.jdbc.Driver)
    data-source add --name=mysqlDS --jndi-name=java:jboss/datasources/mysqlDS --connection-url=$DATABASE_CONNECTION_URL --driver-name=mysql --user-name=$DATABASE_SERVER_ADMIN_FULL_NAME --password=$DATABASE_SERVER_ADMIN_PASSWORD --use-ccm=true --max-pool-size=5 --blocking-timeout-wait-millis=5000 --enabled=true --driver-class=com.mysql.cj.jdbc.Driver --jta=true --use-java-context=true --exception-sorter-class-name=com.mysql.cj.jdbc.integration.jboss.ExtendedMysqlExceptionSorter
    reload
    run batch
    shutdown
    

    SQL Server

    batch
    module add --name=com.microsoft --resources=<JDBC .jar file path> --module-xml=<module file path>
    /subsystem=datasources/jdbc-driver=sqlserver:add(driver-name=sqlserver,driver-module-name=com.microsoft,driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver,driver-datasource-class-name=com.microsoft.sqlserver.jdbc.SQLServerDataSource)
    data-source add --name=sqlDS --jndi-name=java:jboss/datasources/sqlDS --driver-name=sqlserver --connection-url=$DATABASE_CONNECTION_URL --validate-on-match=true --background-validation=false --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLValidConnectionChecker --exception-sorter-class-name=org.jboss.jca.adapters.jdbc.extensions.mssql.MSSQLExceptionSorter
    reload
    run batch
    shutdown
    
  4. Atualizar a configuração da origem de dados do JTA para a aplicação:

    Abra o ficheiro src/main/resources/META-INF/persistence.xml da aplicação e localize o elemento <jta-data-source>. Substitua os respetivos conteúdos, conforme mostrado aqui:

    PostgreSQL

    <jta-data-source>java:jboss/datasources/postgresDS</jta-data-source>
    

    MySQL

    <jta-data-source>java:jboss/datasources/mysqlDS</jta-data-source>
    

    SQL Server

    <jta-data-source>java:jboss/datasources/postgresDS</jta-data-source>
    
  5. Adicione o seguinte a Dockerfile, para que a origem de dados seja criada quando compilar a imagem do Docker.

    RUN /bin/bash -c '<WILDFLY_INSTALL_PATH>/bin/standalone.sh --start-mode admin-only &' && \
    sleep 30 && \
    <WILDFLY_INSTALL_PATH>/bin/jboss-cli.sh -c --file=/opt/database/datasource-commands.cli && \
    sleep 30
    
  6. Determine que DATABASE_CONNECTION_URL vai ser utilizado, pois são diferentes para cada servidor de base de dados e distintos dos valores no portal do Azure. O WildFly é obrigado a utilizar os formatos de URL mostrados aqui:

    PostgreSQL

    jdbc:postgresql://<database server name>:5432/<database name>?ssl=true
    

    MySQL

    jdbc:mysql://<database server name>:3306/<database name>?ssl=true\&useLegacyDatetimeCode=false\&serverTimezone=GMT
    

    SQL Server

    jdbc:sqlserver://<database server name>:1433;database=<database name>;user=<admin name>;password=<admin password>;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;
    
  7. Ao criar o YAML da implementação numa fase posterior, tem de transmitir as seguintes variáveis de ambiente, DATABASE_CONNECTION_URL, DATABASE_SERVER_ADMIN_FULL_NAME e DATABASE_SERVER_ADMIN_PASSWORD, com os valores adequados.

Para obter mais informações sobre como configurar a conectividade da base de dados com o WildFly, veja PostgreSQL, MySQL ou SQL Server.

Configurar recursos do JNDI

Para configurar cada recurso do JNDI que tem de configurar no WildFly, utilizará, geralmente, os passos seguintes:

  1. Transfira os ficheiros JAR necessários e copie-os para a imagem do Docker.
  2. Crie um ficheiro module.xml do WildFly que referencie esses ficheiros JAR.
  3. Crie qualquer configuração de que o recurso específico do JNDI precise.
  4. Crie o script da CLI do JBoss que vai ser utilizado durante a compilação do Docker para registar o recurso do JNDI.
  5. Adicione tudo ao Dockerfile.
  6. Transmita as variáveis de ambiente adequadas no YAML de implementação.

O exemplo abaixo mostra os passos necessários para criar o recurso do JNDI para a conectividade do JMS ao Azure Service Bus.

  1. Transfira o fornecedor Apache Qpid JMS.

    Descompacte o arquivo transferido para obter os ficheiros .jar.

  2. Crie um ficheiro com um nome como module.xml e adicione o markup em /opt/servicebus. Confirme que os números de versão dos ficheiros JAR estão alinhados com os nomes dos ficheiros JAR do passo anterior.

    <?xml version="1.0" ?>
    <module xmlns="urn:jboss:module:1.1" name="org.jboss.genericjms.provider">
     <resources>
      <resource-root path="proton-j-0.31.0.jar"/>
      <resource-root path="qpid-jms-client-0.40.0.jar"/>
      <resource-root path="slf4j-log4j12-1.7.25.jar"/>
      <resource-root path="slf4j-api-1.7.25.jar"/>
      <resource-root path="log4j-1.2.17.jar"/>
      <resource-root path="netty-buffer-4.1.32.Final.jar" />
      <resource-root path="netty-codec-4.1.32.Final.jar" />
      <resource-root path="netty-codec-http-4.1.32.Final.jar" />
      <resource-root path="netty-common-4.1.32.Final.jar" />
      <resource-root path="netty-handler-4.1.32.Final.jar" />
      <resource-root path="netty-resolver-4.1.32.Final.jar" />
      <resource-root path="netty-transport-4.1.32.Final.jar" />
      <resource-root path="netty-transport-native-epoll-4.1.32.Final-linux-x86_64.jar" />
      <resource-root path="netty-transport-native-kqueue-4.1.32.Final-osx-x86_64.jar" />
      <resource-root path="netty-transport-native-unix-common-4.1.32.Final.jar" />
      <resource-root path="qpid-jms-discovery-0.40.0.jar" />
     </resources>
     <dependencies>
      <module name="javax.api"/>
      <module name="javax.jms.api"/>
     </dependencies>
    </module>
    
  3. Crie um ficheiro jndi.properties em /opt/servicebus.

    connectionfactory.${MDB_CONNECTION_FACTORY}=amqps://${DEFAULT_SBNAMESPACE}.servicebus.windows.net?amqp.idleTimeout=120000&jms.username=${SB_SAS_POLICY}&jms.password=${SB_SAS_KEY}
    queue.${MDB_QUEUE}=${SB_QUEUE}
    topic.${MDB_TOPIC}=${SB_TOPIC}
    
  4. Crie um ficheiro com um nome como servicebus-commands.cli e adicione o código seguinte.

    batch
    /subsystem=ee:write-attribute(name=annotation-property-replacement,value=true)
    /system-property=property.mymdb.queue:add(value=myqueue)
    /system-property=property.connection.factory:add(value=java:global/remoteJMS/SBF)
    /subsystem=ee:list-add(name=global-modules, value={"name" => "org.jboss.genericjms.provider", "slot" =>"main"}
    /subsystem=naming/binding="java:global/remoteJMS":add(binding-type=external-context,module=org.jboss.genericjms.provider,class=javax.naming.InitialContext,environment=[java.naming.factory.initial=org.apache.qpid.jms.jndi.JmsInitialContextFactory,org.jboss.as.naming.lookup.by.string=true,java.naming.provider.url=/opt/servicebus/jndi.properties])
    /subsystem=resource-adapters/resource-adapter=generic-ra:add(module=org.jboss.genericjms,transaction-support=XATransaction)
    /subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=sbf-cd:add(class-name=org.jboss.resource.adapter.jms.JmsManagedConnectionFactory, jndi-name=java:/jms/${MDB_CONNECTION_FACTORY})
    /subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=sbf-cd/config-properties=ConnectionFactory:add(value=${MDB_CONNECTION_FACTORY})
    /subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=sbf-cd/config-properties=JndiParameters:add(value="java.naming.factory.initial=org.apache.qpid.jms.jndi.JmsInitialContextFactory;java.naming.provider.url=/opt/servicebus/jndi.properties")
    /subsystem=resource-adapters/resource-adapter=generic-ra/connection-definitions=sbf-cd:write-attribute(name=security-application,value=true)
    /subsystem=ejb3:write-attribute(name=default-resource-adapter-name, value=generic-ra)
    run-batch
    reload
    shutdown
    
  5. Adicione o seguinte a Dockerfile, para que o recurso do JNDI seja criado quando compilar a imagem do Docker.

    RUN /bin/bash -c '<WILDFLY_INSTALL_PATH>/bin/standalone.sh --start-mode admin-only &' && \
    sleep 30 && \
    <WILDFLY_INSTALL_PATH>/bin/jboss-cli.sh -c --file=/opt/servicebus/servicebus-commands.cli && \
    sleep 30
    
  6. Ao criar o YAML da implementação numa fase posterior, tem de transmitir as seguintes variáveis de ambiente, MDB_CONNECTION_FACTORY, DEFAULT_SBNAMESPACE e SB_SAS_POLICY, SB_SAS_KEY, MDB_QUEUE, SB_QUEUE, MDB_TOPIC e SB_TOPIC com os valores adequados.

Rever a configuração do WildFly

Reveja o Guia WildFly Admin para obter eventuais passos adicionais de pré-migração não abrangidos na orientação anterior.

Compilar e enviar a imagem do Docker para o Azure Container Registry

Depois de criar o Dockerfile, tem de compilar a imagem do Docker e publicá-la no Azure Container Registry.

Se tiver utilizado o nosso repositório WildFly Container Quickstart do GitHub, o processo de compilação e envio da imagem para o Azure Container Registry será equivalente a invocar os três comandos seguintes.

Nestes exemplos, a variável de ambiente MY_ACR contém o nome do Azure Container Registry e a variável MY_APP_NAME o nome da aplicação Web que pretende utilizar no Azure Container Registry.

Compilar o ficheiro WAR:

mvn package

Iniciar sessão no Azure Container Registry:

az acr login --name ${MY_ACR}

Criar e enviar a imagem:

az acr build --image ${MY_ACR}.azurecr.io/${MY_APP_NAME} --file src/main/docker/Dockerfile .

Em alternativa, pode utilizar a CLI do Docker para primeiro compilar e testar a imagem localmente, conforme mostrado nos comandos seguintes. Esta abordagem pode simplificar os testes e refinar a imagem antes da implementação inicial no ACR. No entanto, requer que instale a CLI do Docker e que confirme que o daemon do Docker está em execução.

Criar a imagem:

docker build -t ${MY_ACR}.azurecr.io/${MY_APP_NAME}

Executar a imagem localmente:

docker run -it -p 8080:8080 ${MY_ACR}.azurecr.io/${MY_APP_NAME}

Pode agora aceder à aplicação em http://localhost:8080.

Iniciar sessão no Azure Container Registry:

az acr login --name ${MY_ACR}

Enviar a imagem para o Azure Container Registry:

docker push ${MY_ACR}.azurecr.io/${MY_APP_NAME}

Para obter informações mais aprofundadas sobre como compilar e armazenar imagens de contentores no Azure, veja o módulo do Learn Compilar e armazenar imagens de contentores com o Azure Container Registry.

Aprovisionar um endereço IP público

Se a sua aplicação for acessível a partir das suas redes internas ou virtuais, precisa de um endereço IP estático público. Deverá aprovisionar esse endereço IP dentro do grupo de recursos do nó de cluster, conforme mostrado no exemplo seguinte:

export nodeResourceGroup=$(az aks show \
    --resource-group $resourceGroup \
    --name $aksName \
    --query 'nodeResourceGroup' \
    --output tsv)
export publicIp=$(az network public-ip create \
    --resource-group $nodeResourceGroup \
    --name applicationIp \
    --sku Standard \
    --allocation-method Static \
    --query 'publicIp.ipAddress' \
    --output tsv)
echo "Your public IP address is ${publicIp}."

Implementar no Azure Kubernetes Service (AKS)

Crie e aplique o(s) ficheiro(s) YAML do Kubernetes. Para obter mais informações, consulte Guia de início rápido: implantar um cluster do Serviço Kubernetes do Azure (AKS) usando a CLI do Azure. Se estiver a criar um balanceador de carga externo (seja para a aplicação ou para um controlador de entrada), certifique-se de que fornece o endereço IP aprovisionado na secção anterior como o LoadBalancerIP.

Inclua parâmetros exteriorizados como variáveis de ambiente. Para obter mais informações, veja Definir Variáveis de Ambiente para um Contentor. Não inclua segredos (tais como palavras-passe, chaves de API e cadeias de ligação JDBC). Estes são abrangidos na secção seguinte.

Inclua as definições de memória e CPU quando criar o YAML da implementação, para que os contentores sejam dimensionados corretamente.

Configurar armazenamento persistente

Se a sua aplicação necessitar de armazenamento não volátil, configure um ou mais Volumes Persistentes.

Migrar trabalhos agendados

Para executar trabalhos agendados no seu cluster do AKS, defina o CronJobs do Kubernetes conforme for necessário. Para obter mais informações, veja Executar Tarefas Automatizadas com um CronJob.

Pós-migração

Agora que já migrou a sua aplicação para o Azure Kubernetes Service, deve verificar se esta funciona como o esperado. Depois de fazer isso, consulte as recomendações a seguir para tornar seu aplicativo mais nativo da nuvem.

Recomendações