로컬 환경에 자동배포 서버 구축하기
회사에서 서버를 구축하며, 자동배포 환경을 여러번 구축했었으나, 자세히 공부를 하지 않았던 탓에, 번번히 잊혀져만 갔습니다. (설치 과정이나, 설정이나, 처음이어서 그랬던지, 구축을 완료하고나면 진이 빠졌었습니다.)
그러던중 Docker
라는 것을 중간에 공부하게 되었고 이를 통해 jenkins
를 쉽게 구동할 수 있다는것 또한 알아내었습니다. 하지만, 사내 PC에 jenkins를 설치해봤자, github의 webhook이 닿을수 없는 사설 IP를 가지고 있는 상황이었고, 따라서 jenkins를 사내 PC에 설치해봐야, 자동배포환경을 구축할 수 없었습니다.
하지만, 또 다시 Ngrok
라는 것을 발견했고, 이를 통해 github-webhook
을 사내 PC에서 받을 수 있게 되었습니다. 이번 포스팅에서는, 로컬 PC에 docker를 이용해 jenkins를 설치하여, 원격지에 자동 배포를 하는 환경을 구성해보도록 하겠습니다.
구축 인프라 설명
저희가 구축할 환경은 위와 같습니다.
1. local server에 docker를 이용해 jenkins를 구동합니다.
2. develop server에서 code를 push합니다.
3. local server의 jenkins에서 github로부터 webhook을 받아, 이를 알아차리고 코드를 다운받고, test & build를 합니다.
4. jenkins plugin(Publish over ssh)를 이용해 배포서버에 자동으로 전달합니다.
Jenkins의 를 통해서, CI 즉, Test와 Build를 자동화 한뒤, plugin과 script를 이용해, CD 즉, 배포 자동화를 구축할 것입니다.
1. Jenkins 설치
Docker를 이용한 jenkins 서버 구동
docker와 kitematic이 설치된 환경을 가정하여 설명드리겠습니다. (docker에 대해 잘 모르신다면, 제 블로그 내의 글들을 참조해주세요. https://galid1.tistory.com/category/Infra/Docker)
kitematic을 실행합니다. 그 후, jenkins를 검색하여, jenkins/jenkins
tag의 ...
을 클릭합니다. 중요한 점은, official/jenkins
가 아닌 jenkins/jenkins
를 설치해야 한다는 점입니다. (원래라면, Recommended에 나타나는 jenkins를 설치하겠지만, 20.06.16
기준, 해당 버전이 문제가 있어서인지 설치해본결과 플러그인 설치에서 에러가 나타났습니다.)
또한, 제가 구축할 서버의 경우 jdk11
을 사용중이기 때문에, 소스 파일을 빌드하기위해, jdk11이 설치된 jenkins 컨테이너를 실행해야합니다.
상단의 SELECTED TAG:
를 클릭합니다.
그후, jdk11
을 검색하여 jdk11을 선택합니다.
CREATE
버튼을 누르면, jenkins 컨테이너 설치 완료입니다.
jenkins 설치
터미널을 열어, ~ docker ps
명령어를 통해, 실행중인 컨테이너를 확인합니다. :32773
포트에서 동작중인것을 확인할 수 있습니다.
브라우저를 열어 localhost:32773
으로 연결을 시도하면, jenkins가 보입니다. Administrator password
는 빨간색으로 표시된 경로에서 확인할 수 있습니다.
~ docker exec -it jenkins-2 bash
명령어를 이용해, 실행중인 jenkins 컨테이너에 attach하며 bash셸을 실행합니다. 그후, cat /var/jenkins_home/secrets/initialAdminPassword
을 이용하여, administrator password를 확인합니다.
다시 웹에서 비밀번호를 입력한뒤, install suggested plugins
를 클릭하여 설치를 진행합니다.
적절히 정보를 입력하고 다음다음다음 ~~ 그러면 완료입니다.
2. GitHub Repository 생성
우리의 목표를 다시 상기하자면, 특정 Repository에 commit을 push하는 경우, 해당 코드를 읽어들여, build하고 이를 실행상태로 만드는 것 입니다. 즉, 자동배포환경을 구축하는 것이죠, 이를 위해 Application Code의 형상관리가 될 Github에 repository를 생성합니다.
간단한 Spring Boot Application 작성
위와 같이, test.html을 반환하는 간단한 핸들러를 가진 Spring Boot Application을 작성합니다.
Github repository 생성
Application을 위한 git repository를 새로 생성합니다.
터미널 창을 열고, application이 존재하는 디렉토리로 이동합니다. 그후, git init
명령어를 이용해 git project로 만들어준뒤,
git add --all
을 이용하여, 모든 파일을 status에 추가합니다.
그후, git commit -m "init"
명령을 통해 커밋을 생성합니다.
git remote add origin "저장소"
를 입력해 원격 저장소를 추가합니다.
그후, git push -u origin master
를 이용해, commit을 push 합니다.
3. Github webhook 설정
github webhook
은 github에 push하는 행동을 trigger로 이용하여, 어플리케이션을 배포하던지, 다른 빌드스크립트가 실행되도록 하는 기능입니다.
Ngrok 설정
이제 해당 git repository에, push요청이 들어오는 경우, jenkins
서버에 hook을 하도록 설정해야합니다. 하지만, 우리는 로컬 PC에서, Jenkins 서버를 구동하고 있고, 때문에 외부에서 접근가능하도록 만들어 주어야합니다. 이를 위해 우리는 Ngrok
를 사용할 것입니다.
https://galid1.tistory.com/741
자세한 설명과 설치는 위의 링크를 참조해주세요.(금방입니다!)
위의 링크를 참조하여 Ngrok를 설치한 뒤, terminal을 열어 ngrok http "jenkins가 실행중인포트"
(ex. ngrok http 32773)를 입력하면. 위와 같이 jenkins에 접근 가능한 public dns가 생성됩니다. 해당 dns 주소를 복사합니다.
브라우저에서, 앞서 복사한 dns주소를 입력하면 jenkins 로그인 창이 나타나는것을 확인할 수 있습니다.
github 설정
프로젝트의 settings -> webhooks -> Add webhook
을 차례대로 클릭합니다.
그후, 앞서 생성한 public dns + /github-webhook/
을 입력한 뒤, Content type을 application/json으로 선택한 뒤, Add webhook을 클릭합니다.
jenkins item 생성
이제 github로부터 webhook을 받은 경우, jenkins 서버에서, 자동 배포를 처리할 item을 생성해야 합니다. 새로운 Item
을 클릭합니다.
item 이름을 입력한뒤 , Freestyle project
를 클릭하여 생성합니다.
소스코드관리 탭에서, git
을 선택한뒤, 앞서 생성한 repsitory의 주소를 입력합니다. Branch Specifier의 경우, 어떤 브랜치에 code push요청이 되었는지에 따라서, jenkins가 반응할지에대해 설정하는 것입니다. 우리는 master브랜치 밖에 존재하지 않기 때문에 그대로두도록 합니다.
빌드 유발 탭에서, GitHub hook trigger for GITScm polling
을 체크합니다.
Build
탭에서,Add Build Step
을 클릭한뒤,Invoke Gradle script
를 클릭합니다.- 그후,
Use Gradle Wrapper
을 클릭하여, Spring Boot의 내장 Gradle을 사용하도록 합니다. make gradlew executable
를 체크합니다. 이 기능은 gradlew를 jenkins 사용자가 실행할 수 있도록 만들어줍니다.- Wrapper location에는
${workspace}
를 입력합니다. - Tasks에는
bootJar
를 실행하여, git repository로 부터 읽어들여온 소스코드를.jar
파일로 만듭니다.
Web Hook Test
코드를 수정한뒤, 다시 github에 코드를 push합니다. 그후, jenkins를 확인하면!! 위와 같이 자동으로 build가 이루어진 내역을 볼 수 있습니다. 해당 원을 클릭하면 자세한 로그도 확인이 가능합니다.
project 위치
그렇다면, 자동으로 내려받아진 프로젝트는 어디에 위치할까요?? 우선 docker에 다시 shell을 실행하여 attach 합니다. 그 후, /var/jenkins_home/workspace/
를 확인하면, 프로젝트를 찾을 수 있습니다.
4. 원격지에 배포하기
저희는 지금, 로컬 PC
에 jenkins를 설치한 상태입니다. 따라서, git으로 부터 source코드를 받아 build한 곳이, 여러분이 사용중인 PC입니다.
하지만, 개발 PC와, Application이 실행될 서버는 별도에 위치해야겠죠? 그리고, 보통의 경우 Application을 위한 별도의 서버가 마련되어있을 것입니다.
서버 생성
저는 AWS EC2
를 이용해 서버를 생성하였습니다. (해당링크를 참조하여주세요, https://galid1.tistory.com/224) 그 다음 이 서버에 접근하기 위한 public dns를 복사해둡니다.
jdk 11 설치
$ sudo amazon-linux-extras install java-openjdk11
amazon-linux2에 jdk11을 설치합니다.
Jenkins SSH Plungin 추가하기
플러그인 관리
페이지로 이동합니다.
설치가능 탭에서, Publish Over SSH
를 검색한뒤, 해당 플러그인에 체크하고, 재시작없이 설치하기를 클릭합니다.
Jenkins Remote Server 추가하기
이제 build된 Application을 배포할 대상 서버를 jenkins에게 알려주어야 합니다. 저 같은 경우 아까 설치한 EC2 서버가 될것입니다.
Jenkins 관리 -> 시스템 설정 으로 이동합니다.
스크롤을 쭉 내리다보면, Publish over SSH
탭이 보입니다. 추가를 클릭합니다.
Hostname
에는 배포 대상 서버의 주소를 입력합니다.(public dns or IP)username
에는 대상 서버에 접속할 user를 입력합니다.- use password authentication을 체크하여, 해당 유저의 password를 통해 접근하도록 설정합니다.
- 마지막으로 Test Configuration을 클릭합니다. 그림처럼 Success가 나타난다면 성공입니다.
Jenkins Item에 Remote 배포 설정 추가하기
이제 jenkins에서 code push에 대한 web hook을 받은 후의 처리를 진행해야 합니다. build 설정을 통해 얻어낼 동작은 위와 같습니다.
다시 아까전에 생성한 Jenkins item의 Build
탭으로 이동합니다.
Add build step을 클릭하고, Send files or execute commands over SSH
를 선택합니다.
boot jar task를 이용해 build를 하는 경우, jar파일이 생성되는 위치는 PROJECT_DIR/build/libs/*.jar
이므로, Source files
에는 build/libs/*.jar
를 입력합니다.
이때, 원격 서버에 build 디렉토리가 포함되어 전달됩니다. 하지만 파일만을 전달하고 싶은 경우, Remove prefix
란에, *.jar
파일의 상위 경로(build/libs/)를 적어주면 됩니다.
기존에 실행중이던 java application을 종료하기 위해, exec command
란에 sudo pkill -f 'java -jar'
명령어를 입력합니다.
이제 전송된 java application을 실행하는 명령어를 전달하기 위해, add Trasfer Set
을 클릭한뒤, exec command
란에 sudo java -jar *.jar &
를 이용해 배포된 어플리케이션을 실행합니다.
xxxxxxxxxx
*appication 실행시, Spring boot가 포어그라운드에서 동작하는 경우, jenkins가 요청한 작업이 완료됨을 인지하지 못하여, jenkins의 배포가 계속해서 진행중으로 표시됩니다. 따라서, 백그라운드로 동작시키기 위해 꼭 실행 명령어 뒤에 `&`를 붙히시기 바랍니다.
5. TEST
코드 변경을 통해 우선, code를 push합니다. jenkins에 build가 진행됩니다. 한번 자세히 살펴보겠습니다. 우선, jenkins 컨테이너 내부의 /var/jenkins_home/workspace/cicd-test
경로에서, bootJar
가 실행됩니다.
뒤이어, 기존 실행중이던 java application을 종료하는 명령어(sudo pkill -f 'java-jar')가 실행되며, 마지막으로 배포된 java application을 실행하는(sudo java -jar &)가 실행됩니다.
이제 서버에 접속을 시도해보면, 완료입니다 !
'Software Engineering > CICD (jenkins, etc)' 카테고리의 다른 글
CICD - Jenkins와 CodeDeploy를 이용한 CICD 구축하기 - 1 (아키텍처, 과정 소개) (0) | 2020.06.23 |
---|---|
CICD - Codedeploy란? (Codedeploy를 이용한 자동배포(CD) 환경 구축하기) (1) | 2020.06.22 |
Jenkins - AmazonLinux2 에서 Jenkins 구축 및 gitlab 연동 (push 시 자동 빌드) (0) | 2019.07.12 |
CI - CI/CD 구성 - 4(GitHub Push시 자동 Jenkins Build,Test,Deploy 설정) (2) | 2019.03.25 |
CI - CI/CD 구성 - 3 (Jenkins GitHub 연동) (0) | 2019.03.25 |