[CI / CD] Spring + React Jenkins(젠킨스) CI/CD 구축 (with AWS EC2)

최혜원·2024년 9월 26일
1
post-thumbnail
  1. Intellij에서 코드를 작성하고 Push를 한다.
  2. GitHub는 jenkins로 Webhook을 날린다.
  3. Jenkins에서 Build를 한다.
  4. SSH 통신을 통해 배포 서버에서 DockerHub에 올린 이미지를 Pull받아 실행한다.

CI/CD는 개발자 및 팀에 의해서 개발된 결과물에 대해 지속적인 통합과 지속적인 배포를 하는 프로세스

  • CI(Continuous Integration): 작업된 코드의 컴파일테스트패키징하는 작업
  • CD(Continuous Delivery, Continuous Deployment): CI에 의해 패키징된 작업물을 다시 개발테스트운영 서버로 배포하는 작업
    • Continuous Delivery: CI 에서 통합된 데이터를 검증하고 최종 배포를 수동으로 하는 작업
    • Continuous Deployment: 자동로 전 과정을 배포하는 작업

젠킨스를 도커로 실행

docker run -d -v jenkins_home:/var/jenkins_home -p 8081:8080 -p 50000:50000 --restart=on-failure --name jenkins-server jenkins/jenkins:lts-jdk17

첫 번째 숫자 8081은 호스트 머신의 포트를 의미하고, 두 번째 숫자 8080은 컨테이너 내의 Jenkins가 사용하는 기본 포트를 의미한다. 이렇게 하면 호스트 머신에서는 8081 포트로 접속할 수 있게 된다. Jenkins 컨테이너 내부에서는 여전히 8080 포트를 사용하지만, 외부에서 접근할 때는 8081 포트를 사용하게 된다.


🔥 젠킨스와 깃허브 연동해주기 - SSH 연동

traditional-market 는 private repository이다.
Private Repository 연동의 경우 조금 더 복잡한데, 그 이유는 바로 Public Repository와 달리 SSH Key를 사용해서 연동해야 하기 때문이다.

ssh-keygen

🔐 jenkins 서버에 생성된 공개키와 개인키를 확인한다.(복사해놓기)

Your identification has been saved in /var/jenkins_home/.ssh/id_rsa
Your public key has been saved in /var/jenkins_home/.ssh/id_rsa.pub

🔑 깃허브 프로젝트 설정 Deploy Keys에 SSH public key 입력


GitHub repo webhook 설정

이제 Github Webhook이 Trigger되면 자동으로 Jenkins가 Build를 수행할 수 있도록 Github Webhooks을 설정해줘야 한다.

  • Payload URL - 젠킨스 서버 주소에 /github-webhook/ 경로를 추가하여 입력한다.
    - http://locahost:8081를 입력하시면 정상적으로 동작하지 않는다.
    - http://public-ip:8081 같이 공개 IP를 사용하는 경우에도 정상적으로 동작하지 않는다.
    - ngrok 어플리케이션을 통해 외부에서 접근할 수 있는 도메인을 사용한다.
  • Content type - application/json 타입을 사용한다.
  • Add webhook 버튼을 누른다.

(배포전) Ngrok 설정

이제 해당 git repository에 push요청이 들어오는 경우 Jenkins 서버에 hook을 하도록 설정해야 한다. 하지만 우리는 로컬 PC에서 Jenkins 서버를 구동하고 있고, 때문에 Github와 소통하기 위한(외부에서 접근가능하도록) 공인 Url이 필요하다. 이를 위해 Ngrok를 사용할 것이다.

  • 다음 명령을 실행하여 기본 ngrok.yml 구성 파일에 인증 토큰을 추가
  • 깃허브와 연결 확인

✔️ 젠킨스와 연결 확인


🔑 Jenkins Credencials에 spring 레포지토리에 대한 SSH private key 등록

Credentials 등록 : 민감한 정보를 노출하지 않고, 누구나 액세스할 수 없도록 관리해 준다.

  • 비밀키 등록
  • Credentials 등록 확인
  • 깃 리포지토리 webhooks 연결 확인

+ react repository 새로운 이름으로 키 만들기

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_react

Jenkins Credencials에 react 레포지토리에 대한 SSH private key 등록



젠킨스 전용 EC2 생성

배포 후 추가 ✚ 깃 웹훅(Webhook)이 푸시를 감지해 이 내용을 EC2 내부의 젠킨스로 전달을 해준다. -> 웹훅으로 감지한 푸시 파일들을 젠킨스에서 자동 빌드(CI) (main 브랜치에 업데이트가 있으면 자동으로 빌드)

Jenkins 서버 생성

(배포후) 새로운 EC2 에 Jenkins 설치

  1. 패키지 업데이트
sudo apt update
  1. https관련 패키지 설치
sudo apt install apt-transport-https ca-certificates curl software-properties-common
  1. docker repository 접근을 위한 gpg 키 설정
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  1. docker repository 등록
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
  1. 다시 업데이트
sudo apt update
  1. 도커 설치
sudo apt install docker-ce
  1. 도커 설치 버전 확인
docker --version
  1. 젠킨스 run
docker run -d -v jenkins_home:/var/jenkins_home -p 8081:8080 -p 50000:50000 --restart=on-failure --name jenkins-server jenkins/jenkins:lts-jdk17

⭐️ 도커 젠킨스 접속

docker exec -it jenkins-server bash

✔️ 연결 확인

  • tmarket.store:8081 접속하면 jekins 초기 비밀번호 입력 창이 뜨고,
  • /var/jenkins_home/initialAdminPassword 해당 경로 들어가서 초기 비밀번호 찾아 입력

Jenkins container 최초 접속

docker exec -it --user root [컨테이너 ID] /bin/bash

⭐️ Dashboard > All > tmarket-back > Configuration

깃헙 리포지토리 SSH 복사

소스 코드 관리

💥 github.com에 접속 에러

stderr: No ED25519 host key is known for github.com and you have requested strict checking.
Host key verification failed.

  1. The authenticity of host 'github.com (20.200.245.247)' can't be established.
    "호스트 'github.com (20.200.245.247)'의 신뢰성을 확인할 수 없습니다."
    이는 처음으로 해당 서버에서 github.com에 접속할 때 나타나는 일반적인 메시지로, 서버가 GitHub의 SSH 키를 이전에 저장하지 않았기 때문에 신뢰할 수 없다는 뜻입니다.
  2. ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
    "ED25519 키의 지문(핑거프린트)은 SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU입니다." 이 메시지는 GitHub 서버가 사용하는 보안 인증 키의 핑거프린트를 나타냅니다. 이 핑거프린트를 통해 서버의 신뢰성을 검증할 수 있습니다.
  3. This key is not known by any other names.
    "이 키는 다른 이름으로 알려져 있지 않습니다."
    이 메시지는 서버가 다른 이름으로 GitHub 호스트 키를 알고 있지 않다는 의미입니다. 즉, 지금 처음으로 연결 시도를 하는 것입니다.
  4. Are you sure you want to continue connecting (yes/no/[fingerprint])?
    "연결을 계속하겠습니까? (yes/no/[fingerprint])"
    이는 보안상의 확인 절차로, 해당 서버가 진짜 GitHub 서버인지 확인 후 계속 연결할 것인지를 묻는 질문입니다.
  5. yes 입력
    "yes"라고 입력하였고, 그 결과로 해당 호스트가 known_hosts 파일에 추가됩니다.
  6. Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
    "경고: 'github.com' (ED25519)이 영구적으로 known_hosts 목록에 추가되었습니다."
    이제 서버가 GitHub의 호스트 키를 신뢰할 수 있는 목록(known_hosts)에 저장했습니다. 이후 같은 서버에 접속할 때 이 확인 과정을 건너뛸 수 있습니다.

Build Steps

- 터미널 명령어 추가

빌드 유발

🔑 도커허브 credentials 생성

빌드 환경 (빌드 환경 변수 추가 for Docker Hub)

도커 허브에 로그인 할 때 쓰일 환경 변수를 추가해준다.

  • 위에 생성한 도커허브 credentials 설정

Publish Over SSH 플러그인 설치

만약 여러 원격 서버에 파일을 배포하고 빌드 스크립트를 실행하기 위해서는 Publish Over SSH plugin을 설치해야 한.
Jenkins에서 제공해주는 플러그인 중에 SSH로 EC2에 jar 배포 파일을 전달을 해주는 Publish Over SSH 플러그인을 설치해야 한다.

Dashboard > Jenkins 관리 > System > Publish over SSH

서버 생성할 때 저장한 .pem

ec2를 생성할 때 받은 ssh 접속 키인 pem 파일내용을 복사하여 붙여 넣으면 된다.

Publish over SSH > SSH Server

Name : 사용할 임의의 SSH Servers의 Name을 입력
Hostname : 실제로 접속할 원격 서버 ip, 접속 경로를 입력
Username : 접속할 원격 서버의 user 이름
Remote Directory : 원격 서버에 접속하여 작업을 하게 되는 디렉토리

⭐️ 고급탭 열어 Use password authentication, or use a different key -> 비밀키 입력

Test Configuration이 Success 이면 성공!


💥 배포서버에 ssh key 연결 에러 발생

jenkins.plugins.publish_over.BapPublisherException: Failed to connect and initialize SSH connection. Message: [Failed to connect session for config [tmarket]. Message [Auth fail for methods 'publickey']]

원인은 우분투 22.04에서 부터 openssh가 8.8 이상이 설치된다.
openssh 8.8 버전부터 SHA-1 해시 알고리즘 사용하는 RSA 미지원으로 ssh 연결이 실패한 것이다.
ECDSA 사용하면 해결 가능하다고 한다.

⭐️⭐️⭐️ ssh-keygen -t ecdsa -b 521 -m PEM

⭐️⭐️⭐️공개키를 복사해서 원격 서버(tmarket 배포서버)에 추가

cd .ssh
cat authorized_keys
sudo vi authorized_keys

/etc/ssh/sshd_config 파일을 확인하여 PubkeyAuthentication이 활성화되어 있는지 확인

PubkeyAuthentication yes

.ssh파일의 권한은 700 authorized_keys는 600 이 아니면 ssh 인증이 동작하지 않는다.
chmod 600 authorized_keys
chmod 700 .ssh


+ jenkins 서버에서 tmarket 배포 서버로 접속되는지 확인


빌드 후 조치 - Send build artifact over SSH 설정 추가


OR 파이프라인 작성

  • 스프링 부트 프로젝트 build 작업이 끝나면 파이프라인이 실행되어야 하기 때문에 별도의 설정을 해야한다.
  • Build Triggers 에서 Build after other projects are built 선택 > Projects to watch에 파이프라인과 연결할 project 이름을 입력 (tmarket-back)> Trigger only if build is stable 선택

*주의 사항: .ssh파일, authorize_keys 파일을 만들 때 너무 많은 권한(chmod 777)을 주게 되면 보안상 이유로 접속할 수 없다.

profile
어제보다 나은 오늘

0개의 댓글