식혜야 2023. 6. 13. 22:07

230613 TUE

 

학습 주제 - Airflow 환경 구축을 위한 Docker와 K8S 실습 (2)

CI/CD 란?

Continuous Integration / Continuous Delivery, Deployment (지속적 통합 / 지속적 배포)

- 애플리케이션 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법이다.

- DevOps 엔지니어의 핵심 업무이다.

- git push나 git merge 시점이 CI/CD를 실행하기 위한 절호의 순간이다.

- Github에서는 이를 Actions라는 기능을 통해 Workflow라는 이름으로 구현이 가능하다.

- 기본 원칙

  • 코드 Repo는 하나만 유지(Master)
  • 코드 변경을 최대한 자주 반영
  • 테스트를 최대한 추가(Test Coverage)
  • 빌드를 계속적으로 수행(자동화)
  • 성공한 빌드의 프로덕션 릴리즈(자동화)

source: https://www.hanl.tech/blog/ci-cd-%EA%B8%B0%EB%B3%B8%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B0%80%EC%9E%A5-%EB%A7%8E%EC%9D%B4-%EC%93%B0%EC%9D%B4%EB%8A%94-%EB%8F%84%EA%B5%AC-5%EA%B0%80%EC%A7%80/

 

 

 

Github Actions

- 공식 문서 ↓↓↓

https://docs.github.com/en/actions

 

GitHub Actions Documentation - GitHub Docs

Automate, customize, and execute your software development workflows right in your repository with GitHub Actions. You can discover, create, and share actions to perform any job you'd like, including CI/CD, and combine actions in a completely customized wo

docs.github.com

- CI/CD를 Github에서 구현하기 위한 서비스이다.

- 코드 테스트, 빌드, 배포 자동화 기능을 제공한다.

- 하나의 자동화된 프로세스를 Workflow라 부르며 Events, Jobs, Actions, Runner로 구성된다.

- 내 글보다 훨씬 정리가 잘 되어있는 포스팅 ↓↓↓

https://zzsza.github.io/development/2020/06/06/github-action/

 

Github Action 사용법 정리

Github Action 사용법 및 cron 사용 방법에 대해 정리한 글입니다 Github Action으로 YES24 IT 신간을 파이썬으로 크롤링 후 Issue에 업로드하는 예제가 있습니다 Github Action with Python Github action with cron, Github a

zzsza.github.io

 

Workflow

- 트리거 이벤트가 발생하면 시작되는 일련의 동작들을 지칭한다.

- 트리거 이벤트 예시 : 코드 커밋(main과 같은 특정 브랜치를 대상으로만 제한 가능), PR 생성, 다른 Workflow의 성공적인 실행

- Workflow를 위한 명령어들은 YAML파일(환경 설정, scripts 실행 등)로 저장된다.

- Workflow는 Job들로 나누어지며, 각 Job은 일련의 step을 수행한다.

- 각 step은 윈도우나 리눅스 서버 위에서 runner에 의해 실행된다. (이 과정을 Docker Image에서 수행하는 것이 일반적인 서비스 배포 과정이 될 수 있다.)

 

YAML

- Yaml Ain't Markup Language의 약자로, Yaml은 마크업 언어가 아니라는 재귀적 말장난 같은 이름을 가지고 있다.

- Yet Another Markup Language라고도 한다.

- 확장자는 yaml, yml 둘 다 쓰인다.(동일하게 쓰임)

- JSON의 상위호환

- 하지만 데이터 직렬화가 불편하다는 단점이 있어 데이터 전송이나 API 등에서는 JSON을 더 많이 쓰는 추세이다.

- 나무위키: https://namu.wiki/w/YAML

 

YAML - 나무위키

일반적으로 설정파일로 사용하기에 더할 나위없이 좋은 형식이기 때문에 여러 프레임워크나 CI툴에서 설정파일로 쓰이고 있다. Flutter: dart패키지를 관리하기 위해 pubspec.yaml에 설정을 저장한다.d

namu.wiki

 

 

 

Docker와 Github Actions를 사용한 예제

Hangman 웹서비스를 사용하여 간단한 CI를 구현해 보자.

 

1. 먼저 https://github.com/learndataeng/hangman_web를 fork 하고 내 로컬 pc에 clone 하기

.
이후 알아서 로컬에 clone해라

 

2. Dockerfile 작성 후 push

FROM python:3.8-slim-buster
LABEL Maintainer="tmddjs112740@gmail.com"
WORKDIR /app
COPY app.py ./
COPY requirements.txt ./
RUN pip3 install -r requirements.txt
EXPOSE 4000
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0", "--port=4000"]


# 작성 후 fork 한 내 hangman_web에 push하기

 

3. Docker  Image 빌드 후 Docker Container로 실행해 보기

$ docker build --platform=linux/amd64 -t seungeonkim/hangman .
$ docker images
$ docker inspect seungeonkim/hangman
$ docker run -p 4000:4000 seungeonkim/hangman
$ docker run -p 4000:4000 -d seungeonkim/hangman
$ docker push seungeonkim/hangman

 

4. fork 한 내 hangman_web에서 Actions 탭 선택

.

 

5. CI Templates에서 Python application 찾아서 configure 클릭

.

 

 

6. .github/workflows/python-app.yml 편집 후 commit

# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Python application

on:
  push:
    branches: [ "main" ]	# 모든 브랜치에 적용하고 싶다면 ["main", "dev"]
  pull_request:
    branches: [ "main" ]	# 모든 브랜치에 적용하고 싶다면 ["main", "dev"]

permissions:
  contents: read

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python 3.10
      uses: actions/setup-python@v3
      with:
        python-version: "3.10"
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install flake8
        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
    - name: Lint with flake8
      run: |
        # stop the build if there are Python syntax errors or undefined names
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    - name: Test with unittest
      run: |
        python -m unittest discover -p 'test*.py'

- 편집 사항

  • Install dependencies라는 name을 가진 스텝 아래의 run 하위 내용에서, pip install flake8 pytest에서 pytest 삭제
  • 제일 마지막 name을 Test with unittest
  • 제일 마지막 name에서 python -m unittest discover -p 'test*.py'

- 코드 설명

  • on : 트리거 이벤트 지정. main 브랜치에 push 되거나 PR이 만들어지는 경우
  • jobs : 실제 CI 프로세스가 스텝(name) 별로 기술. 위의 예시는 빌드가 하나이다.
  • if 문은 requirements.txt 가 있으면 이를 설치하라는 뜻
  • 코드 전체를 찾아 test로 시작하는 모든 테스트를 실행

 

7. 다시 Github의 Actions 탭으로 가서 Docker image workflow를 찾고 configure 클릭

.

 

8. .github/workflows/docker-image.yml 편집 후 commit

name: Docker Image CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:

  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: docker login
      env:
        DOCKER_USER: ${{secrets.DOCKER_USER}} 
        DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
      run: |
        docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
    - name: Build the Docker image
      run: docker build --tag ${{secrets.DOCKER_USER}}/hangman:latest . 
    - name: docker push
      run: docker push ${{secrets.DOCKER_USER}}/hangman:latest

- 편집 사항

  • steps 하위 name 모두 수정

- 코드 설명

  • name이 docker login인 부분에서 Docker hub ID와 Password를 읽어와야 한다. 하드 코딩하지 않고 Github내에 저장할 것이다. (다음 과정에서 스크린샷으로 설명)

 

9. Github의 Setting 탭으로 이동 후 Secrets and variables - Actions에서 Docker Hub의 계정 정보 기입

.
.
.

 

10. Docker Image Workflow 실행 결과 확인

.

 

두 yml 파일을 하나로 줄일 수도 있다! (아직 안 해봄)

.

 

 

 

 

TMI

다시 복습하면서 보니 한 번에 너무 많은 내용을 배우긴 했다(내 기준..),,,^^

++ 사진 왜 하나도 안 보이냐 티스토리야?????????????????????????