[nginx] Docker 컨테이너 내부에서 머신의 로컬 호스트에 어떻게 연결합니까?

도커 컨테이너 내에서 Nginx를 실행하고 localhost에서 mysql을 실행하고 있으며 Nginx 내에서 MySql에 연결하고 싶습니다. MySql은 localhost에서 실행 중이며 포트를 외부 세계에 노출시키지 않으므로 로컬 IP 주소는 컴퓨터의 IP 주소에 바인드되지 않습니다.

이 도커 컨테이너 내 에서이 MySql 또는 localhost의 다른 프로그램에 연결하는 방법이 있습니까?

이 질문은 도커 호스트의 IP 주소가 네트워크의 퍼블릭 IP 또는 프라이빗 IP 일 수 있다는 사실 때문에 “도커 컨테이너 내부에서 도커 호스트의 IP 주소를 얻는 방법”과 다릅니다. 도커 컨테이너 내에서 연결할 수 없습니다 (AWS에서 호스팅되는 경우 퍼블릭 IP를 의미합니다). Docker 호스트의 IP 주소가 있어도 Docker 네트워크가 오버레이, 호스트, 브리지, macvlan 등이 될 수 있으므로 IP 주소가 주어지면 컨테이너 내에서 docker 호스트에 연결할 수 없다는 의미는 아닙니다. 그 IP 주소.



답변

편집 : 당신이 사용하는 경우 부두 노동자를 위해 맥 또는 부두 노동자를 위해 윈도우 18.03+를 그냥 호스트 사용하여 MySQL의 서비스에 연결 host.docker.internal(대신의를 127.0.0.1연결 문자열에서).

Docker 18.09.3에서 Docker-for-Linux에서는 작동하지 않습니다. 수정은 3 월 8, 2019 제출 된 희망의 코드베이스에 병합됩니다. 그때까지 해결 방법은 qoomon ‘s answer에 설명 된대로 컨테이너를 사용하는 입니다.

2020-01 : 일부 진전 이 이루어졌습니다. 모든 것이 잘되면 Docker 20.04에 도착합니다.


TLDR

사용 --network="host"당신의 docker run다음 명령 127.0.0.1하여 고정 표시기 호스트를 가리 킵니다 당신의 고정 표시기 컨테이너에.

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


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

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

docker run –network = “bridge”(기본값)

Docker docker0는 기본적으로 이름이 지정된 브리지를 만듭니다 . 도커 호스트와 도커 컨테이너 모두 해당 브리지에 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

도커 호스트는 네트워크 인터페이스 172.17.42.1에 IP 주소 를 가지고 docker0있습니다.

이제 새로운 컨테이너를 시작하고 쉘을 가져옵니다. 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

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

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 = “host”

또는 네트워크 설정이로 설정된host 도커 컨테이너를 실행할 수 있습니다 . 이러한 용기는 고정 표시기 호스트와 볼의 용기 지점에서 네트워크 스택을 공유 localhost(또는 127.0.0.1고정 표시기 호스트를 참조한다).

도커 컨테이너에서 열린 포트는 도커 호스트에서 열립니다. 그리고 이것은 -p또는 -P docker run옵션 을 요구하지 않습니다 .

내 도커 호스트의 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

호스트 모드 의 도커 컨테이너에서 :

[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

보시다시피 도커 호스트와 도커 컨테이너는 모두 동일한 네트워크 인터페이스를 공유하므로 IP 주소가 동일합니다.


컨테이너에서 MySQL에 연결

브리지 모드

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

이렇게하려면, 당신이 중 하나를 가지고 있는지 확인 bind-address = 172.17.42.1또는 bind-address = 0.0.0.0MySQL의 설정 파일 (my.cnf의)에서.

게이트웨이의 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에 연결하려는 도커 호스트에서 실행되는 프로세스는 172.17.42.1IP 주소 를 사용해야합니다 .

호스트 모드

호스트 모드의 컨테이너에서 도커 호스트에서 실행되는 MySQL에 액세스하려면 bind-address = 127.0.0.1MySQL 구성을 유지 하고 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 클라이언트는 유닉스 소켓을 사용하여 연결을 시도합니다.


답변

macOS 및 Windows의 경우

Docker v 18.03 이상 (2018 년 3 월 21 일부터)

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

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

이전 버전의 Docker가있는 MacOS

Mac 용 Docker v 17.12 ~ v 18.02

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

Mac 용 Docker v 17.06 ~ v 17.11

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

Mac 17.05 이하용 Docker

도커 컨테이너에서 호스트 시스템에 액세스하려면 IP 별칭을 네트워크 인터페이스에 연결해야합니다. 원하는 IP를 바인딩 할 수 있으며 다른 IP에는 사용하지 않아야합니다.

sudo ifconfig lo0 alias 123.123.123.123/24

그런 다음 서버가 위에서 언급 한 IP 또는를 듣고 있는지 확인하십시오 0.0.0.0. 로컬 호스트에서 수신 대기 중이 127.0.0.1면 연결을 수락하지 않습니다.

그런 다음 도커 컨테이너를이 IP로 지정하면 호스트 시스템에 액세스 할 수 있습니다!

테스트하기 curl -X GET 123.123.123.123:3000위해 컨테이너 내부 와 같은 것을 실행할 수 있습니다 .

별칭은 재부팅 할 때마다 재설정되므로 필요한 경우 시작 스크립트를 작성하십시오.

솔루션 및 추가 문서 : https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds


답변

위의 게시물과 비슷한 해킹을 수행하여 로컬 IP를 컨테이너의 별칭 이름 (DNS)에 매핑하십시오. 주요 문제는 리눅스와 OSX에서 호스트 IP 주소로 작동하는 간단한 스크립트를 사용하여 동적으로 접근하는 것 입니다. 두 환경에서 작동하는이 스크립트를 수행했습니다 (Linux 배포가 "$LANG" != "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://localhosthttp://dockerhost코드에서.

DOCKERHOST스크립트 를 사용자 정의하는 방법에 대한 고급 안내서를 보려면 이 게시물 을 보고 스크립트 작동 방식에 대해 설명하십시오.


답변

이것은 앱이 연결할 수있는 코드 나 네트워킹을 건드리지 않고 NGINX / PHP-FPM 스택에서 나를 위해 일했습니다. localhost

mysqld.sock호스트에서 컨테이너 내부로 마운트 하십시오.

mysql을 실행하는 호스트에서 mysql.sock 파일의 위치를 ​​찾으십시오.
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'

도커에서 예상되는 위치에 해당 파일을 마운트하십시오.
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock

mysqld.sock의 가능한 위치 :

/tmp/mysqld.sock
/var/run/mysqld/mysqld.sock
/var/lib/mysql/mysql.sock
/Applications/MAMP/tmp/mysql/mysql.sock # if running via MAMP


답변

host.docker.internal모든 플랫폼에서 작업 할 때까지 수동 설정없이 컨테이너를 NAT 게이트웨이로 사용할 수 있습니다.

https://github.com/qoomon/docker-host


답변

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

로컬 호스트 서버에는 IP 주소가 172.17.0.1 인 기본 도커 인터페이스 docker0 이 있습니다. 컨테이너는 기본 네트워크 설정 –net = “bridge”로 시작했습니다 .

  1. docker0 인터페이스에 route_localnet을 활성화하십시오.
    $ sysctl -w net.ipv4.conf.docker0.route_localnet=1
  2. 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. 로컬 호스트를 제외한 모든 사람이 의미하는 ‘%’의 액세스 권한으로 mysql 사용자를 만듭니다.
    CREATE USER 'user'@'%' IDENTIFIED BY 'password';
  4. 스크립트에서 mysql-server 주소를 172.17.0.1로 변경하십시오.

로부터 커널 문서 :

route_localnet -BOOLEAN : 라우팅하는 동안 루프백 주소를 화성 소스 또는 대상으로 간주하지 마십시오. 이를 통해 로컬 라우팅 목적으로 127/8을 사용할 수 있습니다 ( 기본 FALSE ).


답변

Windows 10 용 솔루션

Docker Community Edition 17.06.0-ce-win18 2017-06-28 (안정적)

호스트의 DNS 이름을 사용 docker.for.win.localhost하여 내부 IP로 확인할 수 있습니다. (일부 언급 된 경고에주의 windows해야합니다. win)

개요

내를 실행중인 로컬 호스트, 내 부두 노동자의 컨테이너에 연결 비슷한, 할 필요가 Azure Storage EmulatorCosmosDB Emulator.

Azure Storage Emulator에 기본을 청취하여 127.0.0.1 , 당신은 너무, 나는 기본 설정으로 작동 할 수있는 솔루션을 찾고 있었다 바인딩 된 IP를 변경할 수있다.

이것은 또한 기본 포트 설정으로 호스트에서 로컬로 실행되는 Docker 컨테이너에서 SQL Server및 로 연결 IIS하는 데 사용됩니다.