[데이터 엔지니어링 데브코스] TIL 46일차 - Docker & K8S (4)&(5)

박단이·2024년 1월 1일
0

데브코스 TIL

목록 보기
46/56

오늘 배운 것🤓

docker-compose

  • 다수의 container로 소프트웨어가 구성되는 경우 사용하는 툴이자 환경설정파일이다.
  • docker-compose.yml 혹은 docker-compose.yaml으로 설정한다. 둘 중 하나만 있으면 되고 둘 다 있으면 에러가 발생한다.
  • 다양한 테스트들이 수행 가능하며, 다양한 버전(dev, test, prod 등)을 만드는 것이 일반적이다.
  • 개별 container를 따로 관리하는 것보다 훨씬 더 생산성이 높다. 대신 그만큼 배워야할 것도 많고 복잡하다.
  • docker compose v1.27+부터는 v2와 v3가 합쳐져서 따로 구분하지 않는다. v1.27+부터 $ docker-compose 대신 $ docker compose 로 실행한다.
  • $ docker compose 로 빌드한 경우 image 이름 앞에 docker-compose.yml이 속한 폴더의 이름이 자동으로 prefix로 붙는다.

docker-compose 명령어

$ docker compose build  # build 키로 지정된 것들만 빌드한다.
$ docker compose up		# build/pull -> create -> start 까지 한번에 해준다.
$ docker compose pull	# image 키로 지정된 것들만 docker hub에서 불러온다.
$ docker compose ps		# docker compose로 실행된 컨테이너들을 개별적으로 보여준다.
$ docker compose ls		# docker compose로 실행된 컨테이너들을 그룹화하여 보여준다.
$ docker compose down	# 컨테이너를 중지하고 삭제한다. 이미지는 살아있다.
$ docker compose start
$ docker compose stop
$ docker compose rm
$ docker compose images	# docker compose로 실행된 컨테이너에 의해 실행되는 이미지만 보여준다.
$ docker images		# 모든 image를 보여준다.

docker-compose.yml 구성요소

  1. version
    • 1.27 이후로는 쓸 필요없지만 써도 상관은 없다.
    • version2와 3를 구분하여 작성한다.
  2. services
    • app을 구성하는 container들의 서비스 지정
    • 각 서비스는 별개의 docker image 지정과 docker container 실행으로 구성된다.
    • 서비스 별로 포트번호, 환경변수, 디스크 볼륨들을 지정한다.
    • 서비스 이름은 아무거나 가능하지만 서비스 이름이 네트워크 상에서 호스트 이름이 되기 때문에 명시적으로 사용할 것
  3. volumes
    • 여기서 지정한 volume만 services에서 사용 가능
    • Host Volume, Named Volume 기법을 사용한다.
  4. networks
    • 여기서 지정한 network만 services에서 사용 가능
    • 여러 개의 네트워크로 분리하지 않는다면 기입할 필요 X
    • 기입하지 않는다면 알아서 하나의 네트워크(default)를 공유한다.

docker-compose.yml 작성법

version: '3'
services:
  redis:
    image: redis:latest
    ports: 
      - 외부포트:내부포트
    environment:
      DB_URL: /~~~~~/~~
    volumes:
      - ./result: /app	 # host
      - vol1: /app		 # named
    networks:
      - net1
      - net2
  vote:
    build: ./vote
    ...
volumes:
  vol1:
networks:
  net1:
  net2:

docker-compose.yml 다양한 키

depends_on

  • 서비스들 간의 의존성이 있을 경우 먼저 실행되어야하는 서비스들을 기술한다.
  • services 안에 해당 서비스의 키 안에서 작성한다.
depends_on:
  - db
  - redis
  • 각 서비스의 상태에 따라 실행상황을 결정하고 싶다면 condition을 사용한다.
services:
  postgre:
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
      init:
        condition : service_completed_successfully
  1. service_healthy : 해당 서비스가 healthcheck의 테스트를 통과했을 때만 실행한다.
  2. service_started : 해당 서비스가 실패하든 성공하든 실행시작하면 무조건 실행한다.
  3. service_completed_successfully : 해당 서비스가 실행이 모두 끝나고 종료되었을 때 실행한다.

healthcheck

  • 해당 서비스가 제대로 작동하는지 테스트를 진행하여 healthy한지의 기준이 된다.
  • 결과값이 0이면 성공 1이면 실패로 간주한다.
services:
  db:
    healthcheck:
      test: test.sh		# 체크하는 명령문
      interval: 15s		# 테스트 간의 간격
      timeout: 5s		# 5초 안에 결과가 0이어야 성공
      retries: 3		# 재시도 기회
      start_period: 10s	# 해당 컨터이너가 실행되고 10초 후에 테스트를 시작한다.

build할 때 더 많은 정보를 넘겨주고 싶다면

  • context를 사용한다.
services:
  vote:
    context: dockerfile의 경로
    dockerfile: dockerfile의 이름이 다를 때 기입
    args:	# 빌드할 때 사용하는 환경 변수
      ENVIRONMENT: ...

docker-compose.yml anchor

  • 여러 서비스에서 공유하는 공통 구성을 정의하여 YML 파일 블록을 계승이라는 형태로 재사용 가능하게 한다.
  • version, services, networks, volumes를 제외한 최상위 레벨 키워드는 모두 anchor이다.
# anchor 정의
x-new-anchor:
  &anchor-name   # 이 이름을 가지고 뒤에서 부른다.
  
# anchor 사용
services:
  db:
    <<:*anchor-name

docker를 실제 production 환경에서 사용할 때 고려할 점

  1. Docker Volumes
    • Host Volume 방식은 보통 개발할 때 사용한다. 소스 코드를 바로 container 안으로 마운트하여 확인하기 위함이다.
    • Production의 경우 Named Volume 방식을 사용해야 한다.
  2. Docker Container은 read-only로 사용
    • Container를 수정해야할 때 실행중인 컨테이너에서 수정은 금물!
    • 항상 이미지를 새로 빌드하고 다시 컨테이너들을 새로 create 하자.
    • 자동화(CI/CD 프로세스)가 매우 중요
  3. 다수의 Docker Container들을 다수의 호스트에서 실행할 필요가 있을 때
    • 용량 문제와 Fail-over(혹은 Fail-tolerant)에 대비

서버 관리의 어려움

  • 서버 수가 많아지기 시작하면 어떤 서버에 어떤 문제가 있는지 확인하기 힘들어진다.

해결방안

  1. 문서화
    제대로된 문서를 유지하는 것이 힘들 뿐더러 경우에 따라서는 아예 필요없는 경우가 많다.
  2. 문서화가 아닌 코드로 대신
    • Infrastructure AS Code
    • 대화형 명령보다는 자동화된 스크립트로 해결하고 다수의 서버들에 명령을 대신 실행해 준다.
    • Learning Curve가 높고, 설치된 소프트웨어와 모듈 충돌 문제에는 큰 도움이 되지 않는다.
    • 예. chef, Puppet, Ansible, Terraform ...
  3. Virtual Machine 도입
    • 소프트웨어 충돌 해결을 위해 VM을 사용
    • VM이 전반적으로 리소스 소비가 크고 느리다.
    • 특정 VM 벤더 혹은 클라우드에게 종속(Lock-in)된다.
  4. Docker 도입
    • VM에 비해 리소스 낭비도 적고 빠르다.
    • 오픈 소스이기 때문에 클라우드나 특정업체 Lock-in 되지 않는다.
    • 단점이 거의 없지만 Docker Container의 수가 늘어나면서 관리가 힘들다는 점이 부각된다.

Microservice

  • 웹 서비스를 다수의 작은 서비스들로 구현하는 방식
  • 기존의 방식은 Monolith방식으로 하나의 서버에서 모든 내용을 다 넣어서 언어와 기술, 디자인 등이 한가지로 통일되어야 했다.
  • 마이크로서비스는 각 서비스들은 팀 단위로 원하는 언어/기술로 개발하는 자율성을 보장한다.
  • 하지만 너무 다양해지면서 각 서비스들을 이해하고 공유하기 위해 서비스 정보를 등록해야한다. -> service registry
  • 특징
    • Decentralization
    • Modularity
    • Domain driven design
    • Focus on empowering teams

느낀 점😊

세팅하는 부분은 항상 봐도 새로운 것 같다. 다양한 docker-compose.yml 파일을 보고 따라하면서 내 것으로 익히는 과정이 필요하다. 에러도 내보고 새로운 기능도 추가해서 테스트도 해봐야겠다.
우선은 빠르게 진도를 따라잡아야지!

profile
데이터 엔지니어를 꿈꾸는 주니어 입니다!

0개의 댓글