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 이름을 지정해줘야 한다
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 라고 쓴다
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
- 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
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
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
- scale 을 늘리면, web 컨테이너에 대한 scale 만 늘렸으므로, 이 컨테이너들은 하나의 db 컨테이너에 link 된다. 이는 link 는 컨테이너들의 Port 를 직접 매핑한 것이 아니라, 해당 network 에서 해당 Port 로의 접근을 허용한 것이므로, 다수의 web 컨테이너가 하나의 db 컨테이너 Port 로 접근이 가능하게 되는 것이다
- docker-compose ps 를 이용하면 compose 를 이용하여 배포한 컨테이너만 확인할 수 있다. 이때, docker container run 으로 생성한 것은 docker-compose ps 로는 확인이 불가능 하다
scale 을 늘리면, web 컨테이너에 대한 scale 만 늘렸으므로, 이 컨테이너들은 하나의 db 컨테이너에 link 된다. 이는 link 는 컨테이너들의 Port 를 직접 매핑한 것이 아니라, 해당 network 에서 해당 Port 로의 접근을 허용한 것이므로, 다수의 web 컨테이너가 하나의 db 컨테이너 Port 로 접근이 가능하게 되는 것이다
만약, db 컨테이너에 대한 scale 도 같이 늘려서 배포해도, 해당 web 컨테이너가 새로 생긴 db 컨테이너와 link 는 되지만 새로 생성된 db 컨테이너와 연결될지, 기존의 db 컨테이너와 연결될지는 보장할 수 없다. 이와 같은 자원 불균형을 해결하기 위해서는 db 와 web 컨테이너를 하나로 묶어서 배포 해야 한다. 허나, 이는 Docker 에서는 불가능하다
- POD 는 1개 이상의 컨테이너 단위로 구성된 K8S 의 서비스 배포 최소 단위이다