Docker 컨테이너 내부에서 기계의 localhost에 어떻게 연결합니까?


질문

 

따라서 Docker 컨테이너 내에서 NginX를 실행하면 LocalHost에서 MySQL을 실행하고 내 nginx 내에서 MySQL에 연결하고 싶습니다.MySQL은 LocalHost에서 실행 중이며 포트를 외부 세계에 노출시키지 않으므로 로컬 호스트에서 바인딩되어 시스템의 IP 주소에 바인딩되지 않습니다.

이 Docker 컨테이너 내 에서이 MySQL 또는 LocalHost에서 다른 프로그램에 연결할 수있는 방법이 있습니까?

이 질문은 Docker 호스트의 IP 주소가 공용 IP 또는 네트워크의 개인 IP 일 수 있거나 할 수있는 네트워크의 개인 IP 일 수 있거나Docker 컨테이너 내에서 도달 할 수 없습니다 (AWS 또는 무언가에서 호스팅되는 경우 공개 IP를 의미합니다).Docker 호스트의 IP 주소가 있더라도 Docker 네트워크가 오버레이, 호스트, 브리지, MacVlan, None 등을 제한 할 수있는 IP 주소가 오버레이, 호스트, 브리지, MacVlan 등의 IP 주소가있을 수있는 컨테이너 내에서 연결할 수있는 것을 의미하지는 않습니다.그 IP 주소.


답변

 

편집하다:

Docker-For-Mac 또는 Docker-Windows 18.03+를 사용하는 경우 호스트 host.docker.Internal (연결 문자열의 127.0.0.1 대신)을 사용하여 MySQL 서비스에 연결하십시오.

docker-for-linux 20.10.0 이상을 사용하는 경우, -add-host host.docker.internal : host-gateway 옵션을 사용하여 Docker 컨테이너를 시작한 경우 호스트 host.docker.internal을 사용할 수도 있습니다.

그렇지 않으면 아래에서 읽으십시오


tldr.

Docker Run 명령의 -network = "호스트"를 사용하면 Docker 컨테이너의 127.0.0.1이 Docker 호스트가 가리 킵니다.

참고 :이 모드는 문서별로 Linux 용 Docker에서만 작동합니다.


Docker 컨테이너 네트워킹 모드에 대한 참고 사항

Docker는 컨테이너를 실행할 때 다른 네트워킹 모드를 제공합니다.선택한 모드에 따라 Docker 호스트에서 실행중인 MySQL 데이터베이스에 연결합니다.

Docker Run -network = "Bridge"(기본값)

Docker는 Docker0이라는 브리지를 기본적으로 작성합니다.Docker 호스트와 Docker 컨테이너 모두 해당 브리지에 IP 주소가 있습니다.

Docker 호스트에서 Sudo IP Addr Show Docker0을 입력하십시오.

[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever

여기에서 Docker 호스트에는 Docker0 네트워크 인터페이스에 IP 주소 172.17.42.1이 있습니다.

이제 새 컨테이너를 시작하고 쉘을 가져옵니다. Docker Run -rm -It Ubuntu : Trusty BASH 및 컨테이너 유형 IP Addr Show eth0은 주 네트워크 인터페이스를 어떻게 설정하는지 알아보십시오.

root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.1.192/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
       valid_lft forever preferred_lft forever

여기서 내 용기에는 IP 주소가 172.17.1.192가 있습니다.이제 라우팅 테이블을보십시오.

root@e77f6a1b3740:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

따라서 Docker Host 172.17.42.1의 IP 주소는 기본 경로로 설정되며 컨테이너에서 액세스 할 수 있습니다.

root@e77f6a1b3740:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

Docker Run -network = "호스트"

또는 네트워크 설정이 호스트로 설정된 Docker 컨테이너를 실행할 수 있습니다.이러한 컨테이너는 네트워크 스택을 Docker 호스트와 컨테이너 시점에서 공유합니다. localhost (또는 127.0.0.1)는 Docker 호스트를 참조합니다.

Docker 컨테이너에서 열린 모든 포트가 Docker 호스트에서 열리게됩니다.-p 또는 -p docker 실행 옵션이 필요하지 않고

내 Docker 호스트에서 IP 구성 :

[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

및 호스트 모드의 Docker 컨테이너에서 :

[vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

Docker 호스트와 Docker 컨테이너가 모두 동일한 동일한 네트워크 인터페이스를 공유하고 동일한 IP 주소가 동일하게 표시됩니다.


컨테이너에서 MySQL에 연결합니다

브리지 모드

브리지 모드의 컨테이너에서 Docker 호스트에서 실행되는 MySQL에 액세스하려면 MySQL 서비스가 172.17.42.1 IP 주소의 연결을 수신 대기하는지 확인해야합니다.

이렇게하려면 MySQL Config File (my.cnf)에 바인드 주소 = 172.17.42.1 또는 bind-address = 0.0.0.0이 있는지 확인하십시오.

게이트웨이의 IP 주소로 환경 변수를 설정 해야하는 경우 컨테이너에서 다음 코드를 실행할 수 있습니다.

export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')

그런 다음 응용 프로그램에서 docker_host_ip 환경 변수를 사용하여 MySQL에 대한 연결을 엽니 다.

참고 : bind-address = 0.0.0.0을 사용하는 경우 MySQL 서버는 모든 네트워크 인터페이스의 연결을 수신합니다.즉, MySQL 서버가 인터넷에서 도달 할 수 있음을 의미합니다.그에 따라 방화벽 규칙을 설정하십시오.

참고 2 : BIND-ADDRESS = 172.17.42.1을 사용하는 경우 MYSQL 서버는 127.0.0.1로 만들어진 연결을 수신하지 않습니다.MySQL에 연결하려는 Docker 호스트에서 실행되는 프로세스는 172.17.42.1 IP 주소를 사용해야합니다.

호스트 모드

호스트 모드의 컨테이너에서 Docker 호스트에서 실행중인 MySQL에 액세스하려면 Bind-Address = 127.0.0.1을 MySQL 구성에 보관할 수 있으며 모든 컨테이너에서 127.0.0.1에 연결하는 것입니다.

[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

참고 : mysql -h 127.0.0.1 및 mysql -h localhost이 아님을 사용하십시오.그렇지 않으면 MySQL 클라이언트가 UNIX 소켓을 사용하여 연결하려고합니다.



답변

모든 플랫폼 용

Docker v 20.10 이상 (2020 년 12 월 14 일 이후)

내부 IP 주소를 사용하거나 호스트가 사용하는 내부 IP 주소로 해석되는 특수 DNS 이름 host.docker.internal에 연결하십시오.

Linux에서 -add-host = host.docker.internal : host-gateway이 기능을 활성화하려면 host-gateway.Linux에서 Docker 작성을 사용하려면 컨테이너 정의에 다음 줄을 추가하십시오.

extra_hosts:
    - "host.docker.internal:host-gateway"

Docker의 오래된 MacOS 및 Windows 버전의 경우

Docker V 18.03 이상 (2018 년 3 월 21 일 이후)

내부 IP 주소를 사용하거나 호스트가 사용하는 내부 IP 주소로 해석되는 특수 DNS 이름 host.docker.internal에 연결하십시오.

Linux 지원 https://github.com/docker/for-linux/issues/264

docker의 오래된 MacOS 버전의 경우

MAC v 17.12에서 V 18.02 용 Docker

위와 동일하지만 docker.for.mac.host.internal을 대신 사용하십시오.

Docker 용 Mac V v 17.06 ~ V 17.11.

위와 동일하지만 docker.for.mac.localhost를 사용하십시오.

Mac 17.05 및 아래의 Docker

Docker 컨테이너에서 호스트 시스템에 액세스하려면 네트워크 인터페이스에 IP 별명을 첨부해야합니다.원하는 IP를 바인딩 할 수 있습니다.

sudo ifconfig lo0 별칭 123.123.123.123/24.

그런 다음 서버가 위에서 언급 한 IP 또는 0.0.0.0을 듣는지 확인하십시오.LocalHost 127.0.0.1에서 듣는 경우 연결을 수락하지 않습니다.

그런 다음 Docker 컨테이너를이 IP로 가리키면 호스트 시스템에 액세스 할 수 있습니다!

테스트하려면 CURL -X GET 123.123.123.123:3000을 컨테이너 내부에서 실행할 수 있습니다.

별칭은 모든 재부팅에서 재설정되어 필요한 경우 시작 스크립트를 만듭니다.

솔루션 및 더 많은 설명서 : https://docs.docker.com/docker-for-mac/networking/#use-cases-andoworounds.



답변

사용

host.docker.internal

대신에

localhost

나를 위해 완벽하게 작동합니다.👍.



답변

Linux 용 솔루션 (커널> = 3.6).

OK, 로컬 호스트 서버에는 IP 주소 172.17.0.1이있는 기본 Docker Interface Docker0이 있습니다.컨테이너는 기본 네트워크 설정으로 시작되었습니다. -net = "Bridge".

  1. Enable route_localnet for docker0 interface:

    $ sysctl -w net.ipv4.conf.docker0.route_localnet=1
    
  2. Add this rules to iptables:

    $ iptables -t nat -I PREROUTING -i docker0 -d 172.17.0.1 -p tcp --dport 3306 -j DNAT --to 127.0.0.1:3306
    $ iptables -t filter -I INPUT -i docker0 -d 127.0.0.1 -p tcp --dport 3306 -j ACCEPT
    
  3. Create MySQL user with access from '%' that mean - from anyone, excluding localhost:

    CREATE USER 'user'@'%' IDENTIFIED BY 'password';
    
  4. Change in your script the mysql-server address to 172.17.0.1.

커널 문서에서 :

Route_LocalNet - Boolean : 라우팅하는 동안 Martian Source 또는 Destination으로 루프백 주소를 고려하지 마십시오.이렇게하면 로컬 라우팅 용으로 127/8을 사용할 수 있습니다 (기본값은 false).



답변

위의 게시물과 비슷한 해킹을 수행하면 로컬 IP가 컨테이너의 별칭 이름 (DNS)에 매핑되도록합니다.주요 문제는 Linux 및 OSX에서 호스트 IP 주소에서 작동하는 간단한 스크립트로 동적으로 얻는 것입니다.나는 두 환경에서 작동하는이 스크립트 ( "$ lang"로 Linux 배포판에서도! = "en_ *"구성) :

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1

따라서 Docker Compose를 사용하여 전체 구성은 다음과 같습니다.

시작 스크립트 (Docker-Run.sh) :

export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)
docker-compose -f docker-compose.yml up

Docker-Compose.yml :

myapp:
  build: .
  ports:
    - "80:80"
  extra_hosts:
    - "dockerhost:$DOCKERHOST"

그런 다음 해당 코드에서 http : // localhost를 http : // dockerhost로 변경하십시오.

DockerHost 스크립트를 사용자 정의하는 방법에 대한 자세한 가이드는 어떻게 작동하는지에 대한 설명 으로이 게시물을 살펴보십시오.



답변

Mac OSX를위한 가장 간단한 솔루션

Mac의 IP 주소를 사용하십시오.Mac 에서이 기능을 실행하여 컨테이너 내에서 사용하십시오.

ifconfig | grep 'inet 192'| awk '{ print $2}'

Mac 또는 다른 Docker 컨테이너에서 로컬로 실행되는 서버가 0.0.0.0을 수신하는 한, Docker 컨테이너는 해당 주소에서 밖으로 나올 수 있습니다.

0.0.0.0에서 수신 대기하는 다른 Docker 컨테이너에 액세스하려면 172.17.0.1을 사용할 수 있습니다.

출처:https://stackoverflow.com/questions/24319662/from-inside-of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach