- @참고: https://docs.docker.com/compose/networking/
기본적으로 Compose는 당신의 앱에 단일 network를 세팅한다. 각각의 service에 대한 container는 default network에 합류하고, 각각은 다른 container와 container의 이름과 동일한 hostname으로 통신할 수 있다.
당신의 앱의 network는 "project 명"에 기반한다. 즉, 프로젝트의 directory 명이다. --project-name flag나 COMPOSE_PROJECT_NAME 환경 변수로 override 할 수 있다.
예를 들어, 당신의 앱이 myapp 이라는 디렉토리에 있고, docker-compose.yml 이 아래와 같다고 하자.
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
ports:
- "8001:5432"
docker-compose up 을 하면, 다음과 같은 일이 벌어진다.
1. myapp_default 라는 network가 생성된다.
2. web의 configuration을 사용한 container가 생성되고, myapp_default 라는 network에 합류해서 host명은 web이 된다.
3. db의 configuration을 사용한 container가 생성되고, myapp_default라는 network에 합류해서 host명은 db가 된다.
각 컨테이너는 hostname web 과 db를 찾을 수 있고, 각각을 올바른 container의 IP address로 돌릴 수 있다. 예를 들어, web의 어플리케이션은 postgres://db:5432 로 연결하고 사용할 수 있다.
** HOST_PORT와 CONTAINER_PORT 를 구분하는게 중요하다. 위의 예에서, db는 HOST_PORT가 8001 이고 container port는 5432(postgre의 기본값) 이다. service-to-service 네트워크는 CONTAINER_PORT를 쓴다. HOST_PORT 가 정의되면, service는 외부에서 접근 가능하다.
web container 내부에서, db에 접속하는 주소는 postgres://db:5432와 같고, host machine에서 연결 주소는 postgres://{DOCKER_IP}:8001 이다.
서비스 명 | 외부 접근 주소(DOCKER_IP:HOST_PORT) | 외부 접근 주소와 매핑되는 컨테이너 내부 주소(hostname:CONTAINER_PORT) |
web | {DOCKER_IP}:8000 | web:8000 |
db | {DOCKER_IP}:8001 | db:5432 |
container 업데이트 시
service에 대한 configuration을 변경하고 docker-compose up 을 하면, 예전 container는 삭제되고 새로운 container가 다른 IP 주소지만 같은 이름으로 생성된다. running container는 그 이름을 찾을 수 있고, 새로운 주소로 연결할 수 있으며, 예전 IP 주소는 동작을 멈춘다.
만약 어떤 컨테이너가 예전 컨테이너로 연결을 열면, 동작하지 않는다. 이러한 조건을 찾고, 이름을 찾고 연결하는게 컨테이너의 책임이다.
서비스 명 | 외부 접근 주소(DOCKER_IP:HOST_PORT) | 외부 접근 주소와 매핑되는 컨테이너 내부 주소(hostname:CONTAINER_PORT) |
web | {DOCKER_IP}:8000 | web:8000 (web에 대한 ip가 변경됨) |
db | {DOCKER_IP}:8001 | db:5432 (db에 대한 ip가 변경됨) |
Links
Links는 다른 서비스에서 닿을 수 있는 여분의 별칭을 정의할 수 있게 한다. 각 service는 다른 service에 service 이름으로 서로 통신할 수 있으므로, 서비스가 통신하는데 필수값은 아니다. 다음 예에서 db는 web으로부터 hostname db 및 database로 연결가능하다.
version: "3.9"
services:
web:
build: .
links:
- "db:database"
db:
image: postgres
Multi-host networking
Docker Engine에서 Compose application을 Swarm mode enabled 하게 배포하면, multi-host communication을 가능하게 하는 내장 overlay driver를 사용할 수 있다.
Swarm cluster를 구성하는 방법을 보려면, Swarm mode section을 봐라. multi-host overlay networks를 알고 싶으면 Getting started with multi-host networking을 봐라.
custom network 구성하기
기본 app network 대신에, top-level의 networks key로 자신만의 networks를 구성할 수 있다. 더 복잡한 topologies를 생성할수 있게 하고 custom network driver와 options을 구성할 수 있게 한다. Compose 에 의해 관리되지 않는 외부 생성된 network에 연결하기 위해 사용할 수도 있다.
각각의 서비스는 어떤 네트워크가 service-level의 networks key와 연결될건지 구성할 수 있고, top-level networks key 아래에 언급된 entries의 이름들 리스트이다.
아래는 두 custom network를 정의한 예시 Compose 파일이다. proxy service는 db service와 분리되어 있고, 공통의 network를 공유하지 않는다. 오직 app만 둘다 통신이 가능하다.
version: "3.9"
services:
proxy:
build: ./proxy
networks:
- frontend
app:
build: ./app
networks:
- frontend
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
# Use a custom driver
driver: custom-driver-1
backend:
# Use a custom driver which takes special options
driver: custom-driver-2
driver_opts:
foo: "1"
bar: "2"
Networks는 연결된 각 네트워크에 대하여 ipv4_address 또는 ipv6_address 를 세팅함으로써 고정 IP 주소로 구성 가능하다. Networks는 주어진 custom name 으로도 가능하다.(version 3.5부터)
가능한 network configuration option에 대한 자세한 내용을 알려면, 다음을 참조해라.
Top-level networks key 중
external
true로 세팅되면, network가 Compose 외부에서 생성되었음을 지정한다. docker-compose up 이 생성하려 하지 않고, 존재하지 않으면 error를 뱉는다.
3.3이나 그 아래 format에서는, external이 다른 configuration key(driver, driver_opts, ipam, internal)와 함께 사용될 수 없다. v 3.4 이상에서는 그런 제한이 없다.
아래 예시에서는, proxy가 외부와의 gateway이다. [projectname]_outside를 생성하려 시도하는 대신, Compose는 outside라 불리는 network를 찾고, proxy service container를 그 네트워크에 연결한다.
version: "3.9"
services:
proxy:
build: ./proxy
networks:
- outside
- default
app:
build: ./app
networks:
- default
networks:
outside:
external: true
!! version 3.5 file format에서 deprecated 된 것
external.name 은 version3.5 file format 부터 사용되지 않고, 대신 name을 사용한다.
Compose file 내에서 언급한 이름과 별도로 network 이름을 지정할 수도 있다.
version: "3.9"
networks:
outside:
external:
name: actual-name-of-network
default network 구성하기
따로 network를 구성하는 대신, networks 이름을 default로 두어서 앱 전반에 기본 network를 세팅할 수도 있다.
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
networks:
default:
# Use a custom driver
driver: custom-driver-1
기존에 존재하는 network를 사용하기
container가 기존 존재하는 network에 합류하길 원하면, external 옵션을 사용해라.
services:
# ...
networks:
default:
external:
name: my-pre-existing-network
[projectname]_default 의 네트워크를 생성하는 대신, Compose는 my-pre-existing-network를 찾고, 앱의 container와 연결한다.
'Docker' 카테고리의 다른 글
Caused by: java.net.NoRouteToHostException: Host is unreachable (0) | 2022.11.08 |
---|---|
[Docker] 도커 컨테이너의 종료 코드(exit code) 확인하기 (0) | 2022.11.07 |
[Docker] Window docker에서 volume 공유 (0) | 2021.04.07 |
[Docker] window cmd 상에서 -v volume file exists 에러 (0) | 2021.04.07 |