티스토리 뷰

개발

Jenkins로 원격지 API 서버에 war 배포하기

노랑머플러 2016. 7. 26. 23:45

개인적인 오픈소스 프로젝트 개발을 진행하면서 경험한 내용과 느낌을 간단하게 정리해보기로 했습니다. 현재 github(https://github.com/Pyohwan/JakduK)에 소스 코드가 올라가 있습니다. 또한 K리그 작두왕(https://jakduk.com)이 이 소스 코드로 돌아가는 것입니다.


현재 K리그 작두왕의 빌드 및 배포는 Jenkins를 통해서 이루어지고 있습니다. 빌드 및 배포를 수행하는 대상은 4곳인데요.

스테이징과 프로덕션으로 크게 나뉘어 집니다. 또한 RESTful만 담당하는 API 서버와, 웹쪽 렌더링을 담당하는 WEB 서버가 있습니다.


이번 글에서는 Jenkins로 빌드하고 원격지(프로덕션)에 배포하는 방법을 써볼까 합니다.


먼저 Jenkins가 설치된 서버가 있어야 합니다. 저는 Centos 6 서버에 rpm으로 Jenkins를 쉽게 설치했습니다. Jenkins 설치에 대해서는 구글에서 검색해보면 많이 나오니 생략하겠습니다.



JAKDUK Jenkins URL입니다. 물론 계정 정보가 있어야 접속할 수 있습니다.




현재 3개의 아이템이 등록되어 있습니다.


JAKDUK_API_Production 아이템의 Build with Parameters를 선택합니다.


TASK_TYPE에는 각각 build, bowerInstall, deply가 있습니다.





JAKDUK_API_Production 아이템의 구성을 살펴볼께요.


Repositories 설정은 Github에 있는 JAKDUK Repository URL를 사용하고 있고, 빌드에 사용할 branch를 설정해 줍니다.



빌드 환경이 중요합니다.

Execute shell을 선택하고, TASK_TYPE에 맞는 행동을 수행하도록 쉘 명령어를 사용했습니다.


WORK="/var/lib/jenkins/workspace"



if [ "$TASK_TYPE" == "build" ]; then

$WORK/JakduK_build/gradlew clean test build

elif [ "$TASK_TYPE" == "bowerInstall" ]; then

$WORK/JakduK_build/gradlew bowerInstall

elif [ "$TASK_TYPE" == "deploy" ]; then

SVR="172.30.1.33"

ssh jakduk@$SVR "sudo systemctl stop tomcat"

    ssh jakduk@$SVR "sudo rm -rf /usr/local/tomcat/webapps/ROOT"

    scp $WORK/JakduK_build/jakduk-web/build/libs/*.war tomcat@$SVR:/usr/local/tomcat/webapps/ROOT.war

    ssh jakduk@$SVR "sudo systemctl start tomcat"

fi



build TASK를 선택하면 gradlew로 test build를 수행하고, bowerInstall TASK를 선택하면 자바스크립트의 의존 라이브러리를 해결해주는 bower 툴을 실행합니다. (이부분은 RESTful 서버로 완전히 분리되면 사라질 예정이고, bowerInstall에 대한 부분은 https://github.com/JakduK/JakduK/blob/master/jakduk-web/build.gradle#L28 를 참고)

deploy TASK를 선택하면, 원격지(172.30.1.33)의 tomcat을 중지 하고, 빌드한 war를 이동 시킨 다음에 다시 tomcat을 시작합니다.


하지만 ssh나 scp를 통해 원격지 머신을 컨트롤 하기 위해서는 권한 문제를 해결해야 합니다. deploy TASK를 다시 한번 살펴보면 ssh 시에는 jakduk 유저를 사용하여 sudo 명령어를 수행하고, scp를 할때에는 tomcat 유저로 수행하는것을 볼 수 있습니다.


  1. Jenkins를 별도의 유저(jakduk)로 실행할것. 
  2. Jenkins에서 원격지(172.30.1.33)으로 암호 입력 없이 ssh 수행이 가능할것.


위 두가지를 해결해야만 Jenkins에서 원격지로 war를 배포할 수 있습니다.


Jenkins를 별도의 유저(jakduk)로 실행

Jenkins가 yum install을 통해 설치 되었다면 Jenkins는 기본적으로 jenkins 유저를 하나 만들고, jenkins 유저로 실행하게 됩니다. 하지만 jenkins유저는 nologin 설정이 있기 때문에, 로그인 할수 없는 유저입니다. 원격지의 자원을 마음대로 조정하기 위해서는 jenkins 유저의 공개키가 필요한데, 로그인을 할수 없으니 만들수가 없습니다. 따라서 jakduk유저를 새로 만들었습니다. 


useradd 명령어로 jakduk 유저를 만듭니다.


# useradd jakduk



JAKDUK Jenkins 서버에서 /etc/sysconfig/jenkins 파일을 열어봅니다.


## Type:        string

## Default:     "jenkins"

## ServiceRestart: jenkins

#

# Unix user account that runs the Jenkins daemon

# Be careful when you change this, as you need to update

# permissions of $JENKINS_HOME and /var/log/jenkins.

#

JENKINS_USER="jakduk"



위 JENKINS_USER의 값을 jakduk로 수정하고, jenkins를 재시작합니다.

Jenkins에서 원격지(172.30.1.33)으로 암호 입력 없이 ssh 수행

먼저 Jenkins 서버의 jakduk 유저의 공개키와 비밀키를 생성해야 합니다.

먼저 jakduk 유저로 바꾸고, ssh-keygen으로 키를 생성합니다.


# su - jakduk

# ssh-keygen


.ssh 디렉토리가 생성되고 ls 명령어로 확인해보면 키를 확인할 수 있습니다.


[jakduk@localhost .ssh]$ ll

합계 16

-rw-rw-r--. 1 jakduk jakduk  410 2016-07-26 00:30 authorized_keys

-rw-------. 1 jakduk jakduk 1671 2016-06-03 14:04 id_rsa

-rw-r--r--. 1 jakduk jakduk  410 2016-06-03 14:04 id_rsa.pub

-rw-r--r--. 1 jakduk jakduk 1965 2016-07-26 00:17 known_hosts


이제 id_rsa.pub를 원격지(172.30.1.33)에 넣어주면 됩니다.


원격지에 터미널로 접속하여, useradd 명령어로 jakduk, tomcat 유저를 생성합니다. 굳이 2개의 유저를 생성한 이유는 역할을 분리하기 위해서입니다. jakduk 유저는 systemctl 명령어와 rm 명령어만 사용하기 위함이고, tomcat 유저는 tomcat만 담당하기 위해서입니다.


먼저 jakduk 유저로 변경하고 .ssh 디렉토리를 생성합니다.


# mkdir .ssh


.ssh 로 이동하고나서 authorized_keys를 생성합니다. 이 파일 안에 Jenkins의 jakduk유저 공개키를 넣어줍니다. 그리고 나서 권한을 바꿔주세요.


# chmod 600 authorized_keys


이작업을 tomcat 유저도 동일하게 해주면 됩니다.


참고로 원격지 API 서버의 경우 Centos 7를 설치했습니다. jakduk 유저에 약간의 root 권한을 부여해보겠습니다.


[root@api ~]# cat /etc/sudoers.d/jakduk-user 

Cmnd_Alias TOMCAT = /usr/bin/systemctl * tomcat

Cmnd_Alias RM = /bin/rm


jakduk ALL=(ALL) NOPASSWD:TOMCAT,NOPASSWD:RM


jakduk 유저에게 systemctl과 rm 명령어를 비밀번호 입력없이 sudo로 사용할 수 있도록 했습니다.


또한 /etc/sudoers 파일을 수정해야 합니다. requiretty 옵션을 없애야만 Jenkins서버에서 API 서버로 명령을 날릴 수 있습니다.


#Defaults    requiretty


테스트

Jenkins 서버에서 다음의 명령어를 날려보세요. (꼭 한번은 해야 합니다. 왜냐하면 터미널로 최초 접속시 known_hosts에 등록 해야하기 때문입니다.)


[jakduk@localhost .ssh]$ ssh jakduk@172.30.1.33 "sudo systemctl stop tomcat"

[jakduk@localhost .ssh]$ ssh tomcat@172.30.1.33 "ls -al"

합계 28

drwx------. 3 tomcat tomcat 4096  7월 26 23:18 .

drwxr-xr-x. 4 root   root     32  7월 25 23:15 ..

-rw-------. 1 tomcat tomcat  504  7월 26 23:18 .bash_history

-rw-r--r--. 1 tomcat tomcat   18 11월 20  2015 .bash_logout

-rw-r--r--. 1 tomcat tomcat  193 11월 20  2015 .bash_profile

-rw-r--r--. 1 tomcat tomcat  231 11월 20  2015 .bashrc

drwx------. 2 tomcat tomcat   28  7월 26 23:09 .ssh

-rw-------. 1 tomcat tomcat 6416  7월 26 23:18 .viminfo



'개발' 카테고리의 다른 글

OpenVpn 설치  (3) 2017.05.23
Spring Security에 Spring Social 붙이기 1  (4) 2016.05.07
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday