[TIL 49일자] 데브코스 데이터엔지니어링

·2023년 6월 16일
0

데브코스

목록 보기
45/55
post-thumbnail

📚 오늘 공부한 내용

1. dockerignore

  • Image build를 할 때 추가하지 말아야 할 혹은 필요하지 않을 파일들이나 폴더들을 지정해 준다.
  • 빌드 프로세스를 짧게 가고, 이미지의 크기가 너무 커지는 것을 방지하기 위함이다.
  • 보통 이런 내용이 .dockerignore에 들어가며 운영을 하면서 추가가 가능하다.
*.pyc
project.lock.json
bin/
obj/
.vs/
node_modules/
.git
.cache
logs/
*.md
**/*.class
  • Dockerfile에서 COPY 명령
    • 실수로 불필요한 파일 혹은 민감한 정보가 들어 있는 파일들이 이미지로 들어가는 걸 막으려면 COPY 명령을 할 때 전체 폴더나 파일을 할 게 아니라 일일이 파일이나 폴더별로 적어 주는 것이 좋음.
    • 전체를 그냥 COPY 할 시 예상하지 못하게 불필요하거나 중요한 정보들이 들어가 노출될 수 있음.
    • 이러한 이유로 COPY 명령어 사용 시 매번 check 해 주는 로직이 매우 중요해진다.

2. Docker-compose

1) Docker-compose란?

  • 다수의 Container로 소프트웨어가 구성되는 경우 사용할 수 있는 툴 + 환경 설정 파일
  • 보통 docker-compose.yml 혹은 docker-compose.yaml로 설정한다.
  • dev, test, prod 등 다양한 버전을 만드는 것이 일반적이다.
  • 개별 Container를 따로 관리하는 것보다 훨씬 더 생산성이 높다.
  • 하지만 그만큼 배워야 할 것도 많고 복잡해진다.
  • 사용법 자체는 간단하고 명령을 실행하면 소프트웨어를 구성하는 모든 컨테이너에게 적용된다.
    • docker-compose build
      • build 키로 지정된 것들 대상
    • docker-compose up
      • build => create => start
    • docker-compose pull
      • docker hub에서 이미지들을 읽어오려고 함
    • docker-compose ps
    • docker-compose down
      • stop => remove
    • docker-compose start
    • docker-compose stop
    • docker-compose rm
  • Docker Desktop의 일부로 설치된다.
  • Docker Compose v.1.27+부터 v2와 v3가 합쳐졌는데 $docker-compose --version으로 버전 확인을 할 수 있다.

  • service
    • 프로그램을 구성하는 서비스들을 지정
    • 각 서비스는 별개의 Docker Image 지정과 Docker Container 실행으로 구성됨
    • 각 서비스는 자신의 Dockerfile을 가지고 있어야 함
    • 아니면 docker hub 등에서 이미지 다운로드
    • 서비스별로 포트 번호, 환경 변수, 디스크 볼륨 등을 지정해야 함
    • 서비스 이름은 아무 이름이나 가능
  • volumes
    • 앞서 사용된 docker volume을 지정
    • 필수는 아님
  • network
    • 앞서 사용된 network를 지정
    • 필수는 아님

2) docker-compose.yml 작성 예

services:
 frontend:
 build: ./frontend
 ports: #해당 포트로 forwarding
 - 3000:3000
 backend:
 build: ./backend 
 ports:
 - 3001:3001 
 environment:
 DB_URL: mongodb://database/vidly 
 database:
 image: mongo:4.0-xenial #offical image 
 ports:
 - 27017:27017
 volumes: #volume을 지정 
 - vidly: /data/db #vidly라는 이름으로 지칭, db로 마운팅
volumes:
 vidly:
#만약 networks가 필요하다면 volumes와 같은 레벨로 작성
  • network을 지정하지 않았지만 하나의 docker-compose.yml에 포함된 Container끼리는 서로 접근 가능하다.
  • 즉, 일일이 network 설정을 해 주지 않아도 docker-compose.yml 내에서 이름만으로 호출 가능하다.

3) docker-compose 네트워킹

  • docker끼리 네트워크 연결이 필요한 경우
    • services에 준 이름으로 호스트 이름이 생성된다.
    • 내부 DNS 서버가 하나 생성되어 이름을 내부 IP로 변환해 준다.
  • 별도의 네트워크를 구성하고 싶다면
    • networks에 네트워크를 나열하고 네트워크 서비스를 지정해 준다.

4) 실습

  • docker-compose -f docker-compose.mac.yml build를 하면 세 개의 이미지가 build 된다.
  • 공식 이미지를 build 해 주기 위해 docker-compose -f docker-compose.mac.yml pull을 해 주면 다음과 같이 공식 이미지도 build 된 것을 볼 수 있다.
  • docker-composer up을 해 주면 build, create, start 명령어를 한 번에 실행해 주는 명령어이다.
  • 48일자 실습에서는 postgreSQL이 제대로 돌지 않아 투표는 되지만 투표 결과가 반영이 안 됐는데 docker-compose 실습에서는 투표 결과가 제대로 반영되는 것을 볼 수 있다.
  • docker-compose -f docker-compose.mac.yml down를 통해 모든 컨테이너를 중지 및 삭제해 준다. 다만 down을 사용하는 경우 stop 명령과 remove 명령이 순차적으로 실행되지만 Container만 삭제되고 Image는 삭제되지 않는다.

📌 postgres Container 확인

  • docker exec -it --user=postgres example-voting-app-db-1 sh를 통해 postgres Container에 접근한다.
  • $whoami를 입력하면 접근 계정이 나오게 된다.
  • $psql을 입력하면 postgres shell이 실행된다.
  • \c를 통해 database와 user 정보를 모두 볼 수 있고 \dt를 통해 스키마와 테이블을 볼 수 있다.

3. docker-compose.yml 서비스 개선

1) depends on

  • 서비스 간의 의존성이 있을 경우 먼저 실행되어야 하는 서비스를 depends_on을 통해 기술한다.
  • condition 뒤에 붙는 것은 조건이며 선수행의 서비스가 조건에 충족할 때 해당 서비스가 실행된다. (필수 아니고 옵션)
  • 즉, 예시를 들자면 vote라는 서비스는 redis 서비스가 service_healthy할 때 실행된다.
  vote:
    build: ./vote  
    command: python app.py
    depends_on:
      redis:
        condition: service_healthy  

2) healthcheck

  • healthcheck는 해당 서비스의 건강을 나타내주는 확인 기술이다.
  • 0이 아닌 값이 return 되면 실패로 본다.
  • vote라는 서비스가 실행되고 10 초 뒤에 healthcheck가 실행되며 15 초 주기로 실행되며 실패 이후 최대 3 번까지 retry한다.
    healthcheck: 
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 10s  

3) command / entrypoint

  • command: 이미지 Dockerfile의 CMD를 덮어쓸 때 사용한다.
  • entrypoint: 이미지 Dockerfile의 ENTRYPOINT를 덮어쓸 때 사용한다.

4) DB 서비스 개선

  • environment해당 서비스가 컨테이너 안에서 실행될 때 환경 변수들을 지정해 준다.
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "postgres"
    volumes:
      - "db-data:/var/lib/postgresql/data"
      - "./healthchecks:/healthchecks"  
  • 두 가지 작성 방법이 존재한다.
    • map 문법
    • array 문법
  # map
  environment:
  RACK_ENV: development
  SHOW: "true"
  USER_INPUT:
  #array
  environment:
 - RACK_ENV=development
 - SHOW=true
 - USER_INPUT

5) worker 서비스 개선

  • 이렇게 docker-composer를 통해 build를 하는 경우 더 많은 build 관련 정보를 넘겨 줄 수 있다.
worker:
 build:
 context: ./worker

4. Airflow에서의 docker-compose.yml

1) x-airflow-common

  • airflow-common이라는 별칭을 가지며 여러 서비스에서 공유하는 공통 구성을 정의한다.
  • _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-} 값을 통해 airflow 실행 시 꼭 필요한 패키지들을 설치해 줄 수 있도록 설정한다.
x-airflow-common:
 &airflow-common
 image: ${AIRFLOW_IMAGE_NAME:-apache/airflow:2.5.1}
 environment:
 &airflow-common-env
 AIRFLOW__CORE__EXECUTOR: CeleryExecutor
 …
 _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-}
 volumes:
 - ${AIRFLOW_PROJ_DIR:-.}/dags:/opt/airflow/dags
 - ${AIRFLOW_PROJ_DIR:-.}/logs:/opt/airflow/logs
 - ${AIRFLOW_PROJ_DIR:-.}/plugins:/opt/airflow/plugins
 user: "${AIRFLOW_UID:-50000}:0"
 depends_on:
 &airflow-common-depends-on
 redis:
 condition: service_healthy
 postgres:
 condition: service_healthy

2) airflow-scheduler

  • <<: *airflow-common는 앞서 airflow-common에서 설정해 준 내용을 반복하겠다는 뜻이다.
  • command를 통해 해당 airflow 이미지를 build하고 실행할 때 이 내용을 scheduler로 오버라이드 하겠다.
  • depends_on을 통해
  • airflow-init의 conditionservice_completed_successfully 리소스가 충분한지를 확인하고, 이게 충분하다면 airflow와 관계된 docker container를 실행한다.
airflow-scheduler:
 <<: *airflow-common
 command: scheduler
 healthcheck:
 test: ["CMD-SHELL", 'airflow jobs check --job-type SchedulerJob --hostname "$${HOSTNAME}"']
 interval: 10s
 timeout: 10s
 retries: 5
 restart: always
 depends_on:
 <<: *airflow-common-depends-on
 airflow-init:
 condition: service_completed_successfully

3) DAG를 구현하며 특정 파이썬 모듈을 설치해야 한다면?

  • 일일이 Docker Container에 들어가서 설치해 주는 것은 유지보수가 안 되고 불가능하다.
  • docker-compose.yml 파일을 활용해야 하는데 x-airflow-common에서 _PIP_ADDITIONAL_REQUIREMENTS의 값을 변경해 주면 된다.
_PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:- yfinance pandas numpy(설치해야 할 모듈)}  

🔎 어려웠던 내용 & 새로 알게 된 내용

1. .gitignore

  • .gitignore 파일은 git의 root 디렉토리에 저장되어 Git Repository에 추가되지 말아야 할 폴더나 파일을 정의해 주는 파일이다.
  • .gitignore에 정의된 파일은 git track 하지 않도록 설정하는 역할을 한다.
  • 📚 .gitignore 예시


✍ 회고

다다음 주면 프로젝트인데 이번 프로젝트에는 Docker를 사용한 배포와 자동화된 데이터 파이프라인을 만들어 보는 것을 목표로 두어야 되겠다.

profile
송의 개발 LOG

0개의 댓글