JBoss EAP 애플리케이션을 Azure Kubernetes Service의 WildFly로 마이그레이션

이 가이드에서는 Azure Kubernetes Service 컨테이너의 WildFly에서 실행되도록 기존 JBoss EAP 애플리케이션을 마이그레이션할 때 알아야 할 사항에 대해 설명합니다.

사전 마이그레이션

마이그레이션을 성공적으로 수행하려면 시작하기 전에 다음 섹션에서 설명하는 평가 및 인벤토리 단계를 완료합니다.

인벤토리 서버 용량

현재 프로덕션 서버의 하드웨어(메모리, CPU, 디스크) 및 평균 및 최대 요청 수 및 리소스 사용률을 문서화합니다. 선택한 마이그레이션 경로에 관계없이 이 정보가 필요합니다. 예를 들어 노드 풀의 VM 크기 선택, 컨테이너에서 사용할 메모리 양 및 컨테이너에 필요한 CPU 공유 수를 안내하는 데 유용합니다.

AKS에서 노드 풀의 크기를 조정할 수 있습니다. 방법을 알아보려면 AKS(Azure Kubernetes Service)의 노드 풀 크기 조정을 참조하세요.

모든 비밀 인벤토리

프로덕션 서버의 모든 속성 및 구성 파일에서 비밀 및 암호를 확인합니다. WAR에서 jboss-web.xml을 검사 합니다. 암호 또는 자격 증명이 포함된 구성 파일도 애플리케이션 내에서 찾을 수 있습니다.

이러한 비밀을 Azure KeyVault에 저장하는 것이 좋습니다. 자세한 내용은 Azure Key Vault 기본 개념을 참조 하세요.

모든 인증서 인벤토리화

공용 SSL 엔드포인트에 사용되는 모든 인증서를 문서화합니다. 다음 명령을 실행하여 프로덕션 서버의 모든 인증서를 볼 수 있습니다.

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

지원되는 Java 버전이 올바르게 작동하는지 확인

Azure Kubernetes Service에서 WildFly를 사용하려면 특정 버전의 Java가 필요하므로 지원되는 버전을 사용하여 애플리케이션이 올바르게 실행되는지 확인해야 합니다.

참고 항목

이 유효성 검사는 현재 서버가 지원되지 않는 JDK(예: Oracle JDK 또는 IBM OpenJ9)에서 실행 중인 경우에 특히 중요합니다.

현재 Java 버전을 가져오려면 프로덕션 서버에 로그인하고 다음 명령을 실행합니다.

java -version

WildFly를 실행하는 데 사용할 버전에 대한 지침은 요구 사항을 참조하세요.

JNDI 리소스 인벤토리

모든 JNDI 리소스를 인벤토리화합니다. JMS 메시지 브로커와 같은 일부 경우 마이그레이션 또는 재구성이 필요할 수 있습니다.

세션 복제본(replica) 사용 여부 확인

애플리케이션이 세션 복제본(replica) 의존하는 경우 애플리케이션을 변경하여 이 종속성을 제거해야 합니다.

애플리케이션 내부

WEB-INF/jboss-web.xml 및/또는 WEB-INF/web.xml 파일을 검사합니다.

문서 데이터 원본

애플리케이션에서 데이터베이스를 사용하는 경우 다음 정보를 캡처해야 합니다.

  • 데이터 원본 이름은 무엇인가요?
  • 연결 풀 구성이란?
  • JDBC 드라이버 JAR 파일은 어디에서 찾을 수 있나요?

자세한 내용은 JBoss EAP 설명서의 JBoss EAP 데이터 원본 정보를 참조하세요.

파일 시스템의 사용 여부 및 방법 확인

애플리케이션 서버에서 파일 시스템을 사용하려면 재구성하거나 드물게 아키텍처 변경이 필요합니다. 파일 시스템은 JBoss EAP 모듈 또는 애플리케이션 코드에서 사용할 수 있습니다. 다음 섹션에서 설명하는 시나리오의 일부 또는 전부를 식별할 수 있습니다.

읽기 전용 정적 콘텐츠

애플리케이션이 현재 정적 콘텐츠를 제공하는 경우 대체 위치가 필요합니다. 정적 콘텐츠를 Azure Blob Storage로 이동하고 전역적으로 빠른 다운로드를 위해 Azure CDN을 추가하는 것이 좋습니다. 자세한 내용은 Azure Storage빠른 시작에서 정적 웹 사이트 호스팅: Azure CDN과 Azure Storage 계정 통합을 참조하세요. Azure Spring Apps Enterprise 계획의 앱에 정적 콘텐츠를 직접 배포할 수도 있습니다. 자세한 내용은 웹 정적 파일 배포를 참조 하세요.

동적으로 게시된 정적 콘텐츠

애플리케이션이 애플리케이션에서 업로드/생성되었지만 생성 후 변경할 수 없는 정적 콘텐츠를 허용하는 경우, 위에서 설명한 대로 Azure Blob Storage 및 Azure CDN과 Azure Function을 사용하여 업로드 및 CDN 새로 고침을 처리할 수 있습니다. Azure Functions를 사용하여 정적 콘텐츠를 업로드 및 CDN 미리 로드할 때 사용할 샘플 구현을 제공했습니다. Azure Spring Apps Enterprise 계획의 앱에 정적 콘텐츠를 직접 배포할 수도 있습니다. 자세한 내용은 웹 정적 파일 배포를 참조 하세요.

동적 또는 내부 콘텐츠

애플리케이션에서 자주 쓰고 읽는 파일(예: 임시 데이터 파일) 또는 애플리케이션에만 표시되는 정적 파일의 경우 Azure Storage 공유를 영구 볼륨으로 탑재할 수 있습니다. 자세한 내용은 Azure Kubernetes Service에서 Azure Files를 사용하여 영구적 볼륨을 동적으로 만들고 사용하는 것을 참조 하세요.

애플리케이션이 예약된 작업에 의존하는지 확인

Quartz Scheduler 작업 또는 Unix cron 작업과 같은 예약된 작업은 AKS(Azure Kubernetes Service)와 함께 사용하면 안 됩니다. Azure Kubernetes Service는 예약된 작업이 포함된 애플리케이션을 내부적으로 배포하는 것을 방지하지 않습니다. 그러나 애플리케이션이 확장되는 경우 동일한 예약된 작업이 예약된 기간마다 두 번 이상 실행될 수 있습니다. 이 상황은 의도하지 않은 결과를 초래할 수 있습니다.

AKS 클러스터에서 예약된 작업을 실행하려면 필요에 따라 Kubernetes CronJobs를 정의합니다. 자세한 내용은 CronJob을 사용하여 자동화된 작업 실행을 참조하세요.

온-프레미스에 대한 연결이 필요한지 확인

애플리케이션이 온-프레미스 서비스에 액세스해야 하는 경우 Azure의 연결 서비스 중 하나를 프로비전해야 합니다. 자세한 내용은 온-프레미스 네트워크를 Azure에 연결하기 위한 솔루션 선택을 참조하세요. 또는 온-프레미스 리소스가 노출하는 공개적으로 사용 가능한 API를 사용하도록 애플리케이션을 리팩터링해야 합니다.

JMS(Java Message Service) 큐 또는 토픽을 사용하는지 확인

애플리케이션에서 JMS 큐 또는 토픽을 사용하는 경우 외부에서 호스팅되는 JMS 서버로 마이그레이션해야 합니다. Azure Service Bus 및 AMQP(고급 메시지 큐 프로토콜)는 JMS를 사용하는 사람들에게 훌륭한 마이그레이션 전략이 될 수 있습니다. 자세한 내용은 Azure Service Bus 및 AMQP 1.0에서 JMS 사용을 참조 하세요.

JMS 영구 저장소가 구성된 경우 해당 구성을 캡처하고 마이그레이션 후에 적용해야 합니다.

애플리케이션에서 JBoss-EAP 관련 API를 사용하는지 확인

애플리케이션에서 JBoss-EAP 관련 API를 사용하는 경우 해당 종속성을 제거하기 위해 리팩터링해야 합니다.

애플리케이션에서 Entity Beans 또는 EJB 2.x 스타일 CMP Beans를 사용하는지 확인

애플리케이션에서 Entity Beans 또는 EJB 2.x 스타일 CMP Beans를 사용하는 경우 애플리케이션을 리팩터링하여 이러한 종속성을 제거해야 합니다.

Java EE 애플리케이션 클라이언트 기능이 사용 중인지 확인

Java EE 애플리케이션 클라이언트 기능을 사용하여 (서버) 애플리케이션에 연결하는 클라이언트 애플리케이션이 있는 경우 HTTP API를 사용하려면 클라이언트 애플리케이션과 (서버) 애플리케이션을 모두 리팩터링해야 합니다.

애플리케이션에 OS 관련 코드가 포함되어 있는지 확인

호스트 OS에 대한 종속성이 있는 코드가 애플리케이션에 포함되어 있는 경우 해당 종속성을 제거하려면 이 코드를 리팩터링해야 합니다. 예를 들어 파일 시스템 경로에서 사용하고 있는 / 또는 \File.Separator 또는 Paths.get으로 바꿔야 할 수 있습니다.

EJB 타이머가 사용 중인지 확인

애플리케이션에서 EJB 타이머를 사용하는 경우 각 WildFly 인스턴스에서 독립적으로 EJB 타이머 코드를 트리거할 수 있는지 확인해야 합니다. 이 유효성 검사는 Azure Kubernetes 서비스 배포 시나리오에서 각 EJB 타이머가 자체 WildFly 인스턴스에서 트리거되기 때문에 필요합니다.

JCA 커넥터가 사용되는지 확인

애플리케이션에서 JCA 커넥터를 사용하는 경우 WildFly에서 JCA 커넥터를 사용할 수 있는지 확인합니다. JCA 구현이 JBoss EAP에 연결된 경우 애플리케이션을 리팩터링하여 해당 종속성을 제거해야 합니다. WildFly에서 JCA 커넥터를 사용할 수 있는 경우 JCA 커넥터를 사용할 수 있도록 서버 클래스 경로에 JAR을 추가하고 필요한 구성 파일을 WildFly 서버 디렉터리의 올바른 위치에 배치해야 합니다.

JAAS가 사용 중인지 확인

애플리케이션에서 JAAS를 사용 중인 경우 JAAS가 구성된 방식을 캡처해야 합니다. JAAS가 데이터베이스를 사용 중인 경우 WildFly의 JAAS 도메인으로 변환할 수 있습니다. 사용자 지정 구현인 경우 WildFly에서 사용할 수 있는지 확인해야 합니다.

애플리케이션에서 리소스 어댑터를 사용하는지 확인

애플리케이션에 RA(리소스 어댑터)가 필요한 경우 WildFly와 호환되어야 합니다. RA가 서버에 배포하고 올바르게 구성하여 WildFly의 독립 실행형 인스턴스에서 제대로 작동하는지 여부를 확인합니다. RA가 제대로 작동하는 경우 DOCKER 이미지의 서버 클래스 경로에 JAR을 추가하고 필요한 구성 파일을 사용할 수 있도록 WildFly 서버 디렉터리의 올바른 위치에 배치해야 합니다.

애플리케이션이 여러 WAR로 구성되었는지 확인

애플리케이션이 여러 WAR로 구성된 경우 각 WAR을 별도의 애플리케이션으로 처리하고 각 WAR에 대해 이 가이드를 진행해야 합니다.

애플리케이션이 EAR로 패키지되었는지 확인

애플리케이션이 EAR 파일로 패키지된 경우 application.xml 파일을 검사하고 구성을 캡처해야 합니다.

참고 항목

AKS 리소스를 더 효율적으로 사용하기 위해 각 웹 애플리케이션의 크기를 독립적으로 조정하려면 EAR을 별도의 웹 애플리케이션으로 분리해야 합니다.

프로덕션 서버에서 실행되는 모든 외부 프로세스 및 디먼 식별

애플리케이션 서버 외부에서 실행 중인 프로세스(예: 디먼 모니터링)가 있는 경우 해당 프로세스를 제거하거나 다른 곳으로 마이그레이션해야 합니다.

현재 위치 테스트 수행

컨테이너 이미지를 만들기 전에 애플리케이션을 AKS에서 사용하려는 JDK 및 WildFly 버전으로 마이그레이션합니다. 애플리케이션을 철저히 테스트하여 호환성 및 성능을 확인합니다.

마이그레이션

Azure Container Registry 및 Azure Kubernetes Service 프로비전

다음 명령을 사용하여 레지스트리에 읽기 권한자 역할이 있는 서비스 주체를 사용하여 컨테이너 레지스트리 및 Azure Kubernetes 클러스터를 만듭니다. 클러스터의 네트워킹 요구 사항에 적합한 네트워크 모델을 선택해야 합니다.

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

WildFly용 Docker 이미지 만들기

Dockerfile을 만들려면 다음과 같은 필수 조건을 갖추어야 합니다.

  • 지원되는 JDK입니다.
  • WildFly 설치
  • JVM 런타임 옵션.
  • 환경 변수를 전달하는 방법(해당하는 경우).

그런 다음, 해당하는 경우 다음 섹션에 설명된 단계를 수행할 수 있습니다. WildFly 컨테이너 빠른 시작 리포지토리를 Dockerfile 및 웹 애플리케이션의 시작점으로 사용할 수 있습니다.

  1. KeyVault FlexVolume 구성
  2. 데이터 원본 설정
  3. JNDI 리소스 설정
  4. WildFly 구성 검토

KeyVault FlexVolume 구성

Azure KeyVault를 만들고 필요한 모든 비밀을 채웁다. 자세한 내용은 빠른 시작: Azure CLI를 사용하여 Azure Key Vault에서 비밀 설정 및 검색을 참조하세요. 그런 다음, Pod에서 이러한 비밀을 액세스할 수 있도록 KeyVault FlexVolume을 구성합니다.

WildFly를 부트스트랩하는 데 사용되는 시작 스크립트도 업데이트해야 합니다. 이 스크립트는 서버를 시작하기 전에 WildFly에서 사용하는 키 저장소로 인증서를 가져와야 합니다.

데이터 원본 설정

데이터 원본에 액세스하도록 WildFly를 구성하려면 Docker 이미지에 JDBC 드라이버 JAR을 추가한 다음 적절한 JBoss CLI 명령을 실행해야 합니다. 이러한 명령은 Docker 이미지를 빌드할 때 데이터 원본을 설정해야 합니다.

다음 단계에서는 PostgreSQL, MySQL 및 SQL Server에 대한 지침을 제공합니다.

  1. PostgreSQL, MySQL 또는 SQL Server용 JDBC 드라이버를 다운로드합니다.

    다운로드한 보관 파일의 압축을 풀고 드라이버 .jar 파일을 가져옵니다.

  2. 이름이 같은 module.xml 파일을 만들고 다음 태그를 추가합니다. <module name> 자리 표시자(꺾쇠 괄호 포함)를 PostgreSQL의 경우 org.postgres, MySQL의 경우 com.mysql, SQL Server의 경우 com.microsoft로 바꿉니다. 예를 들어 /opt/databaseDocker 이미지에 파일을 배치할 위치의 전체 경로를 포함하여 이전 단계의 .jar 파일 이름으로 바꿉 <JDBC .jar file path> 있습니다.

    <?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. datasource-commands.cli 같은 이름으로 파일을 만들고 다음 코드를 추가합니다. 이전 단계에서 사용한 값으로 바꿉 <JDBC .jar file path> 습니다. 예를 들어 /opt/database/module.xml이전 단계의 파일 이름 및 경로로 바꿉 <module file path> 다.

    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. 애플리케이션에 대한 JTA 데이터 원본 구성을 업데이트합니다.

    앱의 src/main/resources/META-INF/persistence.xml 파일을 열고 <jta-data-source> 요소를 찾습니다. 다음과 같이 내용을 바꿉니다.

    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. Docker 이미지를 빌드할 Dockerfile 때 데이터 원본이 생성되도록 다음을 추가합니다.

    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. DATABASE_CONNECTION_URL 각 데이터베이스 서버마다 다르고 Azure Portal의 값과 다르므로 사용할 대상을 결정합니다. 여기에 표시된 URL 형식은 WildFly에서 사용해야 합니다.

    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. 이후 단계에서 배포 YAML을 만들 때는 환경 변수 DATABASE_CONNECTION_URL, DATABASE_SERVER_ADMIN_FULL_NAMEDATABASE_SERVER_ADMIN_PASSWORD를 적절한 값과 함께 전달해야 합니다.

WildFly를 사용하여 데이터베이스 연결을 구성하는 방법에 대한 자세한 내용은 PostgreSQL, MySQL 또는 SQL Server를 참조하세요.

JNDI 리소스 설정

WildFly에서 구성해야 하는 각 JNDI 리소스를 설정하려면 일반적으로 다음 단계를 사용합니다.

  1. 필요한 JAR 파일을 다운로드하고 Docker 이미지에 복사합니다.
  2. 해당 JAR 파일을 참조하는 WildFly module.xml 파일을 만듭니다.
  3. 특정 JNDI 리소스에 필요한 구성을 만듭니다.
  4. Docker 빌드 중에 JNDI 리소스를 등록하는 데 사용할 JBoss CLI 스크립트를 만듭니다.
  5. Dockerfile에 모든 항목을 추가합니다.
  6. 배포 YAML에서 적절한 환경 변수를 전달합니다.

아래 예제에서는 Azure Service Bus에 대한 JMS 연결을 위한 JNDI 리소스를 만드는 데 필요한 단계를 보여 줍니다.

  1. Apache Qpid JMS 공급자 다운로드

    다운로드한 보관 파일의 압축을 풀어 .jar 파일을 가져옵니다.

  2. 이름이 같은 module.xml 파일을 만들고 다음 태그를 추가합니다 /opt/servicebus. JAR 파일의 버전 번호가 이전 단계의 JAR 파일 이름과 일치하는지 확인합니다.

    <?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. 에서 jndi.properties 파일을 만듭니다 /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. servicebus-commands.cli 같은 이름으로 파일을 만들고 다음 코드를 추가합니다.

    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. Docker 이미지를 빌드할 때 JNDI 리소스가 생성되도록 Dockerfile에 다음을 추가합니다.

    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. 이후 단계에서 배포 YAML을 만들 때는 다음 환경 변수 및 MDB_CONNECTION_FACTORYDEFAULT_SBNAMESPACE , SB_SAS_KEY, SB_TOPICMDB_TOPICSB_QUEUEMDB_QUEUESB_SAS_POLICY적절한 값을 전달해야 합니다.

WildFly 구성 검토

WildFly 관리 가이드를 검토하여 이전 지침에서 다루지 않는 추가 마이그레이션 전 단계를 설명합니다.

Docker 이미지를 빌드하고 Azure Container Registry로 푸시

Dockerfile을 만든 후 Docker 이미지를 빌드하고 Azure Container Registry에 게시해야 합니다.

WildFly Container 빠른 시작 GitHub 리포지토리를 사용한 경우 이미지를 빌드하고 Azure 컨테이너 레지스트리에 푸시하는 프로세스는 다음 세 가지 명령을 호출하는 것과 같습니다.

이러한 예제 MY_ACR 에서 환경 변수는 Azure 컨테이너 레지스트리의 이름을 보유하며 MY_APP_NAME 변수는 Azure 컨테이너 레지스트리에서 사용하려는 웹 애플리케이션의 이름을 보유합니다.

WAR 파일을 빌드합니다.

mvn package

Azure Container Registry에 로그인합니다.

az acr login --name ${MY_ACR}

이미지를 빌드하고 푸시합니다.

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

또는 다음 명령과 같이 Docker CLI를 사용하여 먼저 이미지를 로컬로 빌드하고 테스트할 수 있습니다. 이 방법을 사용하면 ACR에 처음 배포하기 전에 이미지를 테스트하고 구체화하는 작업을 간소화할 수 있습니다. 그러나 Docker CLI를 설치하고 Docker 디먼이 실행 중인지 확인해야 합니다.

이미지를 빌드합니다.

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

로컬에서 이미지를 실행합니다.

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

이제 http://localhost:8080에서 애플리케이션에 액세스할 수 있습니다.

Azure Container Registry에 로그인합니다.

az acr login --name ${MY_ACR}

Azure Container Registry로 이미지를 푸시합니다.

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

Azure에서 컨테이너 이미지를 빌드하고 저장하는 방법에 대한 자세한 내용은 Azure Container Registry를 사용하여 컨테이너 이미지 빌드 및 저장 학습 모듈 을 참조하세요.

공용 IP 주소 프로비전

내부 또는 가상 네트워크 외부에서 애플리케이션에 액세스할 수 있는 경우 공용 고정 IP 주소가 필요합니다. 다음 예제와 같이 클러스터의 노드 리소스 그룹 내에 이 IP 주소를 프로비전해야 합니다.

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

AKS에 배포

Kubernetes YAML 파일을 만들고 적용합니다. 자세한 내용은 빠른 시작: Azure CLI를 사용하여 Azure Kubernetes Service 클러스터 배포를 참조하세요. 외부 부하 분산 장치(애플리케이션 또는 수신 컨트롤러용)를 만드는 경우 이전 섹션에서 프로비전된 IP 주소를 로 LoadBalancerIP제공해야 합니다.

외부화된 매개 변수를 환경 변수로 포함합니다. 자세한 내용은 컨테이너의 환경 변수 정의를 참조하세요. 비밀(예: 암호, API 키 및 JDBC 연결 문자열)을 포함하지 마세요. 이러한 내용은 다음 섹션에 설명되어 있습니다.

컨테이너 크기가 제대로 조정되도록 배포 YAML을 만들 때 메모리 및 CPU 설정을 포함해야 합니다.

영구 스토리지 구성

애플리케이션에 비휘발성 스토리지가 필요한 경우 하나 이상의 영구 볼륨을 구성합니다.

예약된 작업 마이그레이션

AKS 클러스터에서 예약된 작업을 실행하려면 필요에 따라 Kubernetes CronJobs를 정의합니다. 자세한 내용은 CronJob을 사용하여 자동화된 작업 실행을 참조하세요.

마이그레이션 후

이제 애플리케이션을 Azure Kubernetes Service로 마이그레이션했으므로 예상대로 작동하는지 확인해야 합니다. 이 작업이 완료되면 애플리케이션을 클라우드 네이티브로 만들 수 있는 몇 가지 추천 사항이 있습니다.

권장 사항

  • 수신 컨트롤러 또는 애플리케이션 부하 분산 장치에 할당된 IP 주소에 DNS 이름을 추가하는 것이 좋습니다. 자세한 내용은 AKS에서 고정 공용 IP 주소를 사용하여 수신 컨트롤러 만들기를 참조하세요.

  • 애플리케이션에 대한 HELM 차트를 추가하는 것이 좋습니다. HELM 차트를 사용하면 더 다양한 고객 세트에서 사용하고 사용자 지정할 수 있도록 애플리케이션 배포를 매개 변수화할 수 있습니다.

  • DevOps 전략을 설계하고 구현합니다. 개발 속도를 높이는 동시에 안정성을 유지하기 위해 Azure Pipelines를 사용하여 배포를 자동화하고 테스트하는 것이 좋습니다. 자세한 내용은 AKS 빌드 및 배포를 참조 하세요.

  • 클러스터에 대해 Azure Monitoring을 사용하도록 설정합니다. 자세한 내용은 이미 배포된 AKS 클러스터의 모니터링 사용을 참조하세요. 이를 통해 Azure Monitor는 컨테이너 로그를 수집하고 사용률을 추적할 수 있습니다.

  • Prometheus를 통해 애플리케이션별 메트릭을 공개하는 것이 좋습니다. Prometheus는 Kubernetes 커뮤니티에서 광범위하게 채택된 오픈 소스 메트릭 프레임워크입니다. 사용자 고유의 Prometheus 서버를 호스팅하는 대신 Azure Monitor에서 스크랩하는 Prometheus 메트릭을 구성하여 애플리케이션에서 메트릭 집계를 사용하도록 설정하고 비정상 조건에 대한 자동화된 응답 또는 에스컬레이션을 수행할 수 있습니다. 자세한 내용은 컨테이너용 Azure Monitor를 사용하여 Prometheus 메트릭의 스크래핑 구성을 참조하세요.

  • 비즈니스 연속성 및 재해 복구 전략을 설계하고 구현합니다. 중요 업무용 애플리케이션의 경우 다중 지역 배포 아키텍처를 고려하세요. 자세한 내용은 AKS의 비즈니스 연속성 및 재해 복구 모범 사례를 참조 하세요.

  • Kubernetes 버전 지원 정책을 검토합니다. 항상 지원되는 버전을 실행하도록 AKS 클러스터를 계속 업데이트해야 합니다. 자세한 내용은 AKS 클러스터 업그레이드를 참조 하세요.

  • 클러스터 관리 및 애플리케이션 개발을 담당하는 모든 팀 구성원이 관련 AKS 모범 사례를 검토하도록 합니다. 자세한 내용은 AKS에서 애플리케이션을 빌드하고 관리하는 클러스터 운영자 및 개발자 모범 사례를 참조하세요.

  • 배포 파일에 롤링 업데이트 수행 방법이 지정되어 있는지 확인합니다. 자세한 내용은 Kubernetes 설명서의 롤링 업데이트 배포를 참조하세요.

  • 최대 시간 로드를 처리하도록 자동 크기 조정을 설정합니다. 자세한 내용은 AKS의 애플리케이션 요구에 맞게 클러스터 자동 크기 조정을 참조하세요.

  • 코드 캐시 크기를 모니터링하고 JVM 매개 변수 -XX:InitialCodeCacheSize-XX:ReservedCodeCacheSize Dockerfile에 추가하여 성능을 더욱 최적화하는 것이 좋습니다. 자세한 내용은 Oracle 설명서의 Codecache 튜닝을 참조하세요.