[Spring Boot] Jenkins 이용하여 CICD 구축하기(2)

모지리 개발자·2022년 10월 7일
5

CICD

목록 보기
2/2
post-custom-banner

Intro

이번 글에서는 이전 글 에 이어서 ssh 연결을 통해 외부 서버에 jar 파일을 복사하여 CD가 가능하도록 해보겠습니다. (서버는 모두 Ncloud를 이용하여 생성했습니다)

내가 하고싶은 것

이전 글에서도 작성했었지만 그림을 한번 더 보려드리겠습니다.

현재까지는

  • IDE에서 코드를 PUSH한다.
  • Github은 Jenkins로 Webhook을 날린다.
  • Jenkins는 해당 repo를 빌드한다.
    까지 했었습니다.

그림에서 보셔서 아시겠지만 저는 외부 서버에 jar 파일을 복사해서 사용할 예정입니다. 이렇게 구성했던 이유는 현재는 배포서버가 1개이지만 여러개로 늘어나게 되면 각각 서버마다 jenkins를 설치해서 사용하는 것은 불필요한 리소스를 낭비하는 것이라는 생각이 들었고 한개의 젠킨스 서버만 빌드하여 모든 다른 서버에 SSH 방식으로 파일 전송, 빌드 스크립트를 유발하여 관리가 가능한 것이 유지보수 측면에서도 더 용이할 것이라고 생각했습니다.

Step

이번글에서 작성할 Step은 다음과 같습니다.
1. Publish Over SSH 플러그인 설치, 설정
2. jenkins 에서 빌드 후 조치 설정
3. 배포 서버(ubuntu)에서 배포용 스크립트 생성

Publish Over SSH 플러그인 설치, 설정

jenkins에서 빌드 된 파일을 외부 서버로 옮기기 위해서는 젠킨스의 Publish Over SSH 플러그인이 설치되어있어야합니다.

위의 그림에서 보시는 것처럼 왼쪽 Jenkins관리 탭을 누르고 플러그인 관리 메뉴를 선택합니다.


그 후 위에 보이는 플러그인을 설치하고 Jenkins를 restart해주시면 됩니다.

그다음 젠킨스 서버에 접속하신 후에

$ service jenkins restart

를 입력해주시면 됩니다.


설치가 완료됐다면 설정을 해보도록 하겠습니다.

Jenkins 관리에서 시스템 설정을 선택합니다.
그 후 스크롤을 내려서 Publish over SSH 메뉴를 찾으시면 됩니다.
작성을 해야하는 부분은 다음과 같습니다.

사실 이부분부터 애를 먹기 시작했습니다.

우선 원격 서버에 private key를 이용하여 ssh 접속을 하기위해서는 ssh접속에 이용될 private key와 짝을 이루는 public key를 원격 서버에 등록해줘야합니다.

ec2를 기준으로는 ec2를 생성할 때 받은 ssh 접속키인 pem 파일 내용을 복사하면 된다고 하지만 ncloud에서는 생성했던 pem 파일로 접속이 되지 않았습니다.

그래서 jenkins서버에서 직접 ssh-key를 생성했습니다.

우선 jenkins서버에 접속합니다.
그 후

$ ssh-keygen -t rsa

입력하여 키를 생성합니다.

그 후 생성된 *.pub 키의 내용을 복사합니다.

그 후 원격서버(이 글에서는 Ubuntu 서버)로 접속합니다.
그 다음

$ cd .ssh

로 접속 한 후에 authorized_keys파일을 만들어 줍니다.

$ touch authorized_keys

그 후 vim 명령어를 이용하여 위에서 복사했던 *.pub의 내용을 붙여넣어줍니다.

다시 Jenkins로 돌아가겠습니다.
Jenkins Over SSH Key의 Key 값에는
이전에 생성했던 Key의 private Key 값을 넣어주시면 됩니다.

Name : 임의의 SSH Server의 이름을 입력하시면 됩니다.
Hostname : 배포 서버의 비공인 IP를 입력하셔야 합니다.(하루 왠종일 public IP넣었다가 애먹었슴다...)
Username : 접속할 원격 서버의 username 입니다.
Remote Directory : 원격 서버에 접속하여 작업을 하게되는 디렉토리 입니다.

이후 작성이 다 끝났으면 Test Configuration를 클릭합니다.

사진과 같이 Success가 나왔다면 성공입니다.

jenkins 에서 빌드 후 조치 설정

이제는 이전글에서 생성했던 Project로 넘어가보겠습니다.
Add build step을 클릭한 후에

위와 같이 Send files or execute commands over SSH를 클릭해줍니다.

저는 다음과 같이 설정했습니다.

Name은 위에서 만들었던 임의의 SSH Server입니다.
Source files : 전송할 파일을 지정합니다. 전체 파일을 이동하고 싶으시다면 **/* 과 같이 입력하면 됩니다. jenkins에서 build를 하게 되면 보통 /var/lib/jenkins/workspace/젠킨스 프로젝트 명/build/libs 에 저장됩니다. source files에는 workspace 기준 상대 경로를 작성해주셔야 합니다.
제 jar 파일은 /var/lib/jenkins/workspace/chuchu-webhook/build/libs 에 있지만 source files에는 build/libs/chu-chu-0.0.1-SNAPSHOT.jar과 같이 작성했습니다.

Remote prefix : Source files에서 지정한 경로의 하위폴더를 지우는 기능입니다. 위의 예시 같이 입력한다면 폴더를 제외하고 jar파일만 전송하게 됩니다.
Remote directory : SSH Server로 지정한 서버의 원격지 폴더입니다.
Exec command : 파일 전송이 모두 끝난 이후에, SSH Server로 지정한 서버에서 실행될 스크립트를 지정할 수 있는 기능입니다.

이글에서는 아직 원격서버에 deploy.sh를 생성하지 않았습니다. 이제 원격서버에 배포 스크립트를 작성해보겠습니다.

배포 서버(ubuntu)에서 배포용 스크립트 생성

원하는 배포 서버에 접속한 후 deploy.sh를 만듭니다.

$ touch deploy.sh

deploy.sh

echo ">80번 포트 종료"
fuser -k -n tcp 80

echo ">chuchu 어플리케이션 실행"
sudo nohup java -jar /usr/root/chuchu/jar/chu-chu-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &

저는 내용을 위와 같이 작성했습니다.
우선 제 스프링부트 어플리케이션은 80번 포트를 사용하고 있었는데 스크립트가 실행될 때 기존 80번 포트가 사용중이거나 할 수 있어서 종료를 시켰습니다.
그 후 백그라운드로 jar 파일을 실행시킵니다.

주의사항 : 처음에는

...
sudo java -jar /usr/root/chuchu/jar/chu-chu-0.0.1-SNAPSHOT.jar

과 같이 작성했었습니다. 하지만 젠킨스에서 빌드를 실행하니 애플리케이션을 실행시키고 job이 끝나지를 않았습니다...SSH로 원격 스크립트를 실행하게 되면 stdoutput이 닫히거나 timeout이 발생할 때까지 스크립트가 닫히지 않는다고 합니다. 그래서 script로 백그라운드 작업 수행 시에는 위에서 작성했던 것과 같이 모든 output을 redirect 해줘야 스크립트가 종료됩니다.

/dev/null : stdout을 출력을 기록하지 않게 /dev/null로 이동
2>&1 : stderr도 stdout으로 이동
& : 백그라운드로 실행

실행해보기


잘됩니다!

@RestController
public class TestController {

    @GetMapping("/test")
    public String test() {
        return "Hello, this application is chuchu test jenkins0.0.1";
    }
}

code를 변경하고 push해보면 빌드, 배포까지 잘 수행되는 것을 확인 할 수 있었습니다.

추가 : ncloud 서버의 ACG 설정에서 제 기준 80포트를 열어줘야합니다!

결론

아주 단순하고 기본적인 CICD를 구축해보았습니다. Jenkins를 이용한 CICD의 구축은 정답이 없는 것처럼 사람마다 또 비즈니스 마다 아주 다르게 구성하는 느낌을 받았습니다. 아직은 어떤 방식으로 CICD를 구축하는게 좋은지 제일 좋은 방법인지를 모르겠습니다. 하지만 현재 제가 만들었던 CICD를 기준으로는 특정한 jar 파일밖에 실행을 못하고 또 history관리를 전혀 안하고있기 때문에 이부분에 대해서 큰 단점이 보이고 있습니다. 앞으로 프로젝트를 진행하면서 느끼는 단점이 있거나 보완사항이 있었다면 글에 또 추가하도록 하겠습니다. 감사합니다!

제가 잘못이해하고 있거나 잘못 작성한 부분이 있다면 지적, 비판, 피드백 뭐든 해주시면 감사하겠습니다!

profile
항상 부족하다 생각하며 발전하겠습니다.
post-custom-banner

2개의 댓글

comment-user-thumbnail
2023년 9월 19일

많은 도움이 됐습니다. 감사합니다 :)

답글 달기
comment-user-thumbnail
2024년 1월 9일

많은 도움 받았습니다.
만약 ERROR: Exception when publishing, exception message [Exec exit status not zero. Status [1]] Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE에러가 발생한다면 deploy.sh가 권한이 있는지 확인해보면 좋을 것 같습니다.

답글 달기