여러 도커 작성 프로젝트 간의 통신


254

docker-compose.yml두 개의 다른 폴더에 두 개의 별도 파일이 있습니다.

  • ~/front/docker-compose.yml
  • ~/api/docker-compose.yml

컨테이너가 컨테이너에 front요청을 보낼 수 있는지 어떻게 확인할 수 api있습니까?

나는 알고 --default-gateway옵션을 사용하여 설정할 수 있습니다 docker run특정 IP 주소가이 컨테이너에 할당 할 수 있도록하는 것이 개별 컨테이너하지만 사용할 때이 옵션을 사용할 수없는 것으로 보인다 docker-compose.

현재 나는 일을 끝내고 docker inspect my_api_container_id출력에서 게이트웨이를 봅니다. 작동하지만 문제는이 IP가 무작위로 표시되므로 신뢰할 수 없다는 것입니다.

따라서이 질문의 다른 형태는 다음과 같습니다.

  • docker-compose를 사용하여 고정 IP 주소를 특정 컨테이너에 부여 할 수 있습니까?

그러나 결국 내가보고있는 것은 다음과 같습니다.

  • 서로 다른 두 개의 도커 작성 프로젝트는 어떻게 서로 통신 할 수 있습니까?

4
나는 오늘 이것을 다시 한번 살펴 보았다. 개발자들은 마침내 임의의 네트워크 이름을 부여하고 허용했습니다. 편지 쓰기 파일 버전 3.5를 사용하면 '네트워크'키에서 기본 네트워크의 이름을 지정할 수 있습니다. 존재하지 않는 경우 일반적인 프로젝트 이름 접두사없이 이름이 지정된 네트워크를 만듭니다.
cstrutton

답변:


325

서로 대화하려는 컨테이너가 동일한 네트워크에 있는지 확인하면됩니다. 네트워크는 일류 도커 구조이며 작성에만 국한되지 않습니다.

# front/docker-compose.yml
version: '2'
services:
  front:
    ...
    networks:
      - some-net
networks:
  some-net:
    driver: bridge

...

# api/docker-compose.yml
version: '2'
services:
  api:
    ...
    networks:
      - front_some-net
networks:
  front_some-net:
    external: true

참고 : 앱의 네트워크에는 "프로젝트 이름"을 기반으로 이름이 지정되어 있습니다.이 이름은 현재 존재하는 디렉토리 이름을 기반으로합니다.이 경우 접두사 front_가 추가되었습니다.

그런 다음 서비스 이름을 사용하여 서로 대화 할 수 있습니다. 에서 front당신이 할 수있는 ping api반대의 경우도 마찬가지.


1
Jivan은 해결책이 아닙니다. 컨테이너는 호스트에 대해 아무것도 알지 못하거나 그렇게 조작해서는 안됩니다. 내 대답은 꽤 짧았으며 더 자세히 업데이트했습니다.
johnharris85

3
Robert Moskal은 도커 호스트의 IP를 컨테이너에 가져 오기 위해 해킹하는 경우에만 가능합니다. 일반 도커 정의 네트워크에서 통신하도록하는 것이 좋습니다.
johnharris85

2
네트워크에 대한 "front_"접두사는 실행중인 폴더에서 자동으로 생성됩니다. 따라서 첫 번째 docker-compose 파일이 "example / docker-compose.yml"에 있으면 대신 "example_default"라고합니다.
AngryUbuntuNerd

7
name속성을 사용하여 네트워크에 이름을 제공하면 프로젝트 이름 앞에 자동으로 추가 할 수 없습니다. 그런 다음 두 프로젝트 중 하나가 해당 네트워크를 사용하고 아직 존재하지 않는 경우 자동으로 생성 할 수 있습니다.
SteveB

2
@SteveB-name 속성은 docker-compose 파일 버전 3.5 이상에서만 작동합니다.
kramer65

78

@ johnharris85의 훌륭한 답변에 약간의 언급 만하면 도커 작성 파일을 실행할 때 " default"네트워크가 만들어 지므로 다른 작성 파일에 외부 네트워크로 추가 할 수 있습니다.

# front/docker-compose.yml 
version: '2' 
  services:   
    front_service:
    ...

...

# api/docker-compose.yml
version: '2'
services:
  api_service:
    ...
    networks:
      - front_default
networks:
  front_default:
    external: true

나 에게이 접근법은 첫 번째 docker-compose 파일을 소유하지 않았고 통신하기를 원했기 때문에 더 적합했습니다.


이 외부 네트워크에 고정 IP를 할당하는 올바른 방법을 방황합니다. 나는 services:태그 내에서 그것을 할 것을 요구했다. networks:그러면 sintax는 중첩 될 것이고 front_default:( "-"를 제거하고) 우리는 정적 IP를 중첩시킬 것이다 :ipv4_address: '172.20.0.44'
Junior Mayhé

77

업데이트 : 작성 파일 버전 3.5 기준 :

이것은 이제 작동합니다 :

version: "3.5"
services:
  proxy:
    image: hello-world
    ports:
      - "80:80"
    networks:
      - proxynet

networks:
  proxynet:
    name: custom_network

docker-compose up -d'custom_network'라는 네트워크에 가입합니다. 존재하지 않으면 만들어집니다!

root@ubuntu-s-1vcpu-1gb-tor1-01:~# docker-compose up -d
Creating network "custom_network" with the default driver
Creating root_proxy_1 ... done

이제 당신은 이것을 할 수 있습니다 :

version: "2"
services:
  web:
    image: hello-world
    networks:
      - my-proxy-net
networks:
  my-proxy-net:
    external:
      name: custom_network

외부 네트워크에있는 컨테이너가 생성됩니다.

문서에서 아직 참조를 찾을 수 없지만 작동합니다!


두 가지 서비스를 특정 순서로 시작해야합니까? 둘 중 하나를 시작하면 첫 번째 네트워크가 네트워크를 만들고 두 번째 네트워크가 네트워크에 연결됩니까?
slashdottir

4
첫 번째 서비스 (위의 프록시)는 네트워크를 만듭니다. 두 번째 예의 구문이이를 결합합니다.
cstrutton

2
@slashdottir 당신은 할 수 없는 두 번째 서비스에서 외부로 네트워크를 표시하고 아직 존재하지 않는 경우가 생성됩니다.
SteveB

2
작동합니다. 방금 최신 도커 작성으로 DO 방울을 회전 시켰습니다. 예제를 실제 작업 예제로 편집했습니다.
cstrutton

1
필자의 경우 이것은 허용 된 답변보다 더 적합한 솔루션으로 판명되었습니다. 외부 네트워크의 문제는 미리 정의 된 순서로 컨테이너를 시작해야한다는 것이 었습니다. 내 고객에게는 허용되지 않았습니다. 3.5 이후로 명명 된 네트워크는 완벽한 솔루션으로 판명되었습니다. 감사.
ygor

25

의 모든 컨테이너는 다음 구성 으로 기본 네트워크에 api가입 할 수 있습니다 .front

# api/docker-compose.yml

...

networks:
  default:
    external:
      name: front_default

docker compose guide : 기존 네트워크 사용 (아래 참조)을 참조하십시오.


12

이전 게시물 정보는 정확하지만 "external_links"로 연결해야하는 컨테이너 연결 방법에 대한 세부 정보는 없습니다.

이 예제가 당신에게 더 명확 해지기를 바랍니다.

  • 두 개의 서비스 (svc11 및 svc12)가있는 app1 / docker-compose.yml과 두 개의 서비스 (svc21 및 svc22)가있는 app2 / docker-compose.yml이 있고 교차 방식으로 연결해야한다고 가정하십시오.

  • svc11은 svc22의 컨테이너에 연결해야합니다

  • svc21은 svc11의 컨테이너에 연결해야합니다.

따라서 구성은 다음과 같아야합니다.

이것은 app1 / docker-compose.yml입니다.


version: '2'
services:
    svc11:
        container_name: container11
        [..]
        networks:
            - default # this network
            - app2_default # external network
        external_links:
            - container22:container22
        [..]
    svc12:
       container_name: container12
       [..]

networks:
    default: # this network (app1)
        driver: bridge
    app2_default: # external network (app2)
        external: true

이것은 app2 / docker-compose.yml입니다.


version: '2'
services:
    svc21:
        container_name: container21
        [..]
        networks:
            - default # this network (app2)
            - app1_default # external network (app1)
        external_links:
            - container11:container11
        [..]
    svc22:
       container_name: container22
       [..]

networks:
    default: # this network (app2)
        driver: bridge
    app1_default: # external network (app1)
        external: true

6

Compose 1.18 (사양 3.5)부터 필요한 모든 Compose YAML 파일에 대해 고유 한 사용자 지정 이름을 사용하여 기본 네트워크를 재정의 할 수 있습니다. 다음을 추가하는 것만 큼 간단합니다.

networks:
  default:
    name: my-app

위의 내용은 귀하가 (또는 4 이상에서 더 이상 사용하지 않는 경우) version설정 한 것으로 가정합니다 3.5.

다른 답변들도 똑같이 지적했다. 이것은 간단한 요약입니다.


2

다음을 사용하여 모든 컨테이너 docker-compose를 동시에 함께 구성하여 모든 컨테이너가 동일한 네트워크에 연결되도록합니다.

docker compose --file ~/front/docker-compose.yml --file ~/api/docker-compose.yml up -d

그 날은, 예를 들면, 만들 수 있습니다 link또는 depends_on앞의 한 컨테이너에서 API를 하나 개의 컨테이너에?
Jivan

실제로 내가 제안한 것을 할 때, docker-compose는 답장을 build path ~/front/api either does not exist or is not accessible하거나 다른 방법으로 대답합니다 .build path ~/api/front either does not exist or is not accessible
Jivan

1
동시에 작성하는 경우에는 필요하지 않습니다. 모든 컨테이너가있는 네트워크가 작성되며 , 컨테이너 이름이 아닌 작성 파일의 서비스 이름을 통해 통신 할 수 있습니다 .
Nauraushaun

두 개의 작성 파일이 동일한 폴더에 있으면 더 쉬울 수 있습니다. 그러나 나는 그것이 필요하다고 생각하지 않습니다-어느 쪽이든 작동해야한다고 생각합니다.
Nauraushaun

2
이 솔루션이 작동하지 않습니다.이 스레드에 대한 내 의견을 참조하십시오. github.com/docker/compose/issues/3530#issuecomment-222490501
johnharris85

2

업데이트 : 작성 파일 버전 3.5 기준 :

비슷한 문제가 발생하여 docker-compose.yml 프로젝트 중 하나에 약간의 변경 사항을 추가하여 문제를 해결했습니다.

예를 들어 우리는 두 개의 API를의를 가지고 scoringner. Scoringapi ner는 입력 요청을 처리 하기 위해 api 로 요청을 보내야합니다 . 이를 위해 둘 다 동일한 네트워크를 공유한다고 가정합니다.

참고 : 모든 컨테이너에는 자체 네트워크가 있으며 Docker 내에서 앱을 실행할 때 자동으로 생성됩니다. 예를 들어 ner api 네트워크는처럼 생성 ner_default되고 스코어링 api 네트워크는로 이름이 지정됩니다 scoring default. 이 솔루션은 '3'버전에서 작동합니다.

위의 시나리오에서와 같이 내 득점 api는 ner api와 통신하고 싶어하며 다음 줄을 추가합니다. 즉, ner api 용 컨테이너를 만들 때마다 자동으로 score_default 네트워크에 추가됩니다.

networks:
  default:
      external:
        name: scoring_default

ner / docker-compose.yml

version: '3'
services:
  ner:
    build: .
    ...

networks:
  default:
      external:
        name: scoring_default

득점 / 도커 -compose.yml

version: '3'
services:
  api:
    build: .
    ...

위 컨테이너가 이제 scoring_default명령을 사용하여 호출 된 동일한 네트워크의 일부인 방법을 볼 수 있습니다 .

도커 검사 점수 _ 기본

{
    "Name": "scoring_default",
        ....
    "Containers": {
    "14a6...28bf": {
        "Name": "ner_api",
        "EndpointID": "83b7...d6291",
        "MacAddress": "0....",
        "IPv4Address": "0.0....",
        "IPv6Address": ""
    },
    "7b32...90d1": {
        "Name": "scoring_api",
        "EndpointID": "311...280d",
        "MacAddress": "0.....3",
        "IPv4Address": "1...0",
        "IPv6Address": ""
    },
    ...
}

1

.env포함하는 모든 프로젝트에 파일을 추가 할 수 있습니다 COMPOSE_PROJECT_NAME=somename.

COMPOSE_PROJECT_NAME 은 자원의 이름을 지정하는 데 사용되는 두부를 대체합니다. 모든 프로젝트가 somename_default네트워크로 사용 되므로 서비스가 동일한 프로젝트에서와 같이 서로 통신 할 수 있습니다.

주의 : 다른 프로젝트에서 생성 된 "분리 된"컨테이너에 대한 경고가 표시됩니다.


0
version: '2'
services:
  bot:
    build: .
    volumes:
      - '.:/home/node'
      - /home/node/node_modules
    networks:
      - my-rede
    mem_limit: 100m
    memswap_limit: 100m
    cpu_quota: 25000
    container_name: 236948199393329152_585042339404185600_bot
    command: node index.js
    environment:
      NODE_ENV: production
networks:
  my-rede:
    external:
      name: name_rede_externa

0

다른 도커 작성 네트워크를 사용하려면 다음을 수행하십시오 (도커 작성간에 네트워크를 공유하기 위해).

  1. 다음으로 첫 번째 docker-compose 프로젝트를 실행하십시오. up -d
  2. 첫 번째 docker-compose의 네트워크 이름은 다음과 같이 찾으십시오. docker network ls(루트 디렉토리 프로젝트의 이름이 포함되어 있습니다)
  3. 그런 다음 두 번째 docker-compose 파일에서 아래 의이 구조로 해당 이름을 사용하십시오.

두 번째 docker-compose.yml

version: '3'
services:
  service-on-second-compose:  # Define any names that you want.
    .
    .
    .
    networks:
      - <put it here(the network name that comes from "docker network ls")>

networks:
  - <put it here(the network name that comes from "docker network ls")>:
    external: true

0

또 다른 옵션은 'docker-compose'로 첫 번째 모듈을 실행하여 모듈과 관련된 ip를 확인하고 두 번째 모듈을 external과 같은 이전 네트워크에 연결하고 내부 ip를 가리키는 것입니다.

예 app1-서비스 라인에서 생성 된 새로운 네트워크, 외부로 표시 : 하단에 true app1이이 네트워크에 가지고있는 IP를 연결합니다.

이를 통해 서로 대화 할 수 있어야합니다

*이 방법은 지나치게 복잡한 구성을 수행하지 않기 위해 로컬 테스트에 중점을 둡니다. ** 매우 '패치 방식'이라는 것을 알고 있지만 저에게는 효과적이며 다른 사람들은 이것을 활용할 수 있습니다.


0

당신이있는 경우

  • 다른 docker-compose 프로젝트 에서 두 컨테이너간에 통신하려고 하고 동일한 네트워크를 사용 하고 싶지 않습니다. 하자의 그들이 동일한 포트에서 PostgreSQL을하거나 레디 스 컨테이너를 것 말 때문에 (그리고 당신이 그것을 사용하는 이러한 포트를 변경하지 않는 것을 선호하지 것이다 같은 네트워크에서)
  • 로컬로 개발하고 두 도커 작성 프로젝트 간의 통신을 모방하려는 경우
  • localhost에서 두 개의 docker-compose 프로젝트 실행
  • 특히 Django 앱 또는 Django Rest Framework (drf) API 개발 및 노출 된 포트의 컨테이너 내에서 앱 실행
  • 점점 Connection refused두 용기 사이의 통신을 시도하는 동안

그리고 당신은

  • 컨테이너 는 동일한 "도커 네트워크"없이 api_a통신 api_b(또는 그 반대)

(아래 예)

두 번째 컨테이너의 "호스트"를 컴퓨터의 IP 및 Docker 컨테이너 내부에서 매핑 된 포트로 사용할 수 있습니다. 이 스크립트를 사용하여 컴퓨터의 IP를 얻을 수 있습니다 ( Python의 stdlib를 사용하여 로컬 IP 주소 찾기 ).

import socket
def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # doesn't even have to be reachable
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

예:

project_api_a/docker-compose.yml:

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_a
    image: api_a:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

api_a컨테이너 내부 에서 Django 앱을 실행 중입니다. manage.py runserver 0.0.0.0:8000

다른 프로젝트의 두 번째 docker-compose.yml :

project_api_b/docker-compose-yml :

networks:
  app-tier:
    driver: bridge

services:
  api:
    container_name: api_b
    image: api_b:latest
    depends_on:
      - postgresql
    networks:
      - app-tier

api_b컨테이너 내부 에서 Django 앱을 실행 중입니다. manage.py runserver 0.0.0.0:8001

그리고 컨테이너에서 연결을 시도 api_aapi_b의 다음 URL api_b용기하는 것입니다 : http://<get_ip_from_script_above>:8001/

두 개 이상의 도커 작성 프로젝트를 사용하고 모든 프로젝트에 공통 네트워크를 제공하기 어려운 경우 특히 유용 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.