<최종>도커라이징 & CI/CD

bob_ssso·2021년 7월 8일
0

CI/CD

목록 보기
9/10

두 개의 서버(Jenkins. WAS)에서 사용하는 프로그램들을 모두 도커로 설치하고 웹 애플리케이션 또한 도커파일을 통해 이미지를 만든 후 컨테이너를 실행시킴으로써 구축한다.


🥸 젠킨스 서버 준비

1. 젠킨스 설치 by Docker

$ sudo docker pull jenkins/jenkins:lts
$ docker run -d -p 8181:8080 -v /var/jenkins_home:/var/jenkins_home -v /root/.ssh:/root/.ssh --name jenkins -u root jenkins/jenkins:lts

바인드 마운트
추후 파이프라인에서 키파일 경로를 참조해서 ssh연결을 하는데 이 .ssh 폴더를 젠킨스가 참조할 수 있도록 서버의 /root/.ssh 폴더와 젠킨스 컨테이너의 /root/.ssh 폴더를 바인드 마운트 해주었다. 이 ssh 가 연결 안되어서 진짜 며칠을 고생했다.

2. 깃랩 설치 by Docker

3. 젠킨스 슬랙 연동

4. 젠킨스 깃랩 연동

5. 젠킨스에서 파이프라인 프로젝트 만들기

파이프라인 내용은 비워두거나 임의의 파이프라인 스크립트를 집어넣자.


🥸 WAS 서버 준비

1. 오라클 설치 by Docker

A. 오라클 설치 후 테이블 생성하기

B. DB에 더미 데이터 추가하기

(주의사항) 두개의 테이블에 공통된 컬럼 patientlocnum 부분은 무조건 4자리의 정수여야 한다.

C. 깃랩의 ConnectDB.java 파일 수정

도커라이즈를 함으로써 톰캣도 컨테이너로 구동되기에 기존의 localhost(127.0.0.1)로는 오라클을 인식할 수 없다. 초록색 부분을 외부IP로 수정해줘야한다.

2. 도커파일 만들기

톰캣 기반(or jre 8기반) 컨테이너를 구동시키기 위한 도커파일이 필요하다. 이때 도커파일은 WLP_re.war 파일과 같은 위치에 두어야한다.

$ touch Dockerfile
$ vim Dockerfile

리눅스의 빔 편집기로 Dockerfile을 만든다. i를 눌러 편집상태로 바꾼 후 아래 내용을 복붙한다.. 그후 esc 누르고 :wq! 눌러서 저장하긔! Dockerfile 내용은 다음과 같다.

FROM tomcat:8-jre8
RUN echo $(ls -al)
WORKDIR /usr/local/
RUN echo $(ls -al)
RUN rm -rf ./tomcat/webapps/*
COPY WLP_re.war ./tomcat/webapps/
EXPOSE 8080
CMD $CATALINA_HOME/bin/startup.sh && tail -f $CATALINA_HOME/logs/catalina.out

Dockerfile이 성공적으로 만들어졌다.


🥸 서버 연결하기

1. 젠킨스 서버에 필요한 파일 준비하기

: WAR파일을 만들기 위해 WAS 서버에서 /usr/local/tomcat8/lib/* 의 파일들을 젠킨스 서버(/var/lib/jenkins/workspace/)로 가져온다.

: 아래 사진은 WAS 서버의 /usr/local/tomcat8/lib/* 의 파일들이다.

/var/lib/jenkins/
젠킨스 서버에 정확히 /var/lib/jenkins/라는 폴더가 없었다. 컨테이너 실행시키면 /var/lib/jenkins/workspace/이 위치는 뭘로 대체해야 하나?
: 처음 시작하는 어드민 비번 부분 보니 원래의 /var/lib/jenkins/var/jenkins_home/과 동일

A. tar파일로 압축하기

/usr/local/tomcat8/lib/* 파일들을 전송하기 쉽도록 압축한다.

(WAS서버): $ tar cvf lib.tar /usr/local/tomcat8/lib/*

B. WAS 서버에서 tar 파일 다운로드

: WAS 서버에서 위의 tar파일을 다운로드 받는다.GCP가 제공하는 ssh창에서 파일 다운로드 기능 사용.

C. 젠킨스 서버에 tar 파일 업로드

: GCP가 제공하는 ssh창에서 파일 업로드 기능 사용.

D. 업로드한 tar 파일 압축 풀기

(JENKINS)$ tar xvf  lib.tar  
(JENKINS)$ cd ~/usr/local/tomcat8 
(JENKINS)$ sudo mv lib /var/jenkins_home/workspace/

성공적으로 모든 파일이 원하는 자리에 옮겨진 것을 알 수 있다.

2. 서버들간의 ssh 연결 테스트

두 개의 서버 ssh창을 번걸아 써야하니 헷갈리지 말자!

A. 키 파일 만들기

젠킨스 컨테이너를 돌릴때의 사용자를 root로 지정해주고 볼륨시킨 디렉토리도 root 소유 이므로 사용자는 gcp 계정(psystar99)가 아닌 root여야 한다.

  • root계정으로 전환
  • root의 .ssh 폴더에 키 만들기
  • 공개키 확인 및 줄바꿈 없앤 후 내용 복사(Cmd+C)
(Jenkins 서버): $ sudo su root
(Jenkins 서버): $ ssh-keygen -t rsa -C "docjen"
(Jenkins 서버): $ cat /root/.ssh/id_rsa.pub

키 값 내용 복사
GCP에서 제공하는 ssh 창에서 키 내용을 복사한 후 바로 붙여넣기를 하면 아래와 같이 한 줄마다 줄바꿈이 되어 GCP가 해당 내용을 키값으로 인식을 못한다.위의 칸은 정상적인 키값의 상태이고 아래는 복사한 후 바로 붙여넣기 한 결과이다.
따라서 복사한 키값을 메모장이나 어딘가에서 줄바꿈을 일일이 다 없앤 후 WAS 서버에 키 값을 등록해야한다.

B. 키 등록하기

(WAS 서버): $ cat >> ~/.ssh/authorized_keys 

해당 명령어를 치면 WAS 파일의 키의 목록들이 나온다.

  • 위에서 복사한 공개키의 내용을 붙여 넣고(Cmd + V)
  • 줄바꿈(Enter)
  • 저장하기(Ctrl + D )

키 등록방법
키 등록시 해당 방법과 gcp 홈페이지의 메타데이터로 .ssh키를 등록하는 방법이 있는데 후자의 방법은 보안이 빡세서인지(?) 키 파일 경로 표시 안해주면 ssh 접속 안된다.
우리가 한 방법은, 처음 접속할 떄 키파일 지정만 해주면, 추후에는 키파일을 지정 안해도 ssh, scp 연결이 된다.

C. ssh 연결하기

젠킨스 서버에서 ssh 명령어를 통해 WAS 서버에 접속해 본다. 성공적으로 진행되면 ssh창 왼쪽의 '사용자@서버IP'가 바뀌는 것을 볼 수 있다.

(Jenkins 서버): $ ssh -i /root/.ssh/id_rsa WAS서버_아이디@WAS서버_IP 

3. WAR 파일 만들고 위치시키기

A. Jenkins 서버에서 WAR파일 만들기

  • 방법 1. 직접 명령어를 실행하기
    명령어로 WAR파일 만든다. 파이프라인에 있는 명령어와 동일하다.
$ mkdir -p ./WebContent/WEB-INF/classes/; \

            javac \

            -Xlint:unchecked \

            -d ./WebContent/WEB-INF/classes/ \

            -cp ./WebContent/WEB-INF/lib/*:/var/lib/jenkins/workspace/lib/* \

            ./src/user/*.java;

            cd ./WebContent; jar cvf ./WLP_re.war *;
  • 방법 2. 파이프라인 실행하기
    • 4의 파이프라인을 복붙한 다음 푸시이벤트를 줘 젠킨스가 깃랩 리포지토리에 있는 파일을 빌드하도록 한다. 하지만 실행되는 톰캣 컨테이너가 없기에 무조건 오류난다.
    • 빌드 오류가 나지만 결과적으로 /var/jenkins_home/workspace/doc-project/WebContent/에 WLP_re.war 파일이
      생성된다.

B. WAR 파일 위치시키기

  • Jenkins 서버에서 만든 WAR파일을 다운로드 받는다.
  • WAS 서버의 디렉토리 ~/에 WAR 파일을 업로드한다.

C. 도커파일로 이미지 만들기

WAR파일이 준비되었으니 앞에서 만든 도커파일로 이미지를 만든다.

(WAS 서버): $ docker build --no-cache -t wlp:latest ./

D. 도커 컨테이너 실행시키기

C에서 만든 도커 이미지로 컨테이너를 실행시킨다.

(WAS 서버): $ docker run -d --publish 8080:8080 --name wpl_tomcat wlp:latest

파이프 라인 코드는wpl_tomcat이라는 컨테이너가 있는 가정하에 동작되므로 첫 시행 전에 이미지와 컨테이너를 미리 만든다.

4. 파이프 라인 작성(Scripted 방식)

node {

    def hello = 'Hello soso' // 변수선언

    stage ('Init'){
        sh 'rm -rf ./*'
    }


    stage ('Clone') {
        git 'http://root:seCJriGN_ZjgQK8RhxpF@젠킨스아이피:8080/root/doc-wpl.git' // git clone
    }

    

    stage ('Build') {
         try {
        notifySlack('STARTED')

        // Existing build steps.

            sh '''mkdir -p ./WebContent/WEB-INF/classes/; \

            javac \

            -Xlint:unchecked \

            -d ./WebContent/WEB-INF/classes/ \

            -cp ./WebContent/WEB-INF/lib/*:/var/lib/jenkins/workspace/lib/* \

            ./src/user/*.java;

            cd ./WebContent; jar cvf ./WLP_re.war *;\

            scp -i /root/.ssh/id_rsa WLP_re.war soyoung99_park@WAS아이피:/home/soyoung99_park/; \

            TOM=$(ssh -i /root/.ssh/id_rsa soyoung99_park@WAS아이피 "docker container ls -q --filter name=wpl_tomcat");\

            ssh -i /root/.ssh/id_rsa soyoung99_park@WAS아이피 "docker container stop" $TOM;\

            ssh -i /root/.ssh/id_rsa soyoung99_park@WAS아이피 "docker container rm" $TOM;\

            ssh -i /root/.ssh/id_rsa soyoung99_park@WAS아이피 "docker rmi wlp";\

            ssh -i /root/.ssh/id_rsa soyoung99_park@WAS아이피 "docker build --no-cache -t wlp:latest ./"; \

            ssh -i /root/.ssh/id_rsa soyoung99_parkWAS아이피 "docker run -d --publish 8080:8080 --name wpl_tomcat wlp:latest";

            '''

        } catch (e) {
        currentBuild.result = 'FAILURE'
        throw e
        } finally {
        notifySlack(currentBuild.result)
        }
    }

    stage ('print') {
        print(hello) // 함수 + 변수 사용
    }
}

// 함수 선언 (반환 타입이 없기 때문에 void로 선언, 있다면 def로 선언하면 됨)

void print(message) {
    echo "${message}"
}


def notifySlack(String buildStatus = 'STARTED') {

    // Build status of null means success.

    buildStatus = buildStatus ?: 'SUCCESS'
    def color
    if (buildStatus == 'STARTED') {
        color = '#D4DADF'
    } else if (buildStatus == 'SUCCESS') {
        color = '#3bad46'
    } else if (buildStatus == 'UNSTABLE') {
        color = '#FFFE89'
    } else {
        color = '#FF9FA1'
    }

    def msg = "${buildStatus}: `${env.JOB_NAME}` #${env.BUILD_NUMBER}:\n${env.BUILD_URL}"

    slackSend(color: color, message: msg)

}

🥸 결과

깃랩에 푸시 이벤트를 날리면(웹훅 push 이벤트 또는 cmd에서 git 명령어로 push) 젠킨스에서 빌드가 시작되고 성공적으로 빌드가 되었다는 알람을 볼 수 있다.


파이프라인 작성 참고 링크

profile
밥소🐈

0개의 댓글