[ProductServinng] Day76_Cloud,Github Action

윰진·2023년 1월 9일
0

NaverAIBoostCamp정리

목록 보기
23/30

2-4강 Cloud

GOAL

  • Cloud Computing 에 대한 내용을 Google Cloud Platform 을 통해서 학습
    • 각 서비스들의 목적성에 집중하여 수강하기

Further Question

  • Compute Engine 인스턴스 띄우고 삭제해보기
  • Compute Engine 인스턴스에서 Shell Command 연습하기
  • Cloud Storage Bucket 생성하고 파일 업로드, 삭제해보기
  • Python Cloud Storgage API 를 사용해 Cloud Storage 에 업로드한 파일을 파이썬에서 사용하는 코드 작성 ( 참고자료 - Python Client for Google Cloud Storage API )

뒷 강의에서 할 것

  • Instance 생성하고 IP 고정하기
  • 방화벽 설정하기

✨ Cloud Service 를 사용하면 확장성 및 물리적 제약이 줄어든다.

Cloud Computing Service 는 Infrastructure-as-a-Service, Platforms-as-a-Service, Software-as-a-Service 의 3가지 기본 유형에 해당하는 서비스를 제공한다.

  • PAAS 의 경우, 파일을 제공하면 서버에 띄워준다.
  • IAAS 의 경우, 서버를 띄우는 것부터 직접 다한다.

https://www.redhat.com/ko/topics/cloud-computing/iaas-vs-paas-vs-saas

1. Cloud 서비스의 다양한 제품

Computing Service(Server) : 가상 컴퓨터, 서버
Serverless Computing : Computing Service 와 유사하지만, 서버 관리를 클라우드 쪽에서 진행한다.

  • 클라우드에 제출한 코드를 서버에서 실행해준다.
    • 요청 부하에 따라 자동으로 확장된다. Auto Scaling

Object Storage : 다양한 Object 를 저장할 수 있는 저장소, 다양한 형태의 데이터를 저장할 수 있고, API 를 사용해 데이터에 접근할 수 있다.

  • pkl, csv, log file 등을 Object Storage 에 저장할 수 있으며 이 정보를 파싱하여 대시보드 및 시각화를 진행한다.

Database(RDB) : 서비스에서 사용하는 데이터의 경우 Database 에, 분석용 데이터는 Object Storage 에 저장한다.
Data Warehouse : Database + Object Storage {\rightarrow} 데이터 분석에 특화
AI Platform : AI Research, AI Develop 과정을 편리하게 해주는 제품으로 MLOps 관련 서비스를 제공한다.

2. GCP 사용하기

1 ) Compute Engine

a ) Compute Engine 메뉴 클릭

b ) Compute Engine Instance 생성

2 ) Cloud Storage ( 버킷 )

a ) Cloud Storage 메뉴 클릭

b ) Cloud Storage Instance 생성

3. Special Mission

  • Compute Engine 인스턴스 띄우고 삭제해보기
  • Compute Engine 인스턴스에서 Shell Command 연습하기
  • Cloud Storage Bucket 생성하고 파일 업로드, 삭제해보기
  • Python Cloud Storgage API 를 사용해 Cloud Storage 에 업로드한 파일을 파이썬에서 사용하는 코드 작성 ( 참고자료 - Python Client for Google Cloud Storage API )

1 ) Cloud Storage 에 업로드한 파일을 파이썬에서 사용하는 코드 작성하기 ( feat. Python Cloud Storage API )

참고

a ) Compute Engine 환경 설정

Python 3.9.2

sudo apt install python-setuptools
sudo apt-get install python3-pip

sudo pip install virtualenv
virtualenv <your-env>
<your-env>\Scripts\activate
<your-env>\Scripts\pip.exe install google-cloud-storage

b ) Blob 다운로드

from google.cloud import storage
import io

def download_blob_to_stream(bucket_name, source_blob_name, file_obj):
    """Downloads a blob to a stream or other file-like object."""

    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"

    # The ID of your GCS object (blob)
    # source_blob_name = "storage-object-name"

    # The stream or file (file-like object) to which the blob will be written
    # import io
    # file_obj = io.BytesIO()

    storage_client = storage.Client()

    bucket = storage_client.bucket(bucket_name)

    # Construct a client-side representation of a blob.
    # Note `Bucket.blob` differs from `Bucket.get_blob` in that it doesn't
    # retrieve metadata from Google Cloud Storage. As we don't use metadata in
    # this example, using `Bucket.blob` is preferred here.
    blob = bucket.blob(source_blob_name)
    blob.download_to_file(file_obj)

    print(f"Downloaded blob {source_blob_name} to file-like object.")

    return file_obj
    # Before reading from file_obj, remember to rewind with file_obj.seek(0).

def main():
    target_file = io.BytesIO()
    target_obj = download_blob_to_stream("your bucket name","target file name", target_file)
    target_obj.seek(0)
    # Write the stuff
    with open("output.txt", "wb") as f:
        f.write(target_obj.getbuffer())

c ) pandas 와 Cloud Storage

pip install gcsfs
from google.cloud import storage
import pandas as pd
import io

def main():

    training_file_path = 'gs://level3-example/jjinmack2.csv'
    train_df = pd.read_csv(training_file_path, encoding='utf-8')
    
    print(train_df.head())

if __name__ == "__main__" : 
    main()

d ) gsutil 사용하기

gsutil cp gs://level3-example/jjinmack2.csv mydata.csv

e ) 참고 : gsutil 과 python

2-5강 Github Action을 활용한 CI/CD

GOAL

  • CI/CD(Continious Integration/Continuous deploymen) 로 자동화하기

Further More

  • Github Action Workflow 만들기
  • Github Action을 사용해 Voila, Streamlit 코드 배포하기
  • 나만의 Jupyter Notebook Server 만들기
  • Github Action의 결과를 Slack 채널에 메세지 보내기(배포 실패, 배포 성공 등)
  • 특정 Branch가 main에 Merge된 경우 Branch 자동으로 삭제하는 Github Action 만들기

1. CI/CD

일반적으로 main<>prod server, stating<>staging server, dev<>dev server, feat/기능 이름

  • Continuous Integration(CI)
    • 빌드, 테스트 자동화
  • Continuous Deploy/Delivery
    • 배포 자동화
    • 작성한 코드가 항상 신뢰 가능한 상태가 되면 자동으로 배포될 수 있도록 하는 과정
    • dev / staging / main 브랜치에 merge 가 될 경우 코드가 자동으로 서버에 배포됨

2. Github Action - Workflow

1 ) Test Code

2 ) 배포

  • Prod, Staging, Dev 서버에 코드 배포
  • FTP 파일 전송, Docker Image Push
  • Node.js 등 다양한 언어 배포 지원

3 ) 파이썬, 쉘 스크립트 진행

https://github.com/actions/setup-python

  • Github Repo 에 저장된 스크립트를 일정 주기를 가지고 진행
  • crontab 의 대용
  • 데이터 수집을 주기적으로 해야할 경우 활용할 수 있음

4 ) Github Tag, Release 자동으로 설정

  • Main 브랜치에 Merge 될 경우에 특정 작업 실행
  • 기존 버전에서 버전 올리기
  • 새로운 브랜치 생성시 특정 작업 실행도 가능

5 ) 그 외 다양한 workflow

원하는 기능이 있는 경우 <기능> github action 등으로 검색해보자

Action Marketplace : https://github.com/marketplace?type=actions
Awesome Github Action : https://github.com/sdras/awesome-actions

제약 : 하나의 레포 당 최대 20개의 workflow 등록 가능하고 job 은 최대 6시간 수행 가능, 동시 실행 가능한 workflow 의 수 제한 있음

6 ) Github Action 사용 방식

a ) 코드 작업

b ) 코드 작업 후, Github Action으로 무엇을 할 것인지 생각

c ) 사용할 Workflow 정의

d ) Workflow 정의 후 정상 작동하는지 확인

3. Github Action Core

Workflow, Event, Job, Step, Action, Runner

name: CICD-SSH
on:
  push:
      branches: [ main ]
      paths:
        - 'part2/04-cicd/**'

jobs:
  build:
    runs-on: ubuntu-latest
  steps:
    - uses: 8398a7/action-slack@v3
      with:
        status: ${{ job.status }}
        fields: repo,message,commit,author,action,eventName,ref,workflow,job,took,pullRequest # selectable (default: repo,message)
      env:
        SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required
      if: always() # Pick up events even if the job fails or is canceled.

1 ) Workflow

  • Event 로 Trigger 되는 여러 Job 으로 구성된 자동화 Process
  • 최상위 개념으로 YAML 파일로 작성되며, Github Repository의 .github/workflows 폴더에 저장

2 ) Event

  • Workflow를 Trigger하는 특정 활동, 규칙
  • 예를 들어
    • 특정 Branch로 Push하는 경우
    • 특정 Branch로 Pull Request하는 경우
    • 특정 시간대에 반복(Cron)

3 ) Jobs

  • Runner에서 실행되는 Steps의 조합
  • 여러 Job이 있는 경우 병렬로 실행하며, 순차적으로 실행할 수도 있음
    • 다른 Job에 의존 관계를 가질 수 있음(A Job Success 후 B Job 실행)

4 ) Steps

  • Step은 Job에서 실행되는 개별 작업
  • Action을 실행하거나 쉘 커맨드 실행
  • 참고 하나의 Job에선 데이터를 공유할 수 있음

5 ) Action

  • Workflow의 제일 작은 단위
  • Job을 생성하기 위해 여러 Step을 묶은 개념
  • 재사용이 가능한 Component
  • 직접 Action을 만들 수도 있고, Marketplace의 Action을 사용할 수도 있음

6 ) Runner

  • Github Action도 일종의 서버에서 실행됨
  • {\rightarrow} Workflow가 실행될 서버
    • Github-hosted Runner : Github Action의 서버를 사용하는 방법
      • 성능 : vCPU 2, Memory 7GB, Storage 14GB
    • Self-hosted Runner : 직접 서버를 호스팅해서 사용하는 방법

4. ✨ 예시 : Product Serving Part2 를 이용해 gitaction 적용해보기

단계

  • Compute Engine 실행
  • SSH 키 생성 및 Github Secrets 설정
  • 터미널에서 최초로 서비스 실행
  • Github Action 을 통한 배포 자동화

참고 : pip 없으면 설치

sudo apt install python-setuptools
sudo apt-get install python3-pip

1 ) Cloud Engine 설정

2 ) SSH Key 생성하기

cd ~/.ssh/
ssh-keygen -t rsa -b 4096 -C "email"
passphrase 는 enter

browser 에서 server 열기

3 ) SSH Key 등록하기

authorized_keys 에 public key 가 등록되면 외부에서 접근 가능하다.
cat id_rsa.pub >> authorized_keys 
하지만, GCP 는 주기적으로 authorized_keys 파일을 삭제해서 외부에 키 파일을 등록하는 과정이 필요하다.
cat id_rsa.pub

Metadata 에 SSH Key 등록하기

SSH Key 등록하면 왼편에 아이디가 뜸 ( 정상 )

Github 에 Secret 등록

  • HOST : External IP
  • USERNAME : ID
  • SSH_KEY : vi id_rsa 전문

**(참고) Github Action 에서 Secret 활용할 수 있다.

5 ) Cloud Engine 에서 Repository 설정하기

git config --global credential.helper store
git clone {glone repository}

sudo apt-get update
sudo apt-get install3.8-venv -y

폴더 이동
cd CI/CD

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

error: invalid command 'bdist_wheel'은 무시해도 됨 ( 10분 가량 소요 ) 

6 ) Streamlit 실행하기

/usr/bin/nohup streamlit run app.py --server.runOnSave true &

cat nohup.out

7 ) Compute Engine 방화벽 규칙 설정하기

8 ) github action

참고 Repository 명과 폴더 명이 일치해야 한다.

  • cd ${{ github.event.repository.name }}/part2/04-cicd
.github/workflows/deploy_ssh.yml
name: CICD-SSH
on:
  push:
      branches: [ main ]
      paths:
        - 'part2/04-cicd/**'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: executing remote ssh commands using ssh key
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }} 
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        port: 22
        script: |
            cd ${{ github.event.repository.name }}/part2/04-cicd
            sh deploy_ssh.sh

9 ) Done

error .ssh : handshake error 가 뜨면 SSH_KEY 값을 다시 한 번 잘 입력해보자.

main branch 와 merge 되었을 때 자동으로 반영이 된다.

참고 ) IP 고정하기

주의 고정되지 않은 IP 는 인스턴스가 재실행될 때 마다 변경된다.
{\rightarrow} Reserve 를 눌려서 고정 IP 를 할당 받으면 된다.

  • 인스턴스가 하나도 없을 때 요금이 부과되기 때문에 주의

이 글은 커넥트 재단 Naver AI Boost Camp 교육자료를 참고했습니다.

0개의 댓글