- @참고: 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 webdb를 찾을 수 있고, 각각을 올바른 container의 IP address로 돌릴 수 있다. 예를 들어, web의 어플리케이션은 postgres://db:5432 로 연결하고 사용할 수 있다.

** HOST_PORTCONTAINER_PORT 를 구분하는게 중요하다. 위의 예에서, dbHOST_PORT8001 이고 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 이름으로 서로 통신할 수 있으므로, 서비스가 통신하는데 필수값은 아니다. 다음 예에서 dbweb으로부터 hostname dbdatabase로 연결가능하다.

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-levelnetworks key로 자신만의 networks를 구성할 수 있다. 더 복잡한 topologies를 생성할수 있게 하고 custom network driver와 options을 구성할 수 있게 한다. Compose 에 의해 관리되지 않는 외부 생성된 network에 연결하기 위해 사용할 수도 있다.

각각의 서비스는 어떤 네트워크가 service-levelnetworks 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와 연결한다.

블로그 이미지

uchacha

개발자 일지

,