0부터 시작하는 Docker 공부 - Docker Compose - 개념 & Scale 조정 & 기초 추가

Jaehong Lee·2022년 8월 22일
0
post-thumbnail

1. docker compose 란

  • docker compose 를 통해 1대의 노드에서 동일한 컨테이너를 여러개 만들 수 있다

    ex ) httpd1 컨테이너를 만들고, 동일하게 httpd2 컨테이너를 생성할 수 있다

    • 허나, compose 로 동일한 컨테이너를 다수 배포할 때에는 각 컨테이너들이 연결된 Host 의 Port 번호가 충돌할 수 있으므로 각각 다른 Host 의 Port 와 연결 해야 하는데, 이는 좋은 방법이 아니므로, 동일한 컨테이너는 각기 다른 서버에서 배포하는 방법이 좋다. 이를 통해 같은 Port 번호를 사용할 수 있다. 이러한 방법을 stack ( swarm + compose ) 라고 하며, 클러스터 환경에서 이루어진다
  • compose 는 특정 서비스를 제공하기 위하여 컨테이너들의 묶음이라고 할 수 있는 service 단위로 배포한다

  • compose 는 기존 docker container run 명령으로 작성했던 환경, 컨테이너를 yaml 을 이용하여 구성하는 것

  • 파일의 이름은 docker-compose.yaml 이 기본이며, 다른 이름 사용시 -f 옵션을 통해 사용할 docker compose file 이름을 지정해줘야 한다

docker-compose.yaml 작성법

p. 227
참조 ) https://docs.docker.com/compose/compose-file/compose-file-v3/

  • compose 파일 내에는 version, services, networks, volumes 를 정의 해야 한다. 이 4가지는 작성시 왼쪽 벽에 붙여야 한다

    • networks 와 volumes 는 선택 사항이며, 따로 지정하지 않으면 기본 network 및 volume 을 사용한다
  • 컨테이너 이름은 작성한 그대로 생성되지 않고, 앞에 디렉터리 이름, 뒤에 번호가 붙여져 scale 조정과 같은 재사용이 가능하다. 또한, 수정이 용이하다

    • 수정과 재사용이 용이하다
  • 하위 항목 작성시 들여쓰기 주의 해야 한다. column 과 같은 error 가 발생하면 들여쓰기 오류이니 주의 하자

  • docker compose 버전 별로 지원이 되고, 안되는 옵션들이 있기에 공식 문서를 참조하자

    • 예전 버전에서는 지원이 됬으나, 최신 버전은 지원이 되지 않는 옵션
      • --volumes-from : 컨테이너의 디렉터리와 다른 컨테이너의 디렉터리와 mount 하는 것
  • 구성 요소는 하나만 존재하는지, 다수가 존재하는지에 따라 단수 / 복수형으로 나뉘므로 뒤에 s 가 쓰이는 옵션들은 구분하자


version: "3.5" # version 에 대한 값은 무조건 하나만 나온다
services: # service 는 하나일수도 여러개일수도 있기에 services 라고 쓴다
  web: # 처음 만들때는 디렉터리이름_web1 , 다음에는 디렉터리이름_web2 등 만들때마다 이름이 바뀐다
  
  db: 
  
networks: # network 는 하나일수도 여러개일수도 있기에 networks 라고 쓴다

volumes: # volume 는 하나일수도 여러개일수도 있기에 volumes 라고 쓴다
  • docker-compose.yml 파일은 위와 같은 형태로 구성된다

docker-compose.yaml 작성해보기

  • docker compose 버전을 확인해서 작동이 되는지 확인하자
version: '3.7'
services:
  web:
    image: httpd
    ports: 
      - "8001:80"    
    command: httpd -D FOREGROUND  
    depends_on:
      - db
    links:
      - db:mysql

  db: 
    image: mysql:5.7
    environment:
      - MYSQL_DATABASE=testdb
      - MYSQL_ROOT_PASSWORD=test123

  • 위와 같은 docker compose file 을 작성하자
    • depends_on 은 앞에 컨테이너의 시작만을 확인하고, 이 컨테이너가 정상 실행인지는 확인하지 않는다
    • 같은 compose 파일 내에 있는 컨테이너는 자동으로 link 가 된다. 따라서, links 를 따로 작성해줄 필요는 없다
    • EXPOSE 를 통해 Port 를 지정하지 않아도 link 되는 이유는 이미 BASE IMAGE 를 만들때 EXPOSE 가 되있기 때문이다

배포하기 및 확인하기

docker-compose up -d
  • 위 명령어를 통해 docker-compose.yaml 파일을 이용한 컨테이너 배포를 실행하자

  • compose 를 이용할 때 네트워크를 따로 지정하지 않으면 기본 네트워크에 연결되는데, 이때 기본 네트워크는 docker0 가 아닌 별도의 새 네트워크가 생성되어 새로 생성된 컨테이너는 이에 연결된다. 이 네트워크는 bridge 로 외부에 나갈때 NAT 된다. 이 네트워크 이름은 디렉터리명_default 로 생성된다

  • docker-compose up 을 해도, 변경 사항이 없으면 실행되지 않는다

    • 동일한 컨테이너를 늘릴려면 scale 을 통해 동일한 컨테이너를 배포해야 한다
docker-compose ps

  • docker-compose ps 는 docker compose 를 이용해 만든 컨테이너 리스트를 확인할 수 있다

2. scale 조정하기

  • 위와 같이 scale 을 늘리기 위해 web 컨테이너를 늘리려고 했지만 error 가 난다
  • scale 늘릴 시 컨테이너가 생성되는데, 이 컨테이너가 기존 동일한 컨테이너와 동일한 Host 의 Port 와 연결되 사용하게 되므로 error 가 나는 것 이다
version: '3.7'
services:
  web:
    image: httpd
    ports:
      - "8001-8002:80"
    command: httpd -D FOREGROUND
    depends_on:
      - db
    links:
      - db:mysql

  db:
    image: mysql:5.7
    environment:
      - MYSQL_DATABASE=testdb
      - MYSQL_ROOT_PASSWORD=test123
  • 위와 같이 ports 부분을 수정해주자. 이를 통해 scale 조정을 통해 동일한 컨테이너가 생성되도, 서로 다른 Host 의 Port 와 연결된다
  • scale web=2 를 통해 web 컨테이너를 하나 더 늘렸을 때, Host의 8002 번 Port 와 연결된 것을 확인할 수 있다
version: '3.7'
services:
  web:
    image: httpd
    ports:
      - "80"
    command: httpd -D FOREGROUND
    depends_on:
      - db
    links:
      - db:mysql

  db:
    image: mysql:5.7
    environment:
      - MYSQL_DATABASE=testdb
      - MYSQL_ROOT_PASSWORD=test123
  • 몇 개의 컨테이너를 더 늘릴지 모를 경우, 위와 같이 컨테이너의 Port 만 지정해도 된다. 이를 통해 컨테이너 배포시 Host 의 임의의 Port 와 자동으로 연결된다
  • scale 을 3으로 늘리면, 3개의 컨테이너가 배포되며, 각각 임의의 Host 의 Port 와 연결된 것을 확인할 수 있다
    • scale 을 늘리면, web 컨테이너에 대한 scale 만 늘렸으므로, 이 컨테이너들은 하나의 db 컨테이너에 link 된다. 이는 link 는 컨테이너들의 Port 를 직접 매핑한 것이 아니라, 해당 network 에서 해당 Port 로의 접근을 허용한 것이므로, 다수의 web 컨테이너가 하나의 db 컨테이너 Port 로 접근이 가능하게 되는 것이다

  • 다시 scale 을 1로 줄이면 추가 배포된 컨테이너가 멈추고 삭제된 것을 확인할 수 있다
  • 만약, web 컨테이너에 대한 yaml 내용 변경 후 다시 배포를 실행하면, 현재 scale 증가로 인해 늘어난 web 컨테이너들은 삭제되고, 새 web 컨테이너가 생성된다. db 컨테이너에 대한 변경사항은 없기에 그대로다

3. Directory & p 옵션

  • 위와 같이 디렉터리 변경 후 컨테이너를 배포하면, 해당 디렉터리 이름으로 새로 생성된다. 이때 ps 를 하면, 현재 디렉터리에서 docker compose 를 통해 배포되어 실행된 컨테이너만 확인할 수 있다
    • docker-compose ps 를 이용하면 compose 를 이용하여 배포한 컨테이너만 확인할 수 있다. 이때, docker container run 으로 생성한 것은 docker-compose ps 로는 확인이 불가능 하다

network

  • 별도의 네트워크를 위한 기본 네트워크가 생성되고, 컨테이너도 생성된다
  • network 리스트를 확인하면 각 네트워크를 확인할 수 있다. 여기서 0822_default 와 test1_default 는 같은 docker-compose file 을 사용하여 생성했지만, 서로 다른 네트워크 이다

p 옵션

  • -p 옵션을 통해 다른 디렉터리에 명령을 내릴 수 있다

4. 컨테이너 삭제

  • down 명령어를 통해 컨테이너 중지 및 삭제 그리고 사용 네트워크를 삭제할 수 있다. 이때, docker compose 로 생성된 네트워크만 삭제되고, 외부에서 생성한 네트워크는 삭제되지 않는다

5. 컨테이너를 묶어야 하는 이유

  • scale 을 늘리면, web 컨테이너에 대한 scale 만 늘렸으므로, 이 컨테이너들은 하나의 db 컨테이너에 link 된다. 이는 link 는 컨테이너들의 Port 를 직접 매핑한 것이 아니라, 해당 network 에서 해당 Port 로의 접근을 허용한 것이므로, 다수의 web 컨테이너가 하나의 db 컨테이너 Port 로 접근이 가능하게 되는 것이다

  • 만약, db 컨테이너에 대한 scale 도 같이 늘려서 배포해도, 해당 web 컨테이너가 새로 생긴 db 컨테이너와 link 는 되지만 새로 생성된 db 컨테이너와 연결될지, 기존의 db 컨테이너와 연결될지는 보장할 수 없다. 이와 같은 자원 불균형을 해결하기 위해서는 db 와 web 컨테이너를 하나로 묶어서 배포 해야 한다. 허나, 이는 Docker 에서는 불가능하다

  • 컨테이너들끼리 묶지 않으면, 클러스터 환경에서 다른 서버에 있는 컨테이너들끼리 위와 같은 현상이 생겨서 web 컨테이너가 다른 서버에 있는 db 컨테이너에 연결되어 라우팅을 통해 외부를 통해서 연결된다. 이러한 자원 불균형 현상을 방지하기 위해 한 개 이상의 컨테이너로 구성된 POD 로 묶어서 배포 해야 한다. 이는 K8S 에서 가능하다
    • POD 는 1개 이상의 컨테이너 단위로 구성된 K8S 의 서비스 배포 최소 단위이다
profile
멋진 엔지니어가 될 때까지

0개의 댓글