개요
이번 글에서는 저번 글에서 만들어둔 젠킨스에서 파이프라인을 생성하고 깃허브 액션을 연결하도록 하겠다.
우선 나의 프로젝트는 깃허브에 respal이라는 public한 메인 레포지토리가 있고,
application.yml을 관리하는 respal-private이라는 private한 레포지토리가 있고 둘은 깃의 서브모듈로 연결이 되어있다.
따라서 파이프라인에서 메인 레포지토리를 클론하며 서브모듈도 가져오는 작업이 필요했었던 상황이였다.
Jenkins x Github 연동
SSH 키 생성
젠킨스에서 깃헙 프로젝트로 접근하기 위해서
애플리케이션 서버 인스턴스에 접속하여 SSH키를 생성한다.
ssh-keygen -t rsa
이렇게 하면 ~/.ssh 디렉토리 아래에 id_rsa.pub 와 id_rsa 파일이 생긴다.
각각 해당 인스턴스에 접근 할 수 있는 공개키와 비밀키 이다.
비밀키는 해당 인스턴스에 가지고있고, 공개키를 접근을 원하는 곳에 설정하여 접근을 허용하는 것 이다.
Github Deploy Key 등록
위에서 생성해준 키 중 공개키를 깃허브에 등록한다. 사용할 깃헙 프로젝트에서
Settings > Deploy Keys > Add deploy key 클릭
Title 은 구분할 수 있는 명칭으로 하고, Key 값에는 퍼블릭키의 값을 넣어준다.
방금 생성한 애플리케이션 인스턴스에서 해당 명령어를 사용하여 얻어온 퍼블릭키 값을 넣어준다.
$ sudo cat ~/.ssh/[설정한 키 명칭].pub
Jenkins Credential 등록
젠킨스에서는 생성해준 키의 프라이빗 키를 크리덴셜로 등록해주어야 한다.
Jenkins관리 > Security > Credentials 아래 Domain이 (global) 인 화살표를 눌러
add credentials 을 눌러 크리덴셜을 추가한다.
위 크리덴셜 속성에는
종류는 SSH Username with private key 로 선택,
ID 에는 해당 크리덴셜의 ID라고 생각하고 구분할 수 있도록
그리고, Private Key 부분에 Enter directly를 체크해주면 프라이빗키를 입력할 수 있는 창이 나타난다.
애플리케이션 인스턴스로가서 다음 명령어를 통해 프라이빗 키를 확인하여 입력해준다.
$ sudo cat ~/.ssh/[키 명칭]
-----BEGIN OPENSSH PRIVATE KEY-----
...
... 이와 같은 형태의 key가 private key
...
-----END OPENSSH PRIVATE KEY-----
키까지 모두 입력하고 OK를 하면 등록이 완료된다.
위와같은 방법으로 서브모듈 크리덴셜도 생성해준다.
이 때 서브모듈 크리덴셜의 Kind는 Username and password로 설정하고,
password에는 깃허브 access token을 입력한다.
깃허브 access token은 Github > Settings > Developer Settings에서 Generate new token으로 생성한다.
scopes는 아래와같이 잡아준다.
Jenkins x 배포서버 SSH연결
1. Jenkins 서버의 SSH 키 - 쌍 생성
Jenkins 인스턴스에 접근을 하기 위해 PEM 형식의 키를 생성한다.
ssh-keygen -t rsa -C "키명칭" -m PEM -P "" -f /var/lib/jenkins/.ssh/[키명칭]
2. 애플리케이션 서버에 Jenkins 서버의 PublicKey 등록
위에서 생성한 키페어 중 퍼블릭 키를 배포서버인 인스턴스의 .ssh/authorized_keys 파일에 추가한다.
// 젠킨스 서버
$ sudo cat /var/lib/jenkins/.ssh/[키명칭].pub
// 애플리케이션 서버
$ vi .ssh/authorized_keys
3. Publish Over SSH 플러그인 설정
- Jenkins 관리 > 플러그인 관리 > 설치가능 탭 에서 Publish Over SSH 플러그인을 검색하여 설치하고 젠킨스를 재실행하여 플러그인이 적용 될 수 있도록 한다.
Jenkins 관리 > 시스템 설정 아래 Publish Over SSH 영역의 고급 버튼을 눌러 확장하여 설정한다.
- Path to Key 는 위에서 생성해준 (젠킨스 서버의) private key의 경로를 넣는다.
- /var/lib/jenkins/.ssh/{private key 명}
- Key 는 Private key 파일안의 내용을 복사 붙여넣기 해준다.
- Name 는 접속할 ssh 서버의 이름을 작성한다.
- Hostname 는 접속할 (배포할 애플리케이션)인스턴스의 주소를 넣는다.
- Username 는 접속할 (배포할 애플리케이션) 인스턴스의 유저명을 넣는다.
입력을 마친 후 Test Configuration 버튼을 눌러 정상적으로 연결이 되는지 확인까지 한다.
4. 파이프라인 작성
Test Configuration이 정상적으로 이루어지면 애플리케이션 서버의 인스턴스에 접속해서
/home/ubuntu/{서비스명}/script 디렉토리를 만들어주고 해당 디렉토리에 다음과 같은 init_server.sh 파일을 만들어준다.
echo "> respal pid 확인"
CURRENT_PID=$(ps -ef | grep java | grep respal | grep -v nohup | awk '{print $2}')
echo "$CURRENT_PID"
if [ -z ${CURRENT_PID} ] ;then
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
echo "> sudo kill -9 $CURRENT_PID"
sudo kill -9 $CURRENT_PID
sleep 10
fi
echo "> 서버 배포"
JAR_PATH=$(ls -t /home/ubuntu/{서버명}/deploy/*.jar | head -1)
sudo nohup java -jar -DServer.port=80 ${JAR_PATH} >> /home/ubuntu/{{서버명}}/logs/{서버명}.log 2>&1 &
echo "Deploy Success"
init_server.sh 파일 설정
sh 파일을 생성했으면 이제 다시 웹 젠킨스로 돌아가서
대시보드 > 새로운 Item을 들어간 후
item name을 작성하여 Pipeline을 선택 후 OK를 클릭해준다.
프로젝트가 생성되면 스크립트 작성을 하여 수동 배포를 먼저 확인한 이후 Github와 연동하는 설정을 하도록 하겠다 !
4 - 1 파이프라인 스크립트 작성
젠킨스에서는 파이프라인 스크립트를 2가지로 제공하고 있다.
- Pipeline script
- 젠킨스 웹 내에서 스크립트를 작성하여 관리 (default)
- Pipeline script from SCM
- 프로젝트 내에서 Jenkinsfile에 스크립트를 작성하여 관리
우리는 default 방법인 Pipeline script를 활용해서 작성해보도록 하겠다.
Pipeline Script는 2가지 타입으로 작성이 가능하다. 두 방법 모두 Groovy문법 기반이며 둘의 차이는 아래와 같다.
- Declarative Pipeline : 쉽게 작성이 가능하며 Groovy 문법 기반이지만 해당 문법을 몰라도 작성 가능하다고 한다. (최상단에 pipeline 이라고 되어 있으면 declarative 문법으로 작성된 것이다.)
- Scripted Pipeline : Groovy 문법 기반이며 Declarative 보다 효과적이고 많은 기능으로 포함해서 작성 가능한데 어렵다. (최상단에 node 지시어가 있으면 scripted 문법으로 작성된 것이다.)
두 문법을 혼합해서 사용할 수는 없으며 상세한 내용은 공식 문서에서 참고가 가능하다.
이 중 우리는 Declarative Pipeline 문법을 사용하여 스크립트를 작성하도록 하겠다.
pipeline {
agent any
stages {
stage('Git Clone') {
steps {
checkout scmGit(branches: [[name: '*/master']],
extensions: [submodule(parentCredentials: true, reference: '', trackingSubmodules: true)],
userRemoteConfigs: [[credentialsId: '{Credential에서 설정한 서브모듈 토큰의 이름}', url: '배포 서버의 깃 레포지토리']])
}
}
stage('build'){
steps{
sh'''
echo build start
./gradlew clean bootJar
'''
}
}
stage('publish on ssh'){
steps{
sshPublisher(
publishers:
[
sshPublisherDesc(
configName: '{위에서 설정한 SSH Server의 name을 입력}',
transfers:
[
sshTransfer(
cleanRemote: false,
excludes: '',
execCommand: 'sh /home/ubuntu/respal/script/init_server.sh',
execTimeout: 0,
flatten: false,
makeEmptyDirs: false,
noDefaultExcludes: false,
patternSeparator: '[, ]+',
remoteDirectory: '/respal/deploy',
remoteDirectorySDF: false,
removePrefix: 'build/libs',
sourceFiles: 'build/libs/*.jar'
)
],
usePromotionTimestamp: false,
useWorkspaceInPromotion: false,
verbose: true
)
]
)
}
}
}
}
파이프라인은 3개의 stage로 분리가 되어있다.
- 1번 스테이지('Git Clone')에서는 Git에서 프로젝트를 클론해오고
- 우리는 이번 포스트에서 언급했듯 서브모듈도 같이 클론해와야 하기 때문에 extensions를 추가하여 submodule도 같이 클론해온다.
- 2번 스테이지('build')에서는 클론해온 프로젝트를 빌드 한 다음
- 3번 스테이지('publish on ssh')에서는 아까 작성해둔 쉘 스크립트를 실행한다.
스크립트를 작성하고 저장을 한 다음 대시보드에 가서 만들어둔 파이프라인을 클릭 후에
지금 빌드 버튼을 누르면 ( 한 번만 눌러야 함.. 여러번 누르면 에러나니 주의 ! )
하기와 같은 Stage별 Status가 나오는 Stage View에서 정상적으로 동작하는것을 확인 할 수 있다.
이렇게 모든 단계가 초록색으로 되면 배포가 된 것을 확인 할 수있다.
이제 깃허브와 연동을해서 해당 프로젝트를 푸쉬를 하면 자동으로 배포가 되도록 설정을 하도록 하겠다.
5. Github Webhook 연동
5-1 Github 프로젝트에 Webhook 생성
Github의 배포를 원하는 프로젝트의 레포지토리를 들어가 Setting > Webhook > Add Webhook을 클릭한다.
해당 Webhook 세팅에서
- Payload URL
- {Jenkins 인스턴스 주소}/github-webhook/
- 해당 Jenkins는 8080포트를 이용하기 때문에 포트를 적어줬다.
- {Jenkins 인스턴스 주소}/github-webhook/
- Content type
- application/json
을 설정 후 Update webhook을 눌러 Github 설정을 해준다.
5-2 Jenkins 파이프라인에 Github Webhook 연동
아까 작성해둔 파이프라인 프로젝트의 구성 탭으로 들어가서 다음과 같이 설정을 해준다.
- Github project
- Project url : 방금 webhook을 설정한 깃허브 레포지토리 주소
- Github hook trigger for GITScm.polling
해당 설정들을 체크해주고 저장 버튼을 누르면 연동이 모두 완료된다.
출처
- [AWS] Jenkins를 활용한 Docker x SpringBoot CI/CD 구축 (velog.io)
- [DevOps] Jenkins를 통한 CI/CD 구축기 4편 (Backend DB 구축) | Seongwon.dev
'💻Spring' 카테고리의 다른 글
Response 규격화 Swagger 처리 (1) | 2023.06.10 |
---|---|
OAuth, 일반 이메일 회원가입시 중복관련 Trouble Shooting (0) | 2023.06.05 |
Jenkins 파이프라인을 이용한 SpringBoot 자동배포 (환경설정) (1) | 2023.05.19 |
Github에 프로젝트 민감정보 숨기기 (application.yml) (0) | 2023.04.26 |
@ModelAttribute , @RequestParam 정리 (0) | 2023.04.26 |