티스토리 뷰

728x90
반응형

본 포스팅에서는 Jenkins를 활용한 WildFly CI/CD 환경 구성 방법에 대해 살펴보겠습니다.
Jenkins 설치 과정은 아래 포스팅을 참고하세요.

[Jenkins] Jenkins 설치 가이드

 

전형적인 Legacy 환경의 Web Application Server의 Continuous Delivery & Continuous Deploy 구성에 대해 가이드를 진행하고 github를 통한 source 통합 빌드, 사용자 권한 관리 등 Jenkins 활용 가이드에 대해서도 살펴보도록 하겠습니다.

 

1) Jenkins Global Tool Configuration

다음은 Jenkins의 메인 화면입니다.

메인 화면 왼쪽의 메뉴 중 Jenkins 관리를 선택합니다.

다음과 같이 Jenkins 관리 → Global Tool Configuration을 선택합니다.

Global Tool Configuration은 말 그대로 Jenkins 전체에서 사용할 수 있는 전역 설정이라고 볼 수 있습니다.

해당 항목에서 저희는 JDK와 Maven 관련 설정을 추가할 예정입니다.

먼저 JDK를 추가해 보도록 하겠습니다. JDK Installation을 선택합니다.

위와 같이 JDK에 대한 Name & JAVA_HOME을 추가합니다.

다음으로 Maven을 추가해 보도록 하겠습니다. Maven Installation을 선택합니다.

위와 같이 Maven에 대한 Name & MAVEN_HOME을 추가합니다.

추가가 완료되면, Save 버튼을 클릭하여 설정을 완료합니다.

2) FreeStyle Project 생성

다음으로 WildFly에 Application을 Deploy 하기 위한 FreeStyle Project를 생성하는 과정입니다.

Jenkins 메인 화면의 오른쪽 메뉴 항목 중 새로운 Item을 선택합니다.

위와 같이 Jenkins에서 생성 가능한 다양한 Job 중 FreeStyle project를 선택하고 원하는 Item Name을 입력합니다.

하단의 OK 버튼을 선택하면 상세한 Jenkins Job 설정 화면으로 이동됩니다.

 

3) Jenkins Job 상세 설정

위와 같이 Jenkins FreeStyle project에 대한 상세 설정 화면으로 이동하게 됩니다.

먼저 아래와 같이 소스 코드 관리부분의 git을 선택합니다.

다양한 형상관리 툴과 연동이 가능하며, 본 포스팅에서는 git을 예로 들도록 하겠습니다. git repository를 추가하기 위해서는 Add Credentials 정보와 Repository URL 정보 그리고 Branch 정보가 필요합니다.

위와 같이 Credentials 정보를 입력합니다.

필요한 정보는 github 또는 gitlab의 Username, Password, ID, Description 정보를 입력하고 Add 버튼을 클릭합니다.

이후 Repository URL 정보를 입력하고 마지막으로 Branches to build의 branch를 선택합니다.

다음으로 Build 설정입니다.

Build 설정의 Add build step 콤보박스를 열어 Invoke top-level Maven targets를 선택하여 추가하고 Global Property 설정에서 추가한 Maven Version 선택 및 Goals로 clean package를 입력합니다. Maven 빌드 시 clean을 수행하고 Build 및 Packaging을 진행하는 옵션입니다.

이때, Maven Build 시 pom.xml 파일을 Build 환경과 배포환경을 구분하여 적용하고 싶을 경우 고급을 선택하고, pom.xml 파일 이름을 입력한다.

다음으로 Add build step 콤보박스를 열어 Execute Shell을 추가합니다.

해당 설정에서는 WildFly에 디플로이 하기 위한 deploy.xml을 생성하여 maven으로 deploy를 시도합니다.

#!/bin/bash
wildfly_plugin_version=2.0.1.Final

# 서버 접속 정보 예시
wildfly_hostname=192.168.56.105
wildfly_port=9990
wildfly_username=admin
wildfly_password=admin

pushd target
shopt -s nullglob
for file in *.war; do
  war_filename="${file}"
  break
done
popd

cat << EOF > deploy.xml
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>example.com</groupId>
  <artifactId>wildfly-deploy</artifactId>
  <version>1</version>
  <build>
    <plugins>
      <plugin>
        <groupId>org.wildfly.plugins</groupId>
          <artifactId>wildfly-maven-plugin</artifactId>
          <version>${wildfly_plugin_version}</version>
          <configuration>
            <filename>target/${war_filename}</filename>
            <hostname>${wildfly_hostname}</hostname>
            <port>${wildfly_port}</port>
            <username>${wildfly_username}</username>
            <password>${wildfly_password}</password>
            <targetDir>.</targetDir>
            <force>true</force>
          </configuration>
        </plugin>
      </plugins>
  </build>
</project>
EOF

exec mvn -f deploy.xml wildfly:deploy-only

상단의 wildfly 환경변수를 구성 환경에 맞게 수정하여 반영하며, 저장 버튼을 클릭하여 상세 설정을 완료합니다.

WildFly 여러대에 배포를 수행하기 위해서는 Execute Shell을 추가 생성하고 각 환경에 맞게 설정 값을 변경하면 됩니다.

저장 버튼을 클릭하면 신규로 생성한 FreeStyle Project의 메인화면으로 이동되며, 왼쪽 메뉴 중 Build Now를 클릭하면 Build를 시작하게 됩니다.

왼쪽 메뉴 하단에는 Build History가 출력되며 #Build_Number(#2)를 클릭하면 다음과 같이 해당 빌드의 상세 정보를 확인할 수 있는 화면으로 이동됩니다.

위와 같이 빌드 정보를 상세히 확인할 수 있으며, 왼쪽 메뉴 중 Console Output을 선택하면, 다음과 같이 빌드 로그를 확인할 수 있습니다.

위와 같이 빌드가 최종적으로 SUCCESS되고 DEPLOY까지 완료되면 해당 WAS 서버 로그 확인 및 샘플 페이지 호출을 수행하게 됩니다.

앞선 포스팅에서 구성한 WildFly에 접속하여 로그를 확인해 보도록 하겠습니다.

23:27:12,021 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-2) WFLYSRV0028: Stopped deployment template.war (runtime-name: template.war) in 75ms
23:27:12,022 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) WFLYSRV0027: Starting deployment of "template.war" (runtime-name: "template.war")
23:27:12,888 WARN  [org.jboss.as.ee] (MSC service thread 1-4) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletServerHttpResponse$ResponseAsyncListener due to an exception (enable DEBUG log level to see the cause)
23:27:12,888 WARN  [org.jboss.as.ee] (MSC service thread 1-4) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletHttpHandlerAdapter$HandlerResultAsyncListener due to an exception (enable DEBUG log level to see the cause)
23:27:12,889 WARN  [org.jboss.as.ee] (MSC service thread 1-4) WFLYEE0007: Not installing optional component org.springframework.http.server.ServletServerHttpAsyncRequestControl due to an exception (enable DEBUG log level to see the cause)
23:27:12,889 WARN  [org.jboss.as.ee] (MSC service thread 1-4) WFLYEE0007: Not installing optional component org.springframework.web.context.request.async.StandardServletAsyncWebRequest due to an exception (enable DEBUG log level to see the cause)
23:27:12,890 WARN  [org.jboss.as.ee] (MSC service thread 1-4) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletServerHttpRequest$RequestAsyncListener due to an exception (enable DEBUG log level to see the cause)
23:27:12,945 INFO  [io.undertow.servlet] (ServerService Thread Pool -- 197) 2 Spring WebApplicationInitializers detected on classpath
23:27:13,293 INFO  [stdout] (ServerService Thread Pool -- 197) 
23:27:13,293 INFO  [stdout] (ServerService Thread Pool -- 197)   .   ____          _            __ _ _
23:27:13,293 INFO  [stdout] (ServerService Thread Pool -- 197)  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
23:27:13,293 INFO  [stdout] (ServerService Thread Pool -- 197) ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
23:27:13,293 INFO  [stdout] (ServerService Thread Pool -- 197)  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
23:27:13,298 INFO  [stdout] (ServerService Thread Pool -- 197)   '  |____| .__|_| |_|_| |_\__, | / / / /
23:27:13,298 INFO  [stdout] (ServerService Thread Pool -- 197)  =========|_|==============|___/=/_/_/_/
23:27:13,298 INFO  [stdout] (ServerService Thread Pool -- 197)  :: Spring Boot ::        (v2.1.4.RELEASE)
23:27:13,298 INFO  [stdout] (ServerService Thread Pool -- 197) 
23:27:13,392 INFO  [stdout] (ServerService Thread Pool -- 197) 2019-09-21 23:27:13.391  INFO 21452 --- [ead Pool -- 197] c.s.s.simpleservice.ServletInitializer   : Starting ServletInitializer on kubemaster with PID 21452 (started by root in /root/wildfly13/bin)
23:27:13,393 INFO  [stdout] (ServerService Thread Pool -- 197) 2019-09-21 23:27:13.393  INFO 21452 --- [ead Pool -- 197] c.s.s.simpleservice.ServletInitializer   : No active profile set, falling back to default profiles: default
23:27:13,962 INFO  [io.undertow.servlet] (ServerService Thread Pool -- 197) Initializing Spring embedded WebApplicationContext
23:27:13,963 INFO  [stdout] (ServerService Thread Pool -- 197) 2019-09-21 23:27:13.962  INFO 21452 --- [ead Pool -- 197] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 540 ms
23:27:14,347 INFO  [stdout] (ServerService Thread Pool -- 197) 2019-09-21 23:27:14.347  INFO 21452 --- [ead Pool -- 197] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
23:27:14,473 INFO  [stdout] (ServerService Thread Pool -- 197) 2019-09-21 23:27:14.473  INFO 21452 --- [ead Pool -- 197] c.s.s.simpleservice.ServletInitializer   : Started ServletInitializer in 1.485 seconds (JVM running for 7204.339)
23:27:14,477 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (ServerService Thread Pool -- 197) Initializing Mojarra 2.2.13.SP5  for context ''
23:27:14,836 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 197) WFLYUT0021: Registered web context: '/' for server 'default-server'
23:27:14,853 INFO  [org.jboss.as.server] (management-handler-thread - 5) WFLYSRV0016: Replaced deployment "template.war" with deployment "template.war"
23:27:14,853 INFO  [org.jboss.as.repository] (management-handler-thread - 5) WFLYDR0002: Content removed from location /root/wildfly13/standalone/data/content/ee/3575321e2d9c06128d1e6dc97bd80ae8bf7be8/content

위와 같은 로그가 자동으로 출력되며, Application Deploy가 수행되는 것을 확인할 수 있습니다.

실제로 mvn -f deploy.xml wildfly:deploy-only 명령이 수행되면, WildFly standalone.xml 파일에 deployments가 자동으로 추가됩니다.

    <deployments>
        <deployment name="template.war" runtime-name="template.war">
            <content sha1="366853aa21ad1c45bba9718274d978033ff4c504"/>
        </deployment>
    </deployments>

정상 디플로이까지 확인되면 이제 배포한 페이지가 정상 호출되지는 확인해 보도록 하겠습니다.

위와 같이 정상 호출되는 것을 확인할 수 있습니다.

지금까지 살펴본 CI/CD의 동작이 어떻게 흘러가는지 다시한번 되짚어보겠습니다.

1) Jenkins FreeStyle Project 생성

2) Jenkins에서 GitHub Repository와 연결하여 소스 pull

3) Jenkins에서 Maven Build를 통한 Git 소스 clean & package

4) Jenkins에서 WildFly와 연동

5) Jenkins에서 WildFly에 Packaging 된 Archive 파일을 Delivery & Deploy

6) WildFly에서 config file 및 log file 확인

7) 변경된 페이지 호출 확인

 

지금까지 Jenkins를 통해 GitHub & Jenkins & WildFly CI/CD 구성 방안에 대해 살펴보았습니다.

 

# TIP

Jenkins Project를 여러개 생성해야 할 경우 Jenkins에서는 Project를 복제하는 기능을 제공합니다.

앞서 생성한 WildFly_Deploy_Job과 비슷한 형태의 JEUS_Deploy_Job을 생성하고 할 경우 다음과 같이 Copy From을 이용할 수 있습니다.

하단의 Copy From에 복제할 기존 Project 이름을 입력하면 다음과 같이 간단히 JEUS_Deploy_Job을 생성할 수 있습니다.

기존 WildFly_Deploy_Job의 설정이 그대로 포함되어 있으니 수정할 사항에 맞게 수정 후 

이를 활용하기 위해 Template 형태의 Base Project를 생성해 두고 신규 프로젝트를 생성해야 할 경우 복제 후 수정하는 방식을 추천드립니다.

 

포스팅이 도움이 되셨다면 아래 하트♥공감 버튼을 꾹 눌러주세요!

 

728x90
반응형