다른 컨테이너에서 도커 컨테이너에 액세스


93

두 개의 서로 다른 이미지를 기반으로 두 개의 도커 컨테이너를 만들었습니다. db 중 하나와 웹 서버용. 두 컨테이너 모두 내 Mac OSX에서 실행되고 있습니다.

나는 호스트 머신에서 db 컨테이너에 액세스 할 수 있으며 동일한 방법으로 호스트 머신에서 웹 서버에 액세스 할 수 있습니다.

그러나 웹 서버에서 db 연결에 어떻게 액세스합니까?

내가 db 컨테이너를 시작한 방법은

docker run --name oracle-db -p 1521:1521 -p 5501:5500 oracle/database:12.1.0.2-ee

wls 컨테이너를 다음과 같이 시작했습니다.

docker run --name oracle-wls -p 7001:7001 wls-image:latest

다음에 연결하여 호스트의 db에 액세스 할 수 있습니다.

sqlplus scott/welcome1@//localhost:1521/ORCLCDB

호스트의 wls에 다음과 같이 액세스 할 수 있습니다.

http://localhost:7001/console

그렇다면 웹 컨테이너와 db 컨테이너가 모두 호스트 머신에 있습니까? 그렇다면 어떤 버전의 도커를 사용하고 있습니까? 이전 버전의 docker에는 한 가지 방법이 있었지만 새 버전에는 다른 방법이 있습니다. docker-compose도 사용할 수 있습니까? 더 쉽게 만들 수 있지만 사용할 수없는 방법을 사용하여 대답하고 싶지 않습니다.
— Caperneoignis

이 대답은 맥 OS의 컨테이너에서 액세스 로컬 호스트에 어떻게 도움이 될 수 있습니다
— Chaojun 종에게

외부 네트워킹의 경우이 솔루션이 저에게
— 효과적

답변:


51

가장 쉬운 방법은 --link를 사용하는 것이지만 최신 버전의 docker는 그로부터 멀어지고 있으며 실제로 스위치가 곧 제거 될 것입니다.

아래 링크는 두 개의 컨테이너를 연결하는 방법을 제공합니다. 이미지에 항목을 추가하는 데 유용한 방법이므로 첨부 부분을 건너 뛸 수 있습니다.

https://deis.com/blog/2016/connecting-docker-containers-1/

관심있는 부분은 두 컨테이너 간의 통신입니다. 가장 쉬운 방법은 웹 서버 컨테이너에서 이름으로 DB 컨테이너를 참조하는 것입니다.

예:

db 컨테이너 db1와 웹 서버 컨테이너의 이름을 지정했습니다 web0. 컨테이너는 둘 다 브리지 네트워크에 있어야합니다. 즉, 웹 컨테이너가 이름을 참조하여 DB 컨테이너에 연결할 수 있어야합니다.

따라서 앱에 대한 웹 구성 파일이있는 경우 DB 호스트에 대해 이름을 사용합니다 db1.

이전 버전의 docker를 사용하는 경우 --link를 사용해야합니다.

예:

1 단계: docker run --name db1 oracle/database:12.1.0.2-ee

그런 다음 웹 앱을 시작할 때. 사용하다:

2 단계: docker run --name web0 --link db1 webapp/webapp:3.0

웹앱이 DB에 연결됩니다. 그러나 내가 말했듯이 --link 스위치는 곧 제거됩니다.

대신 docker compose를 사용하여 네트워크를 구축합니다. 하나; 시스템 용 docker compose를 다운로드해야합니다. https://docs.docker.com/compose/install/#prerequisites

예제 설정은 다음과 같습니다.

파일 이름은 base.yml

version: "2"
services:
  webserver:
    image: "moodlehq/moodle-php-apache:7.1
    depends_on:
      - db
    volumes:
      - "/var/www/html:/var/www/html"
      - "/home/some_user/web/apache2_faildumps.conf:/etc/apache2/conf-enabled/apache2_faildumps.conf"
    environment:
      MOODLE_DOCKER_DBTYPE: pgsql
      MOODLE_DOCKER_DBNAME: moodle
      MOODLE_DOCKER_DBUSER: moodle
      MOODLE_DOCKER_DBPASS: "m@0dl3ing"
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"
  db:
    image: postgres:9
    environment:
      POSTGRES_USER: moodle
      POSTGRES_PASSWORD: "m@0dl3ing"
      POSTGRES_DB: moodle
      HTTP_PROXY: "${HTTP_PROXY}"
      HTTPS_PROXY: "${HTTPS_PROXY}"
      NO_PROXY: "${NO_PROXY}"

이것은 네트워크의 이름을 일반 이름으로 지정합니다. --name 스위치를 사용하지 않는 한 그 이름이 무엇인지 기억할 수 없습니다.

IE docker-compose --name setup1 up base.yml

참고 : --name 스위치를 사용하는 경우 docker compose를 호출 할 때이 스위치를 사용해야합니다. docker-compose --name setup1 down 하나 이상의 웹 서버 및 db 인스턴스를 가질 수 있으며이 경우 docker compose가 어떤 인스턴스를 알고 있는지 확인합니다. 명령을 실행하려고합니다. 또한 한 번에 여러 개를 실행할 수 있습니다. 동일한 서버에서 병렬로 테스트를 실행하는 경우 CI / CD에 적합합니다.

Docker compose에는 docker와 동일한 명령이 있으므로 docker-compose --name setup1 exec webserver do_some_command

가장 중요한 부분은 단위 테스트를 위해 db 또는 이와 유사한 것을 변경하려는 경우 up 명령에 추가 .yml 파일을 포함 할 수 있으며 유사한 이름을 가진 항목을 덮어 쓸 수 있다는 것입니다. .

예:

db.yml

version: "2"
services:
  webserver:
    environment:
      MOODLE_DOCKER_DBTYPE: oci
      MOODLE_DOCKER_DBNAME: XE
  db:
    image: moodlehq/moodle-db-oracle

그런 다음 전화 docker-compose --name setup1 up base.yml db.yml

이것은 db를 덮어 씁니다. 다른 설정으로. 각 컨테이너에서 이러한 서비스에 연결해야하는 경우 service 아래에 설정된 이름 (이 경우 webserver 및 db)을 사용합니다.

나는 이것이 실제로 귀하의 경우에 더 유용한 설정이라고 생각합니다. yml 파일에서 필요한 모든 변수를 설정할 수 있으므로 필요할 때 docker compose 명령을 실행하면됩니다. 그래서 더 시작하고 설정을 잊어 버리십시오.

참고 : 나는 --port컨테이너-> 컨테이너 통신을 위해 포트를 노출 할 필요가 없기 때문입니다. 호스트가 컨테이너 또는 호스트 외부에서 애플리케이션에 연결하도록하려는 경우에만 필요합니다. 포트를 노출하면 호스트가 허용하는 모든 통신에 포트가 열려 있습니다. 따라서 포트 80에서 웹을 노출하는 것은 물리적 호스트에서 웹 서버를 시작하는 것과 동일하며 호스트가 허용하는 경우 외부 연결을 허용합니다. 또한 어떤 이유로 든 한 번에 하나 이상의 웹앱을 실행하려는 경우 포트 80을 노출하면 해당 포트에서도 노출을 시도 할 경우 추가 웹앱을 실행할 수 없습니다. 따라서 CI / CD의 경우 포트를 전혀 노출하지 않는 것이 가장 좋으며 docker compose를 --name 스위치와 함께 사용하면 모든 컨테이너가 자체 네트워크에 있으므로 충돌하지 않습니다. 그래서 당신은 컨테이너 컨테이너를 거의 가질 것입니다.

업데이트 : 기능을 더 사용하고 다른 사람들이 Jenkins와 같은 CICD 프로그램에 대해 어떻게 수행했는지 확인한 후. 네트워크도 실행 가능한 솔루션입니다.

예:

docker network create test_network

위의 명령은 다른 컨테이너도 연결할 수있는 "test_network"를 생성합니다. --network스위치 오퍼레이터 로 쉽게 만들 수 있습니다.

예:

docker run \
    --detach \
    --name db1 \
    --network test_network \
    -e MYSQL_ROOT_PASSWORD="${DBPASS}" \
    -e MYSQL_DATABASE="${DBNAME}" \
    -e MYSQL_USER="${DBUSER}" \
    -e MYSQL_PASSWORD="${DBPASS}" \
    --tmpfs /var/lib/mysql:rw \
    mysql:5

물론 프록시 네트워크 설정이있는 경우 "-e"또는 "--env-file"스위치 문을 사용하여 해당 설정을 컨테이너에 전달해야합니다. 따라서 컨테이너는 인터넷과 통신 할 수 있습니다. Docker는 프록시 설정이 최신 버전의 docker에서 컨테이너에 흡수되어야한다고 말합니다. 그러나 나는 여전히 그것들을 습관으로 전달합니다. 이것은 사라질 "--link"스위치를 대체합니다. 컨테이너가 생성 한 네트워크에 연결되면 컨테이너의 '이름'을 사용하여 다른 컨테이너에서 해당 컨테이너를 계속 참조 할 수 있습니다. 위의 예에 따라 db1. 모든 컨테이너가 동일한 네트워크에 연결되어 있는지 확인하기 만하면됩니다.

cicd 파이프 라인에서 네트워크를 사용하는 자세한 예는 다음 링크를 참조하십시오. https://git.in.moodle.com/integration/nightlyscripts/blob/master/runner/master/run.sh

Moodle에 대한 대규모 통합 테스트를 위해 Jenkins에서 실행되는 스크립트이지만 아이디어 / 예제는 어디에서나 사용할 수 있습니다. 이것이 다른 사람들에게 도움이되기를 바랍니다.


1
첫 번째 링크가 작동하지 않으면이 링크를 사용할 수 있습니다. linode.com/docs/applications/containers/…
— Caperneoignis

1
Docker가 네트워크를 구성하거나 수행하는 경우 웹 서버가 DB를 어떻게 참조합니까? 컨테이너 이름을 사용합니까? 두 번째 링크는 다음과 같습니다. 따라서 DB와 APP를 정의하면 앱이이 경우를 참조해야합니다. psql -U {USER} -h database -p 5432 {DATABASE}내가
— 쉘링

1
@Fallenreaper 컨테이너에 있고 docker가 구성한 경우 명시 적으로 이름을 지정하지 않은 경우 "services :"에서 사용되는 이름을 사용합니다. 따라서 예제에서 쉘의 "db"컨테이너에서 연결을 시도하는 경우 "webserver"를 사용합니다. db.yml의 예를 보면 webserver 및 db라는 이름을 사용합니다. 지연되어 죄송합니다. 알림을 잊어 버렸습니다.
— Caperneoignis

52

그것은 간단합니다. 두 개 이상의 실행중인 컨테이너가있는 경우 다음 단계를 완료하십시오.

docker network create myNetwork
docker network connect myNetwork web1
docker network connect myNetwork web2

이제 web1에서 web2 컨테이너로 또는 그 반대로 연결합니다.

다음을 실행하여 찾을 수있는 내부 네트워크 IP 주소를 사용하십시오.

docker network inspect myNetwork

내부 IP 주소와 포트만 네트워크 브리지로 연결된 컨테이너에 액세스 할 수 있습니다.

예를 들어 web1 컨테이너가 다음으로 시작되었다고 가정하고 docker run -p 80:8888 web1(서버가 내부적으로 포트 8888에서 실행 중임을 의미 함), 검사 myNetwork결과 web1의 IP가 172.0.0.2 인 것으로 표시되며을 사용하여 web2에서 web1로 연결할 수 있습니다 curl 172.0.0.2:8888.


1
안녕하세요, web1에서 web2로 어떻게 연결합니까? IP로, 호스트 이름? 이 정보는 어디에서 얻을 수 있습니까?
— Henry Ávila

docker-compose.yml 파일에서 네트워크 생성 : myNetwork.
— MxWild

14
@ HenryÁvila 컨테이너의 이름 (예 :)을 web1호스트 이름으로 사용합니다.
— Pascal

19

호스트 컴퓨터의 IP를 통해 db에 액세스해야합니다. 또는 localhost : 1521을 통해 액세스하려면 다음과 같이 웹 서버를 실행해야합니다.

docker run --net=host --name oracle-wls wls-image:latest

여길 봐


1
호스트의 IP가 실행중인 머신 컨테이너에 따라 변경되므로 실제 생활에서 어떻게 작동할까요?
— Vik

1
머신에 고정 IP 또는 DNS가있는 경우에만 유효하며 그렇지 않으면 두 번째 방법을 사용합니다.
— xitter

나는 이것에 문제가있는 것 같다. 내 정확한 실행 명령은 다음과 같습니다. docker run --name ora-tools-wls -it -p 7001 : 7001 orawls 작동하며이 컨테이너에서 실행중인 내 서버에 localhost : 7001 / console로 액세스 할 수 있습니다. 그러나 서버에서 db 액세스가 필요합니다. DB를 실행하는 다른 컨테이너에 도달하기위한 정확한 IP. docker run --name ora-tools-wls -it -p 7001 : 7001 --network = "host"orawls를 사용하면 서버가 언급 한대로 localhost를 ip로 사용하여 db에 액세스 할 수 있지만 호스트 컴퓨터 브라우저에서 서버에 액세스 할 수 있습니다. 실패합니다.
— Vik

3
-p 7001:7001모든 컨테이너가 호스트의 네트워크 스택 자체를 사용 하므로을 정의 할 필요가 없습니다 .
— xitter

@Vik, 같은 문제가 있었고 Mac에서 지원되지 않는다는 것을 알았습니다. 그게 당신이하는 일이기도합니다. > 호스트 네트워킹 드라이버는 Linux 호스트에서만 작동하며 Mac 용 Docker Desktop, Windows 용 Docker Desktop 또는 Windows Server 용 Docker EE에서는 지원되지 않습니다. docs.docker.com/network/host
— Brent Fisher

9

를 사용하면 docker-compose기본적으로 서비스가 이름별로 서로 노출됩니다. 문서 .
다음과 같은 별칭을 지정할 수도 있습니다.

version: '2.1'
services:
  mongo:
    image: mongo:3.2.11
  redis:
    image: redis:3.2.10
  api:
    image: some-image
    depends_on:
      - mongo
      - solr
    links:
      - "mongo:mongo.openconceptlab.org"
      - "solr:solr.openconceptlab.org"
      - "some-service:some-alias"

그리고 예를 들어 호스트 이름으로 지정된 별칭을 사용하여 서비스에 액세스 mongo.openconceptlab.org하기위한 mongo이 경우.

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