안녕하세요.
aws에서 돌리던 서비스를 라즈베리파이로 옮기려고 여러 문서를 찾아봤었는데
Gradle 기반, 깃허브 연동 후 조치 등에 대한 지식이 방대하고 흩어져 있어 정리하게 되었습니다.
로컬로 돌리던 서비스를 원격서버에 배포하려고 한다.
깃허브 레포지토리에 작업이 끝난 변경사항을 push 하면 jenkins는 push를 감지해 빌드 후 배포를 한다.
변경사항 push → 서버에 clone → 빌드 → 배포의 과정이
변경사항 push → 자동 배포로 바뀌게 되는 마법이 일어난다.
최근 jekins는 java버전 1.8이상이 되어야 제대로된 실행이 가능합니다.
$ sudo apt-get update
$ sudo apt-get upgrade
$ java -version
openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b01-1+rpi1-b01)
OpenJDK Client VM (build 25.212-b01, mixed mode)
$ wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
$ vim /etc/apt/sources.list
#추가하기
deb https://pkg.jenkins.io/debian-stable binary/
$ sudo apt-get update
$ sudo apt-get install jenkins
젠킨스의 기본 포트는 8080입니다.
한대의 서버에서 이것저것 설치할 경우 8080는 사용하기 어렵기 때문에 (저 같은 경우 배포 서버를 8080에 두고있습니다.) 이를 잘 사용하지 않는 포트로 변경하겠습니다.
# jenkins config 열기
sudo vim /etc/default/jenkins
그리고 아래와 같이 HTTP_PORT 를 변경합니다.
저는 8081로 수정하였습니다.
이렇게 설정 하신 후 Jenkins를 실행해보시면 포트가 바뀌어서 수행된 것을 확인할 수 있습니다.
$ sudo service jenkins start
실행이 원활하게 되었다면 (자바 버전 제대로 설치했다면 문제가 생기지 않음) 브라우저를 열어
http://본인서버localhost:8081/
에 접근합니다.
그러면 아래와 같은 창을 보실 수 있습니다.
cat으로 해당 코드를 확인하여
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
출력 값을 브라우저에 붙여넣습니다.
다음엔 플러그인 설치 화면인데, 저는 모두 설치를 진행하였습니다.
다음으로 계정 설정이 나오는데, jenkins에 사용할 계정과 비밀먼호를 설정합니다.(이후 접속시 로그인을 해야하기 때문에 까먹으면 안돼요)
설치가 다 완료 되었다면 아래와 같은 화면을 볼 수 있습니다.
로그인을 한다면 밑의 화면을 만날 수 있습니다. 저는 현재 배포중이기에 배포중인 것을 확인할 수 있습니다.
젠킨스와 Github연동 시 사용자명과 비밀번호 인증방식은 보안상 추천하지 않습니다.
그렇기 때문에 ssh로 연동하는 법을 배워보겠습니다.
사용자의 SSH키들은 기본적으로 ~/.ssh
디렉터리에 저장되어 있습니다.
$ ls ~/.ssh
id_rsa id_rsa.pub
만약 파일이 없거나, ~/.ssh
디렉터리가 없다면 ssh-keygen
프로그램을 사용하여 키를 생성해야합니다.
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pi/.ssh/id_rsa):
Created directory '/home/pi/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/pi/.ssh/id_rsa.
Your public key has been saved in /home/pi/.ssh/id_rsa.pub.
The key fingerprint is:
저는 디렉터리와 키를 따로 설정하지 않았습니다.( 기본 디렉터리, 키 사용시 암호없음 )
젠킨스로 배포하려는 Repository > Settings > Deploy keys → Add deploy key 선택
저는 현재 만들어진 상태입니다.
add를 누르고
위에서 확인한 ssh키값을 복사합니다.
$ cat ~/.ssh/id_rsa.pub
title엔 적절한 이름을,
key는 cat으로 확인한 값을 넣고 저장합니다.
젠킨스에도 연동을 해줘야겠죠 Jenkins 관리 > Manage Credentials
에 들어갑니다.
Global credentials에 들어간다음
Add Credentials를 눌러 줍니다.
비밀키를 등록하기 위해 비밀키를 복사합니다.
$ cat ~/.ssh/id_rsa
그러면
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbDnBpQHJhc3BiZXJyeXBpAQIDBA==
...
...
...
-----END OPENSSH PRIVATE KEY-----
이러한 형식의 값들을 볼 수 있는데
Begin 과 End를 포함한 것을 아래와 같은 설정으로 넣어줍니다.
Kind
사용자의 GitHub OAuth 토큰을 이용해 Jenkins가 자동으로 Hooks & Service를 등록하게 하겠습니다.
우선 Jenkins 관리 > 시스템 설정
에서 Github 세팅을 찾습니다
GitHub Personal access 토큰은 자신의 GitHub계정의 Settings > Developer Settings > Personal access tokens
에서 Generate new token으로 토큰을 생성합니다.
아래와 같이 진행합니다.
주의 생성되고 나오는 토큰을 저장해두세요, 처음 생성할때만 알려줍니다.
다시 Jenkins로 돌아가서 Credentials에 add를 눌러줍니다.
설정이 완료되고 Test connection으로 연결이 잘 되는지 확인합니다.
젠킨스 서버에서 자바 버전을 알아야 하기때문에 지정을 해줍니다.
젠킨스 관리 > Global Tool Configuration
에 들어갑니다.
add jdk를 눌러주고 라즈베리파이에 설치된 Jdk name과 JAVA_HOME을 적어줍니다. 현재 저는 밑에와 같이 되어있습니다.
$ java -version
openjdk version "1.8.0_212"
# javac 위치 확인
$ which javac
/usr/bin/javac
# 실제 위치 확인
$ readlink -f /usr/bin/javac
/usr/lib/jvm/java-8-openjdk-armhf/bin/javac
# profile을 연다.
$ sudo vim /etc/profile
맨밑에 추가해줍니다
# 환경변수
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-armhf
# profile reload
$ source /etc/profile
profile을 reload 하고 서버 재시작후 확인 가능합니다.
$ echo $JAVA_HOME
/usr/lib/jvm/java-8-openjdk-armhf
이를 아래의 JAVA_HOME에 추가해줍니다.
젠킨스 관리 > Global Tool Configuration
에서 동일하게 Git 설정을 해줍니다.
위와같이 설정을 해줍니다.
드디어 길고긴 설정의 과정이 끝났습니다.
새로운 item > Freestyle project
를 클릭합니다.
이름에는 적절한 이름을 적어주세요 (저는 github_deploy로 지정하였습니다)
General 에선 GitHub project를 클릭한 후 Url에 배포하려는 소스가 있는 레포 즉, 위에서 ssh값을 입력한 레포지토리의 URL을 적습니다.
필요한 경우 concurrent 빌드 실행
또한 체크해주세요. (빌드가 현재 실행중이더라도 추가적인 빌드를 가능하게 해줍니다.). 체크하지 않는다면 커밋이 올라오면서 실행되는 webhook에 의한 빌드가 실행되질 않습니다.소스 코드 관리 에선 Git을 체크한 후 Repository URL 에 위의 url을 동일하게 적으시면 됩니다.
Credentials은 위에서 추가하였기 때문에 클릭하시면 아래와 같이 보일 것입니다.
빌드 유발 에서는 GitHub hook trigger for GITScm polling 항목을 선택합니다.
이는 젠킨스가 repository로 부터 GitHub hook Push를 받는다는 얘기입니다.
여기까지 설정을 하고 저장을 합니다.
저장 후 위에서 등록한 Url의 Git repository > Settings > Webhooks
에 들어가면 Jenkins가 자동으로 등록한 Webhooks를 볼 수 있습니다.
이제 Jenkins Job에서 GitHub Hook Log라는 메뉴가 생긴 것을 확인할 수 있습니다.
branch에서 푸시하면 hook 이벤트를 수신한 것을 직접 확인 할 수 있게 되었습니다.
저는 여기서 밑의 그림과 같이 세팅을 하였습니다.
필요한 경우 concurrent 빌드 실행
을 체크 하여 빌드가 실행되고 있을 때 추가로 실행되려 하지만 현재 실행중인 서비스의 포트를 동시에 쓸 수 없음.Build Now
를 실행 합니다.다시 이미지로 돌아가겠습니다.
밑의 구성은 Add build step에서 추가할 수 있습니다.
첫 번째, Excute Shell:
8080포트에 서비스가 실행중 일 때, 같은 포트를 쓰려하면 에러를 내며 실행이 되지않습니다.
ps -ef | grep ""/build/libs/에 들어가는 jar 버전 이름"" | grep -v 'grep' | awk '{print $2}' | xargs kill -9
ex)
ps -ef | grep myservice | grep -v 'grep' | awk '{print $2}' | xargs kill -9
프로세스 중 Gradle build를 통해 생성된 jar파일을 실행한 프로세스를 찾아 kill 의 파라미터로 넘김
두 번째, Invoke Gradle script 에선 Repository에 포함되어있는 Gradle을 사용할 것이기 때문에 Use Gradle Wrapper를 선택합니다.
세 번째, Excute Shell
Gradle build 된 jar 파일을 배포하는 과정입니다.
nohup java -jar \
-Dspring.config.location=classpath:src/main/resources/application.yml,/var/lib/jenkins/workspace/중요 키값 yml 파일\
-Dspring.profiles.active=real \
build/libs/myservice-0.1.jar
위와 같은 실행 옵션을 설명하겟습니다.
nohup java -jar
-Dspring.config.location=classpath:
깃허브에 올리지 못하는 주요 파일( DB 키값,
Oauth 키값) 등을 서버에 yml로 저장 후 그 path를 지정하면, 프로젝트 실행시 import 됩니다.
-Dspring.profiles.active=real
build/libs/myservice-0.1.jar java -jar을 실행할 jar의 위치를 적습니다. workspace가 지정되어있기 때문에 현재와 같이 적어도 무방합니다.
설정을 마치고 저장을 누릅니다.
이제 모든 설정이 완료되었습니다!
Build Now를 누르고 싶은 마음이 굴뚝 같겠지만, 우선 구성의 kill 옵션이 있는 첫번째 Excute shell을 없애고 다시 저장합니다. (옵션을 복사해주세요)
Build Now를 누르고 다시 구성에 들어가 Add build stpe의 ExcuteShell을 추가한 뒤 위에서 복사한 kill 옵션을 다시 작성하고 첫번째로 옮깁니다.
결론적으로, 서비스는 계속 구동되어지고 master에 push 가 되면 자동적으로 현재 실행중인 서비스를 중단시키고 새로운 변경이 있는 서비스를 실행시킵니다.
아직 저도 배우는 단계라 일단 되게 해보자는 마음으로 했던 과정들입니다.
이후에 더 좋은 방법이 있으면 추가하겠습니다.
긴글 읽어주셔서 감사합니다.
참고좀 하겠습니다👍