[프로그래머스] 데브코스 데이터엔지니어링 TIL Day 47

주재민·2023년 12월 19일
0
post-thumbnail

📖 학습주제

개발환경 구축을 위한 Docker와 K8S 실습 (2)


웹 서비스를 Docker로 실행해보기

웹서비스를 Docker로 구동해보는 전체 과정

hangman_web이라는 repo의 main에 코드가 머지될 때마다 다음을 수행

  1. 테스트 수행
  2. Docker Image 빌드
    • 이를 위해 Dockerfile 부터 만들어볼 예정
  3. Docker Image를 Docker Hub로 푸시

위 과정을 Github repo에 Github Actions으로 구현

Hangman 프로그램

https://github.com/learndataeng/hangman_web

  • hangman 프로그램을 flask를 사용하여 웹으로 노출
    - 포트번호는 어디든 바인딩 가능하며 실행할 때 지정
    - flask 관련 모듈 설치가 필요함: requirements.txt
  • 실행 방법
    - python3 -m flask run --host=0.0.0.0 --port=4000
    이 경우 app.py를 기본으로 사용함

Repo 구성 설명

  • app.py
from flask import Flask,session
app = Flask(__name__)
…
app.secret_key = "Python Study"
if __name__ == "__main__":
 app.run()

flask의 메인 함수가 있고 커맨드라인으로 받은 포트에 바인드하고 요청이 들어오기를 기다림

  • requirements.txt
Flask==2.3.2
Flask-HTTPAuth==4.5.0
Flask-Login==0.6.2
Flask-SQLAlchemy==3.0.3

pip3 install -r requirements.txt flask 모듈들을 설치함

  • test.py
    app.py에 있는 코드의 유닛 테스트 로직이 들어가 있음.
    CI/CD 구성시 실행이 되게 구성할 예정
  • README.md

Hangman 서비스를 Docker Image로 구성

Docker 컨테이너 내부 프로세스와 호스트 프로세스간의 통신

  • Docker 컨테이너 내부 프로세스가 오픈한 포트번호는 바깥 프로세스에는 안 보임
    - 예를 들어 4000번 포트는 호스트 프로세스 브라우저에게는 안 보임

  • 포트맵핑 : Docker 컨테이너 내부 프로세스가 오픈한 포트번호를 외부로 노출해주는 것
    - docker run 수행시 -p 옵션 사용 (docker run -p 4000:4000 이미지이름)
  • Docker 컨테이너를 실행할 때 포트 맵핑을 통해 호스트 운영체제 단에서 접근되는 포트를 컨테이너쪽으로 포워드해주어야함

hangman repo에 Dockerfile 추가하기

FROM python:3.8-slim-buster
LABEL Maintainer="*****"  #메타데이터로 docker inspect 명령으로 찾아볼 수 있음
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"]

전체 과정 데모

  • 과정에서 사용해볼 일부 docker 명령
    - docker inspect 명령
    - docker run "-d" 옵션
    - docker stop 명령

순서:

  • docker build --platform=linux/amd64 -t keeyong/hangman .
  • docker image ls
  • docker inspect keeyong/hangman
  • docker run -p 4000:4000 keeyong/hangman
  • docker run -p 4000:4000 -d keeyong/hangman
  • docker push keeyong/hangman

CI/CD와 Github Actions

소프트웨어 빌드

  • 자신(혹은 팀)이 개발한 소프트웨어를 최종적으로 출시하기 위한 형태로 만드는 것
    - 테스트가 빌드의 중요한 일부로 포함
  • 참여 개발자들이 많을수록 이는 더 중요
  • 개발이 끝나기 전부터 빌드를 하면 소프트웨어의 안정성 증대
    - Continuous Integration!

Continuous Integration

  • Software Engineering Practice의 하나
  • 기본 원칙
    - 코드 Repo는 하나만 유지 (Master)
    - 코드변경을 최대한 자주 반영
    - 테스트를 최대한 추가
       Test Coverage
    - 빌드를 계속적으로 수행 (자동화)
       Commit Build vs. Nightly Build
    - 성공한 빌드의 프로덕션 릴리스 (자동화)
       CD: Continuous Delivery

CI/CD

Git

  • 분산환경을 지원하는 소스 버전 컨트롤 시스템
    - CVS, SVN은 항상 서버에 연결되어 있다는 전제하에서 사용 가능 (중앙 개발)
  • 리눅스를 만든 Linus Torvalds가 개발
    - 리눅스 커널 개발을 위해 만들었으며 GPL v2 오픈소스
  • SVN/CVS에 비해 현저하게 빠르나 사용법은 훨씬 더 복잡함

장점

  • 다수의 개발자가 공동 개발
  • 코드 리뷰 가능
  • 코드 백업
  • 과거의 코드로 롤백 가능
  • 팀원들과 코딩을 같이 할 수 있고 코드 충돌이 생기면 이를 해결가능 (구글닥처럼)
  • 코드변경을 주기적으로 저장하면서 리뷰를 받을 수 있음
  • 모든 코드 변경이 기록 (백업)
  • 지금 코드의 스냇샵을 잡아 (이를 버전이라 부름) 나중에 필요시 버전간 이동이 가능
  • 사실 이런 모든 작업을 꼭 코드 뿐만 아니라 모든 텍스트 파일에 사용 가능

Git 사용시 필요한 것

  • 직접 git을 사용한다면 git이 설치된 컴퓨터와 저장 공간
  • 클라우드 버전 사용 (GitHub, BitBucket, GitLab 등등)
    - 클라이언트는 별도 설치
    - Github이 가장 인기가 많음

Github

  • Git repo 호스팅/클라우드 서비스 (http://github.com)
    - 대부분의 회사들이 Git을 직접 설치해서 사용하기 보다는 github을 사용
  • Git은 텍스트 커맨드라인 툴이지만 Github은 웹기반 인터페이스도 제공 (일부)
  • 자신이 만든 repo들이 모두 public일 경우 사용이 무료
    – private repo의 수에 따라 가격대가 결정됨
    – 개발자들을 위한 Facebook!
  • 다양한 툴을 제공하여 생태계 마련
    – Code 개발 생산성 증대를 위한 Copilot
    – CI/CD등의 다양한 연동을 위한 Workflows 제공
    – 또한 문서화를 위한 Wikis와 버그리포트와 트랙킹을 위한 Issues 기능을 제공

Git 관련 용어

  • Repo : Repository의 준말로 Git으로 관리되는 소프트웨어 프로젝트를 지칭
  • Master/Main : 한 Repo에서 기본이 되는 메인 코드를 지칭. Git에서는 master이고 github에서는 이제 main
  • Branch : 자신의 Repo에서 새로운 기능 개발등을 위해 Master 혹은 다른 Branch로부터 만든 코드 작업본을 지칭. 작업 후 나중에 원본 Branch와 다시 병합하려는 목적으로 만들어짐
  • Clone : 다른 계정에 존재하는 repo로부터 새로운 local repository를 만드는 것
  • Commit (Check-in) : 내가 만든 코드 변경을 Branch의 Local Repository에 반영하는 것
  • Pull : Master와 같은 Remote Repo로부터 마지막 Pull이후 변경된 것을 다시 가져오는 작업. 즉 Master(혹은 Branch)와 씽크하는 것을 지칭
  • Push : 작업 중인 로컬 복사본 (Local Repo)에서 서버(Remote Repo)로 변경사항들을 복사하는 것을 지칭
  • Merge : Pull이나 Push했을 경우 두 Branch(대부분 이 중 하나는 Master)간의 충돌(Conflict)을 해결하는 과정

메인/마스터 브랜치

  • Github에서는 이전에 master라 불렀고 지금은 main이라 부르는 source of truth가 되는 특별한 branch
  • 특정한 기능을 구현하기 위해 만들어진 mainline의 복사본. 구현과 테스트가 이뤄진 후에 main branch와 머지됨

전체플로우

Push나 Merge 시점이 CI/CD를 실행하기 위한 절호의 순간

  • 코드가 메인/마스터나 브랜치에 추가되는 순간 CI/CD를 트리거
    - 이를 특정 메인/마스터나 특정 브랜치만 대상으로 하도록 설정 가능
    - 이 때 테스트 수행하고 최종적으로 Docker Image등을 만들도록 하는 것이 가능
    - 그래서 CI/CD는 Github에 구현하는 것이 가장 자연스러움
  • Github에서는 이를 Actions라는 기능을 통해 Workflow라는 이름으로 구현 가능

Github Actions

  • CI/CD를 Github위에서 구현하기 위한 서비스
    - 코드 테스트, 빌드, 배포 자동화 기능 제공
  • Workflow라 부르며 아래 컴포넌트로 구성
    - Events
    - Jobs
    - Actions
    - Runner
       Github hosted runners
       Self hosted runners

Workflow

  • 트리거 이벤트가 발생하면 시작되는 일련의 동작들을 지칭
    e.g.)
    코드 커밋 (main과 같은 특정 브랜치를 대상으로만 제한 가능)
    PR 생성
    다른 Workflow의 성공적인 실행
  • Workflow를 위한 명령어들은 YAML 파일로 저장
    - 명령어들로는 환경설정과 scripts 실행들이 대표적
  • Workflow는 Job들로 나눠지며 각 Job은 일련의 스텝을 수행
    - 각 스텝은 하나 혹은 그 이상의 명령어를 실행
       이 명령어는 actions라고 부르는 명령어들의 집합이 될 수도 있음
    - 각 스텝은 윈도우나 리눅스 서버 위에서 runner에 의해 실행
       이걸 Docker Image에서 수행하는 것이 서비스 배포 과정에 따라 더 일반적이기도 함

0개의 댓글