엔지니어링/CI-CD

[TmaxSoft] Jeus Webtob 도커 이미지 연동하기

joon95 2022. 12. 30. 12:24
반응형

이번에 on-prem을 MSA 클라우드 전환 프로젝트 PoC를 준비하며

Tmaxsoft 사의 Jeus, Webtob를 컨테이너로 옮기는 작업이 필요했다.

 

필자는 다른 프로젝트를 진행해오면서 React, Vue, Angluer 등의 스크립트언어를 통해

front-end 와 back-end가 명확히 분리된 환경으로 컨테이너를 구성해 왔다.

 

기존의 Web->WAS 구조는 대학생 때 apache mod_jk를 통한 tomcat 연동을 해보았고,

이번기회에 Webtob와 Jeus 연동테스트를 진행하려한다.

 

Base Image

먼저 Tmax에서 제공하는 이미지를 확인해보니 두 이미지 모두 tmaxsoftofficial 유저에 의해 2년전에 배포가 되어있었다.

2022.12.30 기준으로 가장 마지막 태그 정보는 아래와 같다.

docker pull tmaxsoftofficial/jeus:8.1.105067.1-jdk8-openjdk-ubuntu
docker pull tmaxsoftofficial/webtob:5.0.0.2.217.41.3.2

각 컨테이너 이미지를 기동시켜서 버전을 확인해보았다.

- Webtob 5.0 SP 0 Fix #2

- Jeus 8 Fix#1

 

Webtob

이제 웹서버 역할을 하는 Webtob부터 설정해보자.

여기서는 정적리소스와 jeus 연동을 위한 JSV 설정이 필요하며, 

webtob의 설정파일은 config 폴더 하위에 http.m을 기술한다.

컨텍스트경로설정

최초 파일을 보면 examples 로 설정되어있는데 '/' 로 변경하자.

*URI

*URI
uri             Uri = "/",   Svrtype = JSV

정적리소스

*EXT 절

http.m 파일은 *설정명칭 으로 구분되는데, 확장자에 따라 아래의 *EXT 내용을 추가해준다.

*EXT
htm             MimeType = "text/html", SvrType = HTML
html            MimeType = "text/html", SvrType = HTML
jsp             Mimetype = "application/jsp",  Svrtype=JSV
gif             MimeType = "image/gif", SvrType = HTML
jpeg            MimeType = "image/jpeg", SvrType = HTML
jpg             MimeType = "image/jpeg", SvrType = HTML
js              MimeType = "application/x-javascript", SvrType = HTML
css             MimeType = "text/css", SvrType = HTML
swf             MimeType = "application/octet-stream", SvrType = HTML
hwp             MimeType = "application/octet-stream", SvrType = HTML
doc             MimeType = "application/msword", SvrType = HTML
ppt             MimeType = "application/vns.ms-powerpoint", SvrType = HTML

*NODE 절

다음은 위에서 설정한 EXT에 대한 우선순위 'ServiceOrder' 항목을 추가한다.

*NODE
webtob1	        ...,
                ServiceOrder="ext,uri"

JSV

Webtob 에서 말하는 JSV는 Jeus와 연결하기 위한 옵션이다.

여기서 기존과 약간 다른 방식을 확인할 수 있었는데, apache-tomcat 구조에서는 mod_jk를 통한 web서버가 was를 바라연결하는 구조였다면 webtob는 jsvport를 listener로 열어두고 jeus가 연결하는 구조이다. 이는 webtob를 DMZ구간에서, jeus를 internal 망에서 운용할 경우 보안적 이점(out-bound)을 가져갈 수 있다.

*NODE 절

Jeus서버에서 접근할 포트를 지정한다. 

*NODE
webtob1	        ...,
                JSVPORT=9900

*SVRGROUP 절

*SVRGROUP
jsvg            SVRTYPE = JSV

base image에 기본적으로 추가되어있다.

*SERVER 절

여기서 지정한 이름은 Jeus에서 똑같이 적어주어야한다(MyGroup)

적당히 프로세스 수량을 지정해 주자.

*SERVER
MyGroup         SVGNAME = jsvg, MinProc = 2, MaxProc = 1000, ASQCount = 1

MinProc : 웹 컨테이너와 최소 연결 개수

MaxProc : 웹 컨테이너와 최대 연결 개수

이 개수는 Jeus 환경 파일 중 <webtob-listener> 하위 <thread-pool> 설정값과 각각 일치하거나 커야 한다.

 

완성된 http.m

*DOMAIN
webtob


*NODE
webtob1         WEBTOBDIR="$WEBTOB_HOME",
                SHMKEY = 54000,
                DOCROOT="docs",
                PORT = "80",
                HTH = 1,
                #Group = "nobody",
                #User = "nobody",
                NODENAME = "$NODENAME",
                ERRORDOCUMENT = "503",
                #Options="IgnoreExpect100Continue",
                JSVPORT = 9900,
                LOGGING = "log1",
                ERRORLOG = "log2",
                SYSLOG = "syslog",
                ServiceOrder="ext,uri"

*HTH_THREAD
hth_worker
                  SendfileThreads = 4,
                  AccessLogThread = Y,
                  #ReadBufSize=1048576, #1M
                  #HtmlsCompression="text/html",
                  #SendfileThreshold=32768,
                  WorkerThreads=8

*SVRGROUP
htmlg           SVRTYPE = HTML
jsvg            SVRTYPE = JSV

*SERVER
MyGroup         SVGNAME = jsvg, MinProc = 2, MaxProc = 1000, ASQCount = 1


*URI
uri             Uri = "/",   Svrtype = JSV

*LOGGING
syslog          Format = "SYSLOG", FileName = "log/system.log_%M%%D%%Y%",
                        Option = "sync"
log1            Format = "DEFAULT", FileName = "log/access.log_%M%%D%%Y%",
                        Option = "sync"
log2            Format = "ERROR", FileName = "log/error.log_%M%%D%%Y%",
                        Option = "sync"

*ERRORDOCUMENT
503                     status = 503,
                        url = "/503.html"


*EXT
htm             MimeType = "text/html", SvrType = HTML
html            MimeType = "text/html", SvrType = HTML
jsp             Mimetype = "application/jsp",  Svrtype=JSV
gif             MimeType = "image/gif", SvrType = HTML
jpeg            MimeType = "image/jpeg", SvrType = HTML
jpg             MimeType = "image/jpeg", SvrType = HTML
js              MimeType = "application/x-javascript", SvrType = HTML
css             MimeType = "text/css", SvrType = HTML
swf             MimeType = "application/octet-stream", SvrType = HTML
hwp             MimeType = "application/octet-stream", SvrType = HTML
doc             MimeType = "application/msword", SvrType = HTML
ppt             MimeType = "application/vns.ms-powerpoint", SvrType = HTML

여기서 몇가지 확인해 볼 사항은

- DOCROOT : 리소스 제공 기본 경로

- PORT : webtob listener 포트

- LOGGING : 로그 파일 설정 정보

 

이제 기본적인 설정파일은 끝났다.

Dockerfile

웹사이트에서 사용할 정적리소스 파일, 내가 설정한 http.m 파일을 넣어주면 끝난다.

추가로 yum 을 통해 디버깅에 필요한 패키지를 설치할 수 있다. 

FROM tmaxsoftofficial/webtob:5.0.0.2.217.41.3.2

RUN yum update
RUN yum install -y vim net-tools curl

COPY ./styles /home/webtob/docs/
COPY ./http.m /home/webtob/config/http.m

docker build & run

현재 작업한 위치의 파일리스트

도커이미지를 생성하고, 서비스포트 80과 jsv포트 9900을 포트포워딩 해주자.

docker build -t webtob-my:0.1 .
docker run -d -p 80:80 -p 9900:9900 --name webtob webtob-my:0.1
docker logs -f webtob

 

Jeus

Jeus(제우스)는 티맥스소프트에서 제공하는 유료 와스(WAS) 이다.

 

신입사원 때 WebSphere를 1달정도 사수를 따라다니며 유지보수를 했던 기억이 있는데, 유료 Was 솔루션들은 모두 비슷한 포맷으로 운용되는 것 같다. 당시에도 WebSphere 내부에서 서버/애플리케이션 등의 개념으로 여러 서비스를 올리기 위해 분리해둔 개념이 있었고, 제우스도 관리서버, 노드서버, 매니지드서버의 명칭으로 사용되고 있었다.

 

참고로 제우스에는 자체적으로 웹서버가 있다고 하지만, 결국 성능적 최적화를 위해 별도의 웹서버 분리를 지향한다.

 

클라우드 아키텍처

먼저 TmaxSoft에서 제공하고 있는 클라우드 환경에서의 아키텍처를 보자. 

Jeus 클라우드 아키텍처

DAS(Domain Admin Server)라 불리는 관리서버가 각각의 애플리케이션인 매니지드서버를 총 관리하고 있었는데,

독립적인 os를 가지는 클라우드환경에서의 오토 스케일링 때문에 관리서버가 필요없게 되었고, 이로인해 모든 도메인은 별도 네이밍으로 운영되야한다.

 

기동 프로세스 분석

jeus 컨테이너를 기동한 뒤 ps -ef 로 프로세스를 분석해보았다.

{homeDirectory}/script/start.sh 를 실행하는데,

이때 env.sh을 실행해 시스템변수들을 체크하여 domain.xml 파일의 내용을 변경한다.

그리고 /root/jeus8/bin/startCloudServer 파일을 실행하여 서비스를 기동하게 된다.

 

위 내용을 기준으로 우리가 해야할 작업은 아래와 같다.

- 첫번째, 환경변수를 세팅

- 두번째, domain.xml 에 webtob 연동내용 삽입

- 세번째, domain.xml 에 배포할 애플리케이션 정보

 

환경변수세팅

프로세스 분석 시 env.sh 을 보았는데 아래내용을 참고해보자.

#!/bin/bash

export PATH="$JEUS_HOME/bin:$JEUS_HOME/lib:$PATH"

# JEUS properties option(ex: -Djeus.scf.group-id=prozone-1 #######
ADD_START_OPT="${ADD_START_OPT}"
export ADD_START_OPT

# Set SCF ID NAME ################################################
if [ -z $SCF_ID ]; then SCF_ID="prozone-1"; fi
SCF_GROUP_ID="-Djeus.scf.group-id=${SCF_ID}"
export SCF_ID
export SCF_GROUP_ID
##################################################################

# Set JVM-Option #################################################
export JAVA_VM_PROPERTIES="${JAVA_VM_PROPERTIES} -Xms1024m -Xmx1024m "
##################################################################

# DOMAIN ID set ##################################################
#BASE_ADDRESS=`grep "${HOSTNAME}" /etc/hosts | awk '{print $1}'`
if [ -z $BASE_ADDRESS ]; then export BASE_ADDRESS=0.0.0.0; fi
sed -i "s/%BASE_ADDRESS%/${BASE_ADDRESS}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $SERVERNAME ]; then export SERVERNAME=`hostname`; fi
sed -i "s/%SERVERNAME%/${SERVERNAME}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $BASE_PORT ]; then export BASE_PORT=9736; fi
sed -i "s/%BASE_PORT%/${BASE_PORT}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $HTTP_PORT ]; then export HTTP_PORT=8080; fi
sed -i "s/%HTTP_PORT%/${HTTP_PORT}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $HTTP_THREAD_MIN ]; then export HTTP_THREAD_MIN=10; fi
sed -i "s/%HTTP_THREAD_MIN%/${HTTP_THREAD_MIN}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $HTTP_THREAD_MAX ]; then export HTTP_THREAD_MAX=20; fi
sed -i "s/%HTTP_THREAD_MAX%/${HTTP_THREAD_MAX}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $APP_DIR ]; then export APP_DIR="${INSTALL_HOME}/app"; fi
sed -i "s+%APP_DIR%+${APP_DIR}+g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $APP_NAME_1 ]; then export APP_NAME_1=examples; fi
sed -i "s/%APP_NAME_1%/${APP_NAME_1}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $APPLICATION_PATH_1 ]; then export APPLICATION_PATH_1=examples.ear; fi
sed -i "s/%APPLICATION_PATH_1%/${APPLICATION_PATH_1}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $APP_TYPE_1 ]; then export APP_TYPE_1=EAR; fi
sed -i "s/%APP_TYPE_1%/${APP_TYPE_1}/g" ${DOMAIN_HOME}/config/domain.xml

if [ -z $NODE_JAVA_1 ]; then export NODE_JAVA_1=false; fi
sed -i "s/%NODE_JAVA_1%/${NODE_JAVA_1}/g" ${DOMAIN_HOME}/config/domain.xml

# JEUS admin IP/PW
if [ -z $JEUS_USER ]; then export JEUS_USER=jeus; fi
if [ -z $PASSWORD ]; then export PASSWORD=jeus; fi

내용은 아주 쉬웠다. 환경변수가 없으면 default 값을 세팅하고 domain.xml에 문자열을 치환하는 것.

필자는 여기서 애플리케이션 정보 관련 정보를 docker run 에서 넣어줄 것이다.

- APP_NAME_1

- APPLICATION_PATH_1

- APP_TYPE_1

 

domain.xml

해당 파일의 위치는 /root/jeus8/domains/domain1/config/domain.xml 이다.

스크립트가 돌기전 파일을 추출하기 위해 sleep 명령어를 준 상태로 이미지를 기동하여 파일을 가져왔다.

 

Webtob Listener

이제 단순한 xml 작업인데, jeus domain.xml 을 검색해보면 어떤 태그가 존재하는지 설명이 나오니 참고바란다.

servers>server>web-engine 태그 하위에 webtob-connector 라는 태그를 작성하여 webtob 에서 설정한 jsv에 관한 내용을 작성할 것이다. (필자는 DAS화면에서 직접 webtob-connector를 만들어 생성된 xml을 이용하였다)

               <webtob-connector>
                  <name>my-webtob</name>
                  <postdata-read-timeout>30000</postdata-read-timeout>
                  <max-post-size>-1</max-post-size>
                  <max-parameter-count>-1</max-parameter-count>
                  <max-header-count>-1</max-header-count>
                  <max-header-size>-1</max-header-size>
                  <max-querystring-size>8192</max-querystring-size>
                  <wjp-version>2</wjp-version>
                  <registration-id>MyGroup</registration-id>
                  <network-address>
                     <port>9900</port>
                     <ip-address>20.41.116.235</ip-address>
                  </network-address>
                  <thread-pool>
                     <number>1000</number>
                     <thread-state-notify>
                        <max-thread-active-time>0</max-thread-active-time>
                        <interrupt-thread>false</interrupt-thread>
                        <active-timeout-notification>false</active-timeout-notification>
                        <notify-threshold-ratio>0.0</notify-threshold-ratio>
                        <restart-threshold-ratio>0.0</restart-threshold-ratio>
                     </thread-state-notify>
                  </thread-pool>
                  <hth-count>1</hth-count>
                  <request-prefetch>false</request-prefetch>
                  <read-timeout>120000</read-timeout>
                  <reconnect-interval>5000</reconnect-interval>
                  <reconnect-count-for-backup>12</reconnect-count-for-backup>
               </webtob-connector>

webtob *SERVER에 정의 하였던 MyGroup 을 registration-id 태그에 넣어주고,

접근 포트와 webtob ip를 작성해주면 완성된다.

deployed-application

이부분은 기본적으로 시스템변수로 변경이 되는데,

배포되는 애플리케이션의 root context가 기본으로 /{app name}으로 설정되어 '/' 로 변경하는 태그를 넣어주었다.

    <deployed-applications>
        <deployed-application>
        	...
            <context-path>/</context-path>
            ...
        </deployed-application>
    </deployed-applications>

Dockerfile

FROM tmaxsoftofficial/jeus:8.1.105067.1-jdk8-openjdk-ubuntu

RUN apt update
RUN apt install -y vim net-tools curl

COPY ./web-0.0.1-SNAPSHOT.war /root/app
COPY ./new-domain.xml /root/jeus8/domains/domain1/config/domain.xml

필요한 패키지를 apt install을 통해 다운하고,

배포할 애플리케이션을 deploy 경로에, 작성한 domain.xml 파일을 복사한다.

docker build & run

Jeus 작업디렉토리 파일정보

docker build -t jeus-my:0.1
docker run -d  -p 8080:8080 -p 9736:9736 \
 -e APP_NAME_1=web-0.0.1-SNAPSHOT \
 -e APPLICATION_PATH_1=web-0.0.1-SNAPSHOT.war \
 -e APP_TYPE_1=WAR \
 --name jeus-my jeus-my:0.1

docker logs –f jeus-my

9736 포트는 admin 콘솔인데 UI로 확인차 열어주었고, 앞서말한 환경변수를 다음과 같이 세팅해주었다.

 

테스트

이제 모든 설정이 완료되었다

webtob 80 port '/'로 접근하면 jsv 설정을 따라 jeus서비스를 연결하여 webtob를 통해 client가 응답을 받게 된다.

이 때 webtob access log를 확인하면 아래와 같이 .css 파일은 webtob로 요청이 오게된다.

확실한 테스트를 위해 해당 파일을 없애도 보고(Status Code 404)

해당파일 내용을 변경해가며 페이지 스타일의 변경을 확인하였다.

 

마치며

전통적인 3Tier 구조는 MSA 아키텍처가 생기며 점차 사용하지 않고 관심도 없었는데, 아직도 3Tier 구조를 사용하는 수많은 기업들이 남아있다. 뭐 고객사는 대부분 UNIX 빵빵한 서버에 WEB-WAS로 거의죽지않는 서비스를 하고있으니, ㅋㅋㅋ 그리고 대고객서비스가 아닌 이용자가 많지 않은 서비스는 필요가 없겠지만... 그래도 난 컨테이너화된 쿠버네티스가 너무 재밌고 좋다. 

추가로 WAS에서 db connection을 관리하는 설정도 있는데 커뮤니케이션이 어떻게 될지 모르겠으나 나중에 해봐야겠다.

반응형