1. CI/CD란
Continous Integration, Continuous Deployment라는 의미를 가지고 있다. 쉽게 표현하자면 테스트, 통합, 배포의 과정을 자동화하는 것을 의미한다.
2. CI/CD를 학습하려는 이유
이전 프로젝트에서 AWS EC2서버를 이용해 배포까지 해봤다. 그 후 코드 수정이나 기능 업데이트를 할 때마다 여러 과정을 거쳐 재배포를 하는 것이 너무나 번거롭고 반복적이었기 때문에 자동화를 시키기 위해 CI/CD를 학습하고자 한다.
3. Github Actions vs Jenkins
사용 방식 | GitHub에 내장된 클라우드 기반 CI/CD 도구 | 자체 서버에 설치해 운영하는 CI/CD 도구 |
서버 관리 | 서버 관리 불필요 (GitHub에서 제공) | 자체 서버 관리 필요 |
사용 편의성 | GitHub과 통합되어 사용하기 쉬움 | 설치 및 설정이 복잡할 수 있음 |
확장성 | GitHub에서 자동 스케일링 제공 | 스케일링을 직접 관리해야 함 |
비용 | GitHub 사용량 기반 요금제 (일정 시간 무료) | 자체 서버 사용 (서버 운영 비용 발생) |
커스터마이징 | 제한적 (GitHub 환경에 의존) | 무한한 커스터마이징 가능 (플러그인 및 서버 환경 제어) |
복잡한 파이프라인 처리 | 간단한 파이프라인에 최적화 | 복잡한 빌드/배포 파이프라인 처리에 유리 |
보안 | GitHub에서 관리하는 환경 (자체 서버 제어 부족) | 자체 서버 제어로 보안 강화 가능 |
플러그인 지원 | 제한적 (GitHub Actions 마켓플레이스 액션 사용) | 매우 방대한 플러그인 생태계 제공 |
프라이빗 프로젝트 | 유료 사용 또는 GitHub 요금제 필요 | 오픈 소스, 자체 서버에서 사용 |
- ChatGPT에 검색해본 결과, github actions가 개인 프로젝트나 학습에 용이해보인다.
- 또한 실제로 당근, 카카오엔터프라이즈, 테이블링 등을 비롯해 현업에서도 github actions를 도입하고 있는 것을 기술블로그들을 통해 확인되었다.
4. CI/CD 전체 흐름
- 코드 작성 후 Commit
- Github에 Push
- Push를 감지해서 Github Actions에 작성한 로직이 실행
- 빌드
- 테스트
- 서버로 배포
- 서버에서 배포된 최신 코드로 서버를 재실행
5. EC2 초기 설정 및 명령어
- 프리티어 메모리가 부족할 경우 - EC2 스왑 메모리
업데이트
sudo apt update
자바 설치
sudo apt install openjdk-17-jdk -y
자바 설치 확인
java -version
레파지토리 복제
git clone <git repository>
빌드
cd <repository directory>
./gradlew clean build
권한이 없는 경우
chmod +x ./gradlew
서버 실행
cd build/libs
nohup java -jar <.jar> &
포트 확인
sudo lsof -i:8080
서버 종료
sudo fuser -k -n tcp 8080
깃허브 계정 저장
git config --global credential.helper store
ssh로 ec2 원격 접속하기 - appleboy
https://github.com/marketplace/actions/ssh-remote-commands
6. Github Actions 적용1 - EC2에서 빌드하는 방식
name: Deploy To EC2
on:
push:
branches:
- main
jobs:
Deploy:
runs-on: ubuntu-latest
steps:
- name: SSH로 EC2에 접속하기
uses: appleboy/ssh-action@v1.1.0
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
envs: APPLICATION_PROPERTIES
script_stop: true
script: |
cd /home/ubuntu/cicd-server
git pull origin main
./gradlew clean build
sudo fuser -k -n tcp 8080 || true
nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &
uses: 라이브러리
host: 서버의 호스트 (EC2 public ip)
username: ubuntu
key: EC2에 접속할때 사용하는 키 (.pem)
script_stop: 스크립트가 실패할 시 중지 여부
sudo fuser -k -n tcp 8080 || true
: 8080포트를 사용하는 프로세스를 강제종료 || 실행중인 프로세스가 없어서 오류 발생시 무시
nohup java -jar build/libs/SNAPSHOT.jar > ./output.log 2>&1 &
: 백으로 실행하며, 표준 출력과 오류 로그를 output.log 파일에 저장 (appleboy 라이브러리 이슈 때문에 로그를 저장해야함)
- 장점
- git pull을 활용해서 변경된 부분의 프로젝트 코드에 대해서만 업데이트 하기 때문에 CI/CD 속도가 빠름.
- 대부분의 CI/CD 방식들은 전체 프로젝트를 통째로 갈아끼우는 방식을 사용.
- CI/CD 툴로 Github Actions만 사용하기 때문에 인프라 구조가 복잡하기 않고 간단한다.
- 단점
- 빌드 작업을 EC2에서 직접 진행하기 때문에 운영하고 있는 서버의 성능에 영향을 미칠 수 있다.
- Github 계정 정보가 해당 EC2에 저장되기 때문에 개인 프로젝트 또는 믿을만한 사람들과 같이 진행하는 토이프로젝트에서만 사용해야한다.
- application.yml에 민감한 값을 넣는 경우가 많기 때문에 .gitignore을 통해 버전관리가 되지 않게 제외시킨다.
name: Deploy To EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: SSH로 EC2에 접속하기
uses: appleboy/ssh-action@v1.1.0
env:
APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
envs: APPLICATION_PROPERTIES
script_stop: true
script: |
cd /home/ubuntu/cicd-server
rm -rf src/main/resources/application.yml
git pull origin main
echo "$APPLICATION_PROPERTIES" > src/main/resources/application.yml
./gradlew clean build
sudo fuser -k -n tcp 8080 || true
nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &
env: 환경변수 설정로, env에서 선언하고 $변수명 으로 사용
secrets: 깃허브에서 사용할 수 있는 비밀 변수, setting - Secrets and variables - Actions
echo "$APPLICATION_PROPERTIES" > src/main/resources/application.yml
: gitIgnore로 yml을 제외했을 때, 빌드에 필요한 내용을 secrets에 저장하고
이를 직접 yml을 생성해 저장한다.
7. Github Actions 적용2 - Github Actions에서 빌드하는 방식
- 장점
- 빌드 작업을 Github Actions에서 하기 때문에 우영하고 있는 서버의 성능에 영향을 거의 주지 않는다
- CI/CD 툴로 Github Actions만 사용하기 때문에 인프라 구조가 복잡하지 않고 간단한다.
- 단점
- 무중단 배포를 구현하거나 여러 EC2 인스턴스에 배포를 해야하는 상황이라면, 직접 Github Actions에 스크립트를 작성해서 구현해야 한다.
- 꽤 복잡하다.
name: Deploy To EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Github Repository 파일 불러오기
uses: actions/checkout@v4
- name: JDK 17버전 설치
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: application.yml 파일 만들기
run: echo "${{ secrets.APPLICATION_PROPERTIES }}" > ./src/main/resources/application.yml
- name: 테스트 및 빌드하기
run: |
chmod +x ./gradlew
./gradlew clean build
- name: 빌드된 파일 이름 변경하기
run: mv ./build/libs/*SNAPSHOT.jar ./project.jar
- name: SCP로 EC2에 빌드된 파일 전송하기
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
source: project.jar
target: /home/ubuntu/cicd-server/tobe
- name: SSH로 EC2에 접속하기
uses: appleboy/ssh-action@v1.1.0
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
script_stop: true
script: |
rm -rf /home/ubuntu/cicd-server/current
mkdir /home/ubuntu/cicd-server/current
mv /home/ubuntu/cicd-server/tobe/project.jar /home/ubuntu/cicd-server/current/project.jar
cd /home/ubuntu/cicd-server/current
sudo fuser -k -n tcp 8080 || true
nohup java -jar project.jar > ./output.log 2>&1 &
rm -rf /home/ubuntu/cicd-serve/tobe
checkout
: github 에서 코드를 가져와 워크플로우에서 사용할 수 있게함
setup-java
: java 17을 설치하여 빌드 환경을 셋팅
scp-action
: EC2 인스턴스로 파일 전송, source: 전송할 파일, target: EC2 인스턴스의 경로
script:
1. 현재 실행중인 서버 파일 삭제 후 재생성
2. SCP로 전송받은 파일을 /tobe 디렉토리에서 /current로 이동
3. 현재 실행중인 프로세스 종료
4. 새로 배포한 파일 실행
5. 배로 후 불필요한 파일 삭제
'DevOps > Git' 카테고리의 다른 글
[Git] Directory 별 계정 설정하기 (0) | 2024.11.05 |
---|---|
이클립스 github 연동하기 (0) | 2023.04.13 |