[Product Serving Part.4] Github Action을 사용한 CI/CD
- -
1. CI/CD(Continious Integration/Continuous deploymen)
- Local : 각자의 컴퓨터에서 개발, 각자의 환경 통일을 위해 Docker 등을 사용
- Dev : Local에서 개발한 기능을 테스트할 수 있는 환경
- Staging : Production 환경에 배포하기 전에 운영하거나 보안, 성능을 측정하는 환경
- Production : 실제 서비스를 운영하는 환경
서버에 코드를 보내는 것과 반복적으로 진행할 Test를 어떻게 실행해야할까?
Dev Branch에 Merge되면 → Local에서 Git Pull & Test 실행 후 괜찮으면 코드 배포 (FTP로 파일 전송)
→ 매번 해주기가 너무 번거롭다!
→ CI (Continuous Integration:지속적 통합) !!
새롭게 작성한 코드 변경 사항이 Build, Test 진행 후 Test case에 통과했는지 확인하여 지속적인 코드 품질 관리 가능
→ CD (Continuous Deploy:지속적 통합) !!
작성한 코드가 항상 신뢰 가능한 상태가 되면(CI가 통과가 되면) 자동으로 배포될 수 있도록 하는 과정
CI/CD를 활용할 수 있는 도구
2. Github Action
- Github Repo 당 Workflow는 최대 20개까지 등록할 수 있다.
- Workflow에 존재하는 Job(실행)은 최대 6시간 실행 가능, 초과 시 자동으로 중지
- 동시에 실행할 수 있는 Job 제한 존재
Github Action 사용 방식
- 코드 작업
- 코드 작업 후, Github Action으로 무엇을 할 지 생각
- 사용할 workflow 정의
- 정의 후 정상 작동하는 지 확인
Github Action Core
- Workflow
- 최상위 개념
- 여러 Job으로 구성되고 Event로 Trigger(실행)되는 자동화된 Process
- Workflow 파일은 YAML로 작성되고, Github Repo의 .github/workflows 폴더에 저장
name: GitHub Actions Demo
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v2
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
- Event
- Workflow를 Trigger하는 특정 활동, 규칙
- 특정 Branch로 Push하는 경우
- 특정 Branch로 Pull Request 하는 경우
- 특정 시간대에 반복(Cron)
- Jobs
- Runner에서 실행되는 Steps의 조합
- 여러 Job이 있는 경우 병렬로 실행하며, 순차적으로 실행할 수도 있음
- 다른 Job에 의존 관계를 가질 수 있음 (A Job Success 후 B Job 실행)
- Step
- Job에서 실행되는 개별적인 작업
- Action을 실행하거나 쉘 커맨드 실행
- 하나의 Job에서는 데이터 공유가 가능
- Actions
- Workflow의 제일 작은 단위
- Job을 생성하기 위해 여러 Step을 묶은 개념
- 재사용이 가능한 Component
- 개인적으로 Action을 만들 수도 있고, Marketplace의 Action을 사용할 수도 있음
- Runner
- Github Action도 일종의 서버에서 실행되는 개념
- Workflow가 실행될 서버
- Github-hosted Runner: Github Action의 서버를 사용하는 방법
- 성능: vCPU 2, Memory 7GB, Storage 14GB
- Self-hosted Runner : 직접 서버를 호스팅해서 사용하는 방법
Github Action Hello World
repo를 하나 파고 아무거나 출력되는 간단한 print 코드가 있는 .py 파일을 생성한 뒤 Actions를 클릭
Python application 검색 후 Configure 클릭
클릭하면 자동으로 python-app.yml 파일이 자동으로 생성된다.
우리는 Test with pytest를 하는게 아니라 아까 만든 파이썬 코드를 실행할 것이다.
name에 무엇을 할지 설명하고
run에 python hello-world.py 를 할 것이라고 변경해준다.
커밋하고 해당 파일을 들어가보면 노란색 동그라미가 생김을 확인할 수 있다.
노랑색 동그라미는 github action이 실행되고 있다는 것을 뜻한다.
노란색 동그라미를 클릭하면 현재 check중인지 check가 다 되었는지 알 수 있다.
Details를 눌러보면 로그를 확인할 수 있는데 아래 그림처럼 초록색이면 Success를 의미
YAML 파일 분석
on : Event
언제 Workflow가 실행될 것인지
- main 브랜치로 push 될 때 실행
- main 브랜치에 pull_request 될 때 실행
jobs : jobs 정의, build는 job의 이름이다.
runs-on : ubuntu 환경에서 실행
uses : 사용할 Github Action
name : step의 이름
uses가 없는 경우 : run에 작성된 쉘 커맨드 실행
3. 배포하고 CI/CD까지 설정하기
진행 순서
1. Compute Engine 실행
2. SSH 키 생성 및 Github Secrets 설정
3. 터미널에서 최초로 서비스 실행
4. Gihub Action을 통한 배포 자동화
3.1 Compute Engine에서 Streamlit 실행
- 인스턴스 생성
- 인스턴스 이름 작성
- Region 설정 : 서울
- 머신 유형 설정 : 메모리 8GB 이상인 유형으로 설정
- 부팅 디스크 설정
- 인스턴스 생성 완료
- SSH 클릭 후 브라우저 창 열기로 터미널 진입
- SSH Key 생성
cd ~/.ssh/
ssh-keygen -t rsa -b 4096 -C "이메일"
그 뒤로 그냥 Enter
- cat 명령어로 id_rsa.pub 파일을 authorized_keys에 등록한다.
기본적으로 authorized_keys에 퍼블릭 키가 등록되면 외부에서 접근이 가능하다.
cat id_rsa.pub >> authorized_keys
- 단 GCP는 주기적으로 authorized_keys 파일을 삭제하므로 외부에서 키파일을 등록하는 과정이 필요하다.
따라서 cat 명령어로 id_rsa.pub을 출력한 후 복사해서 개인적으로 저장해둔다.
cat id_rsa.pub
- GCP 콘솔로 이동한 후 메타데이터 클릭
- SSH 키로 이동 후 수정 클릭
- 아까 개인저장해둔 퍼블릭 키를 추가 후 저장
- Github Repo : https://github.com/zzsza/Boostcamp-AI-Tech-Product-Serving 로 이동해서 Fork
- Setting - Secrets의 Action으로 이동한 후 New Repository secret 클릭
- 그러면 왼쪽 아래같은 화면이 나타나는데 총 3개의 Secret을 등록해야함
- 첫번째로는 Host를 추가해야 함
- 인스턴스 외부 IP를 복붙해서 붙여넣기
- 두번째로는 USERNAME 추가
- 터미널의 저 값을 적어주면 된다.
- Private Key는 vi id_rsa로 확인한 후 전체 복사
- 3개의 Secret이 등록된다.
- 한 번 저장하면 값을 확인할 수는 없고 update만 가능하다.
- Github Action에서 Secret을 활용할 수 있다.
- ${{ secrets.HOST }} : secrets에 저장된 HOST의 Value
- Github Action에서 추가 인증 없이 사용하도록 설정하기 위해 아래 코드 터미널에서 실행
nextlevelpotato13@boostcamp:~/.ssh$ cd
nextlevelpotato13@boostcamp:~$ git config --global credential.helper store
- Fork한 Repo Clone
- 만약 이 부분에서 인증 오류가 난다면 Github의 Access Token 발급이 필요하다.
- Github의 우측 상단 계정의 Settings 클릭
- 좌측 하단의 Developer Settings 클릭
- 토큰 생성 클릭
- Note, 기한, 권한 scope 설정
- 해당 값은 지금 창을 나가면 다시는 확인할 수 없으므로 개인저장해두고 절대 유출되어서는 안됨
- 그리고 아까 실패했던 git clone에서 password에 해당 토큰 값을 붙여넣으면 된다.
- 다시 돌아와서 이제 필요한 프로그램을 설치해야 한다.
sudo apt-get update
sudo apt-get install python3.8-venv -y
- 가상환경 venv 만들고 실행
python3 -m venv venv
source venv/bin/activate
- 아까 클론한 레포의 CI/CD 폴더로 이동하고 requirments.txt 설치
cd Boostcamp-AI-Tech-Product-Serving/part2/04-cicd/
pip install -r requirements.txt
- 설치가 완료되면 아래 코드로 Streamlit을 실행한다.
nohup streamlit run app.py --server.runOnSave true &
runOnSave : 파일이 변경될 경우 자동으로 다시 실행
nohup으로 Background 실행한다.
- nohup.out을 출력하면 Externel URL을 확인할 수 있다.
cat nohup.out
- 그러나 해당 URL로 접속하면 사이트에 접근이 할 수 없다.
→ 방화벽 이슈
→ 클라우드 서비스엔 아무나 접근할 수 없도록 설정되어 있기 때문에 방화벽 설정을 수정해야 접근할 수 있다.
- GCP 웹사이트의 인스턴스 목록 하단에서 방화벽 규칙 설정을 클릭한다.
- 방화벽 규칙 만들기
- 이름 설정
- 지정된 대상 태그
- 태그 이름은 그냥 이름이랑 똑같이 설정함
- 소스 IPv4 범위 : 0.0.0.0/0
- 누구나 접근 가능
- Streamlit을 실행할 것이므로 Streamlit Port를 지정
- 8501
- 그럼 생성된 방화벽을 확인할 수 있다.
- Compute Engine 페이지로 간 후, 인스턴스 이름 클릭
- 수정 클릭 후, 네트워크 태그에 아까 생성한 streamlit 추가한 후 저장
- 다시 그 URL에 접근해보면 접속이 가능하다!
이제 Github Action을 사용해 자동화 배포를 해보자
- Fork한 Repo로 이동해서 Actions를 클릭하고 I understand를 클릭
- Boostcaml-AI-Tech-Product-Serving/.github/workflow/deploy_ssh.yml 으로 이동
- ssh-action을 사용해 볼 것이다.
- SSH로 붙은 후, 스크립트를 실행
- push 하단의 paths의 의미
- main branch로 push/merge가 될 경우
- 이 경로에 있는 파일이 변경된 경우에 실행
- ignore를 하면 해당 경로에 수정된건 신경쓰지 않겠다는 것
- deploy_ssh.sh 쉘 스크립트 실행
- cicd 폴더로 이동
- deploy_ssh.sh 쉘 스크립트를 실행
- deploy_ssh.sh 쉘 스크립트 실행
- git pull 받은 후
- 가상환경 만든 것 activate
- 라이브러리 설치
- 아까 Streamlit을 runOnSave true로 설정해서 실행했기 때문에 파일이 바뀌면 rerun됨
+ 임시로 IP 할당했을 경우, 인스턴스를 중지했다가 다시 실행할 경우 IP가 변경됨
→ 고정 IP로 설정하면 인스턴스 중지 후 다시 실행해도 그대로 유지 가능
- VPC 네트워크의 IP주소에서 외부 고정 주소 예약
- 이름/설명/리전/연결대상 설정
- 네트워크 인터페이스에서 외부IP를 쓰고 있음을 확인할 수 있다.
- 인스턴스를 삭제하면 수동으로 고정주소 해제를 해줘야 한다.
'부스트캠프 AI Tech 4기' 카테고리의 다른 글
[Product Serving Part.5] Poetry로 프로젝트 생성 및 FastAPI 기초 (0) | 2023.01.16 |
---|---|
[Product Serving Part.5] 백엔드 프로그래밍 (0) | 2023.01.16 |
[Product Serving Part.4] Cloud (0) | 2023.01.13 |
[WEEK14/15/16] Open-Domain Question Answering 대회 Wrap-up 및 회고 (2) | 2023.01.13 |
[WEEK14/15/16] TIPS (0) | 2023.01.08 |