[데이터 엔지니어링 데브코스 2기] TIL-11주차-파트02 개발환경 구축을 위한 Docker와 K8S 실습 (1)

이재호·2023년 12월 18일
0

1. Airflow 운영 상의 어려움


만약 관리해야 하는 DAG의 수가 100개를 넘어간다면 어떨까. 아마 다음과 같은 이슈들이 발생할 것이다.

  • 데이터 품질 및 데이터 리니지 이슈.
  • 라이브러리 충돌.
  • Worker의 부족.
  • Worker 서버들의 관리와 활용도 이슈.
  1. 라이브러리 충돌

    • DAG에 따라 실행에 필요한 라이브러리/모듈이 다르니 DAG 혹은 Task를 위한 별도의 독립 공간(Docker Container)에서 실행해야 함.
    • 코드를 Docker Image화 -> Docker Container
  2. Worker의 부족

    • Scale Out 시에 서버가 증설되다 보니 이를 관리하기 위한 방법이 필요하다.
    • K8s와 같은 컨테이너 기술이 필요하다.
  3. 낮은 Server Utilization 이슈

    • 놀고 있는 서버를 관리해야 한다.
    • 서비스별로 Capacity를 관리해야 함.
    • K8s로 해결할 수 있음.

해결책.

  • 태스크나 대그 코드를 Docker Image로 만들어서 Docker Container 형태로 실행.
  • Airflow Worker를 K8s에서 필요한 대로 동적으로 할당하여 사용.

Airflow Executor란?

  • 태스크들을 관리하고 실행하는 역할 수행.
  • 병렬 혹은 직렬 실행, 어느 worker에서 실행할 지 등등.
  • 다양한 Executor 타입이 존재함.
    -
    • Sequential Executor : 디폴트로 설치되면 sqlite와 같은 싱글 스레드 디비에서만 사용 가능.
    • Local Executor : 태스크들을 airflow 마스터 노드 안에서 실행.
    • Celery Executor : 다수의 worker 노드의 경우, Celery 큐를 사용해 태스크 분산.
    • Kubernetes Executor : K8s 클러스터를 사용하여 태스크 분산.
    • Local Kubernetes Executor와 Celery Kubernetes Executor도 존재함.

2. Docker 소개


  • 내가 만든 프로그램이 다른 컴퓨터에서 돌아가게끔 해 줌. (라이브러리/모듈, 환경 설정, 중요 파일 등을 Docker Image화 함.)
  • Docker Image : 독립적으로 완전하게 만들어진 패키지.
  • Docker Container : 빌드된 Docker Image를 독립된 환경에서 실행한 것.
  • VM(AWS EC2)의 경우 컴퓨터의 OS 시스템에서 실행되는 개념이지만, Docker의 경우 Docker 엔진에서 실행되는 개념이기에 더욱 lite하다는 장점이 있다.
  • Docker File -> 빌드 -> Docker Image -> 실행 -> Docker Container.
  • 윈도우 앱이나 맥 앱과 같은 GUI 소프트웨어를 개발할 때는 플랫폼 차이 상 제대로 구현하기가 힘들다는 단점이 있음. 대신 이 경우 VM 사용.

Docker Desktop vs. Docker Engine

  • Docker Desktop은 Docker Engine과 더불어 여러 편리한 기능들도 같이 실행 가능한 앱이다.

3. Docker 개발 프로세스


하이 레벨에서의 프로세스.
1. 대상 소프트웨어 선택. (다수의 컴포넌트(이미지)가 필요한 소프트웨어인지 하나의 컴포넌트가 필요한 소프트웨어인지)
2. 이를 Docker Image로 빌드. Dockerization.
-
- Dockerfile이라는 텍스트 파일로 세부 정보를 기술.
- 하나의 Docker Container 안에서 실행.

Docker Image의 구성 요소.

  • 기본 OS 혹은 기본 소프트웨어 환경.
  • 코드.
  • 라이브러리.
  • 파일 시스템 스냅샷(필요한 파일).
  • 환경 설정 변수. 빌드용과 실행용 두 가지.
  • 메타 데이터. 이미지에 대한 정보.

Docker Image의 실행.

  • 독립된 공간인 Container에서 실행.
  • docker run ...으로 실행.

Docker Image의 등록 : Docker Hub.

  • Docker Registry라는 Docker Image들의 보관소가 있음. (docker hub이 가장 유명함.)
  • 개발자 서버에서 Docker Image 개발 -> Registry에 등록 -> 프로덕션 서버에서 실행.

Docker Hub.

  • https://hub.docker.com/
  • 계정이 필요하며, Docker Desktop과 연동해 주어야 함.
  • Public 혹은 Private Repo. 제공.
  • Official Images라는 인증 태그가 있음.
  • Github과 연동을 통해 자동화된 빌드 기능 제공.

4. Docker 실습


4-1. Hello World


// app.js

console.log("Hello Docker!");

Dockerfile 생성.

  • Docker에게 소프트웨어 설치 명령을 기술.
  • 베이스 이미지(OS, 언어 등) 기술. (FROM)
  • 코드 복사.
  • 코드 실행.
FROM node:alpine # node의 alpine이라는 OS type을 베이스 이미지로 지정. 해당 이미지를 Registry에서 다운로드 받아서 사용함.
COPY ./app # 코드 복사 명령어.
WORKDIR /app # 실행 디렉토리.
CMD node app.js # "node app.js" 명령어 실행.

Dockerfile 기타 키워드.

  • ARG : 최종 이미지에 저장되지 않는 컨테이너가 실행될 때 사용되는 환경 변수.
  • ENV : 최종 이미지에 저장되는 컨테이너가 실행될 때 사용되는 환경 변수.
  • USER : 컨테이너를 실행하는 (리눅스) 유저 ID.
  • EXPOSE : 웹 서비스의 경우 사용되는 포트 번호.
  • RUN : 이미지를 빌드할 때 필수적으로 실행되어야 하는 명령어(docker build). (RUN apt-get update && apt-get install -y curl)

CMD vs. ENTRYPOINT.

  • 두 개 모두 컨테이너가 시작할 때 실행되어야 하는 명령어 지정.
  • 두 개 모두 한 dockerfile에서 여러 번 실행되면 마지막 것만 실행됨.
  • 우선 순위는 ENTRYPOINT가 더 높음.
  • 웬만하면 CMD만 사용하는 것을 권장함.

CMD 예시.

FROM debian:buster
COPY ./myproject
RUN apt-get upgrade ...
CMD ["./cmd1.sh"]

라는 dockerfile에 대해서,

  • docker run my-image라고 실행하면, ./cmd1.sh가 실행됨.
  • docker run my-image cmd2.sh라고 실행하면, cmd2.sh가 실행됨.

CMD + ENTRRYPOINT 예시.

FROM debian:buster
COPY ./myproject
RUN apt-get upgrade ...
ENTRYPOINT ["entrypoint.sh"]
CMD ["param1", "param2"]

라는 dockerfile에서,

  • docker run my-image : "entrypoint.sh param1 param2"
  • docker run my-image cmd2 : "entrypoint.sh cmd2"
  • docker run --entrypoint="/cmd3.sh" my-image : "/cmd3.sh param1 param2"

웬만하면 CMD만 사용하는 것을 권장.

Docker Image 생성.

  • docker build --platform linux/amd64 -t hello-world-docker:{버전. default="latest"}.
  • --platform : Apple M1 chip 관련 이슈.
  • -t : 태그 지정.
  • docker build 명령이 실행되면 RUN 명령이 실행됨.
  • docker image ls로 Docker Image 생성 확인.

Docker Container로 실행.

  • docker run hello-world-docker.

Docker Registry에 등록.

  • 위 이미지를 생성한 상태에서, Docker Hub에 Repo를 생성.
  • docker tag hello-world-docker:latest ho99/hello-world-docker:latest로 현재 이미지의 repo 이름을 jaeho/hello-world-docker로 변경.
  • docker login --username=ho99 로 유저 정보 저장.
  • docker push ho99/hello-world-docker로 docker hub에 푸시함.

docker run vs. docker exec.

  • docker run은 새로운 Container를 실행하는 것.
  • docker exec는 실행된 Container에 작업을 하는 것.
  • 두 명령 모두 --user root 혹은 -u root로 루트 유저로 연결 가능.ㄹ

4-2. Ubuntu


우분투는 리눅스의 가벼운 버전이며, 다음과 같이 docker로 실행 가능하다.

  • docker run ubuntu
  • docker ps : 현재 실행 중인 프로세스.
  • docker ps -a : 현재 + 이전에 실행된 프로세스.
  • docker run -it ubuntu : 우분투 배쉬 실행.

4-3. MySQL 연동


  • docker pull mysql/mysql-server:8.0으로 MySQL 도커 이미지 설치.
  • docker run --name=mysql_container mysql/mysql-server:8.0으로 이미지 이름을 mysql_container로 수정.
  • docker logs mysql_container 2>&1 | grep GENERATED로 루트 계정 패스워드 확인.
  • docker exec -it mysql_container mysql -uroot -p로 MySQL shell 실행.
profile
천천히, 그리고 꾸준히.

0개의 댓글