programing

도커 컨테이너 내부에서 기기의 로컬 호스트에 연결하려면 어떻게 해야 합니까?

subpage 2023. 10. 16. 21:52
반응형

도커 컨테이너 내부에서 기기의 로컬 호스트에 연결하려면 어떻게 해야 합니까?

도커 컨테이너 안에 있는 Nginx를 가지고 있습니다.호스트 시스템에서 MySql을 실행하고 있습니다.컨테이너 내에서 MySql에 연결하고 싶습니다.MySql은 로컬 호스트 디바이스에만 바인딩되어 있습니다.

이 도커 컨테이너 내에서 이 MySql 또는 로컬 호스트의 다른 프로그램에 연결할 수 있는 방법이 있습니까?

이 질문은 "도커 컨테이너 내부에서 도커 호스트의 IP 주소를 가져오는 방법"과 다릅니다. 도커 호스트의 IP 주소가 도커 컨테이너 내부에서 연결되거나 연결되지 않을 수 있는 네트워크의 퍼블릭 IP 또는 프라이빗 IP일 수 있기 때문입니다(즉, AWS에서 호스팅되는 경우 퍼블릭 IP를 의미합니다).도커 호스트의 IP 주소를 가지고 있더라도 컨테이너 내에서 도커 호스트에 연결할 수 있는 것은 아닙니다. 도커 네트워크의 IP 주소가 오버레이, 호스트, 브리지, macvlan, none 등으로 해당 IP 주소의 도달 가능성을 제한할 수 있기 때문입니다.

편집:

Docker-for-mac 또는 Docker-for-Windows 18.03+를 사용하는 경우 호스트를 사용하여 mysql 서비스에 연결합니다.host.docker.internal)의d)127.0.0.1연결 문자열에 입력합니다.)

리눅스용 도커(Docker-for-Linux) 20.10.0+를 사용하는 경우 호스트를 사용할 수도 있습니다.host.docker.internal 만약 당신이 도커 컨테이너를 시작했다면.--add-host host.docker.internal:host-gateway 토막글을 추가했습니다.했습니다-composite.yml커.

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

그렇지 않으면 아래를 읽으십시오.


TLDR

사용하다--network="host"n에docker run어,어127.0.0.1도커 컨테이너에서 도커 호스트를 가리킵니다.

참고: 이 모드는 설명서에 따라 Linux용 도커에서만 작동합니다.


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

도커는 컨테이너를 실행할 때 다양한 네트워킹 모드를 제공합니다.선택한 모드에 따라 도커 호스트에서 실행 중인 MySQL 데이터베이스에 다르게 연결할 수 있습니다.

도커 실행 --network="bridge"(기본값)

는 라는 .docker0기본적으로.도커 호스트와 도커 컨테이너 모두 해당 브리지에 IP 주소가 있습니다.

도커 호스트에서 다음을 입력합니다.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

내 가 IP 를 있습니다.172.17.42.1docker0네트워크 인터페이스.

새 하고 그 껍질을 .docker run --rm -it ubuntu:trusty bashdip 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

도커 실행 --network="host"

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

도커 컨테이너에 열려 있는 포트는 도커 호스트에서 열립니다.그리고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_IPMySQL에 대한 연결을 열기 위한 환경 변수.

참고: 다음을 사용하는 경우bind-address = 0.0.0.0MySQL 서버는 모든 네트워크 인터페이스에서 연결을 수신합니다.인터넷에서 MySQL 서버에 연결할 수 있으므로 방화벽 규칙을 적절하게 설정해야 합니다.

참고 2: 다음을 사용하는 경우bind-address = 172.17.42.1의 MySQL다에 .127.0.0.1는 ..172.17.42.1IP 주소.

호스트 모드

호스트 모드의 컨테이너에서 도커 호스트에서 실행되는 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 클라이언트는 유닉스 소켓을 사용하여 연결을 시도할 것입니다.

모든 플랫폼용

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

IP DNS 합니다에 합니다.host.docker.internal호스트에서 사용하는 내부 IP 주소로 확인됩니다.

이는 개발용이며 도커 데스크톱 외부의 프로덕션 환경에서는 작동하지 않습니다.

리눅스 주의 사항

리눅스의 도커에서 이 기능을 활성화하려면 다음을 추가합니다.--add-host=host.docker.internal:host-gatewayo대로docker명령을 실행합니다.

리눅스의 Docker Composition에서 이를 활성화하려면 컨테이너 정의에 다음 행을 추가합니다.

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

한 DNS 합니다 합니다.bridge사용자 지정 네트워크가 아닌 네트워크입니다.

이전 MacOS 및 Windows 버전의 도커용

도커 v 18.03 이상 (2018년 3월 21일 이후)

IP DNS 합니다에 합니다.host.docker.internal호스트에서 사용하는 내부 IP 주소로 확인됩니다.

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

이전 macOS 버전의 도커용

Mac v 17.12 ~ v 18.02용 도커

:docker.for.mac.host.internal대신.

Mac v 17.06 ~ v 17.11용 도커

:docker.for.mac.localhost대신.

Mac용 도커 17.05 이하

도커 컨테이너에서 호스트 시스템에 액세스하려면 네트워크 인터페이스에 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/desktop/networking/ #사용 사례 및 해결 방법-모든 것을 위한-

사용하다

host.docker.internal

대신에

localhost

위 게시물과 유사한 해킹을 하여 로컬 IP를 컨테이너의 별칭 이름(DNS)으로 매핑합니다.가장 큰 문제는 Linux와 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 Composition을 사용하면 전체 구성은 다음과 같습니다.

시작 스크립트(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

도커- compose.yml:

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

요.http://localhost.http://dockerhost자네 코드대로

DOCKERHOST대본, 어떻게 작동하는지 설명과 함께 이 게시물을 보세요.

리눅스용 솔루션(kernel >= 3.6).

네 , 요.localhost다가(가) .docker0172.17.0.1가 기본 되었습니다(으)로되었습니다.--net="bridge".

  1. 가능하게 하다route_localnet위해서docker0인터페이스:

    $ 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에서 수 MySQL '%' 말은 -은을 -든,든localhost:

    CREATE USER 'user'@'%' IDENTIFIED BY 'password';
    
  4. 를 에서 mysql-server 합니다(으)로합니다.172.17.0.1.

커널 설명서에서:

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

은 NGINX/PHP-FPM 했습니다에 수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

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

Mac의 IP 주소만 사용하면 됩니다.Mac에서 다음을 실행하여 IP 주소를 가져와 컨테이너 내에서 사용합니다.

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

또는 도커 에서 로컬로 을 청취하는 한,0.0.0.0그 주소,이 가능합니다.

0.0.0.0합니다.172.17.0.1

IP 를로 할 수 있습니다.ifconfig x)xipconfig(window) 그런 다음 docker-compose.yml을 만듭니다.

version: '3' # specify docker-compose version
services:
  nginx:
    build: ./ # specify the directory of the Dockerfile
    ports:
      - "8080:80" # specify port mapping
    extra_hosts:
      - "dockerhost:<yourIP>"

이렇게 하면 컨테이너가 호스트에 액세스할 수 있습니다.이 DB다)을 dockerhost고.portDB가 실행 중인 호스트.

다음과 같은 몇 가지 솔루션이 고려됩니다.

  1. 먼저 종속성을 컨테이너로 이동
  2. 다른 서비스를 외부에서 액세스할 수 있도록 하고 해당 외부 IP를 사용하여 해당 서비스에 연결합니다.
  3. 네트워크 분리 없이 컨테이너 실행
  4. 네트워크를 통해 연결하지 않도록 하고 대신 볼륨으로 장착된 소켓을 사용합니다.

이 문제가 해결되지 않는 이유는 컨테이너가 기본적으로 자체 네트워크 네임스페이스로 실행되기 때문입니다.즉, localhost(또는 루프백 인터페이스를 가리키는 127.0.0.1)는 컨테이너마다 고유합니다.이것에 연결하면 컨테이너 자체에 연결되며 도커 외부 또는 다른 도커 컨테이너 내부에서 실행되는 서비스가 아닙니다.

옵션 1: 의존성을 컨테이너로 옮길 수 있다면, 먼저 이렇게 하겠습니다.다른 사용자가 자신의 환경에서 컨테이너를 실행하려고 할 때 응용프로그램 스택을 휴대할 수 있습니다.또한 마이그레이션되지 않은 다른 서비스가 포트에 연결할 수 있는 호스트의 포트를 게시할 수도 있습니다.포트를 도커 호스트의 로컬 호스트 인터페이스에 게시하여 다음과 같은 구문으로 외부에서 액세스할 수 없도록 할 수도 있습니다.-p 127.0.0.1:3306:3306게시된 포트에 대해.

옵션 2: 컨테이너 내부에서 호스트 IP 주소를 탐지하는 방법은 다양하지만 각각 작동하는 시나리오의 수는 제한적입니다(예: Mac용 도커 필요).가장 휴대하기 쉬운 옵션은 다음과 같은 환경 변수나 구성 파일과 같은 것을 사용하여 호스트 IP를 컨테이너에 주입하는 것입니다.

docker run --rm -e "HOST_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')" ...

이를 위해서는 서비스가 해당 외부 인터페이스에서 수신 중이어야 하므로 보안 문제가 될 수 있습니다.컨테이너 내부에서 호스트 IP 주소를 가져오는 다른 방법은 이 게시물을 참조하십시오.

휴대성이 약간 떨어지는 것이 사용하기에 적합합니다.host.docker.internal 이것은 윈도우용 도커와 맥용 도커의 최신 버전에서 작동합니다.그리고 20.10에서 다음과 같은 특별한 호스트 항목을 통과하면 리눅스용 도커(Docker for Linux)에 이 기능이 추가되었습니다.

docker run --add-host host.docker.internal:host-gateway ...

host-gateway는 호스트 IP로 자동 확장되는 도커 20.10에 추가된 특별한 값입니다.자세한 내용은 이 PR을 참조하십시오.

옵션 3: 네트워크 분리 없이 실행, 예를 들어 다음과 같이 실행--net host 네트워크 네임스페이스인되고 있음을 합니다.이렇게 하면 컨테이너에 대한 격리가 덜 되고 DNS를 사용하는 공유 도커 네트워크를 통해 다른 컨테이너에 액세스할 수 없습니다(대신 컨테이너로 연결된 다른 응용프로그램에 액세스하려면 게시된 포트를 사용해야 함).만 하는 에 액세스해야 하는 r127.0.0.1호스트에서 가장 쉬운 옵션이 될 수 있습니다.

옵션 4: 다양한 서비스를 통해 파일 시스템 기반 소켓을 통한 액세스도 가능합니다.이 소켓은 바인딩 마운트 볼륨으로 컨테이너에 마운트할 수 있으므로 네트워크를 거치지 않고 호스트 서비스에 액세스할 수 있습니다.도커 엔진에 접근하기 위해, 종종 장착의 예를 볼 수 있습니다./var/run/docker.sock(해당 컨테이너 루트를 호스트에 액세스할 수 있도록 함).하면 mysql로,다 할 수 -v /var/run/mysqld/mysqld.sock:/var/run/mysqld/mysql.sock할 수 있습니다.localhost합니다.

윈도우 10용 솔루션

도커 커뮤니티 에디션 17.06.0-ce-win18 2017-06-28 (안정적)

의 DNS 의 할 수 .docker.for.win.localhost ( 언급, 로합니다를 합니다.) (를 참조하십시오.windows하지만 그래야 합니다.win)

개요
유사한 작업을 수행해야 했습니다. 즉, 도커 컨테이너에서 로컬 호스트로 연결하는 것입니다. 이 작업은
Azure Storage Emulator그리고.CosmosDB Emulator.

Azure Storage Emulator기본적으로 127.0.0.1에서 청취하지만 IP 경계도 변경할 수 있지만 기본 설정에서 작동하는 솔루션을 찾고 있었습니다.

내에서 로 가 있습니다.SQL Server그리고.IIS으로 둘 다 내 됩니다.

창문의 경우,

에서 database spring.datasource.url=jdbc:postgresql://host.docker.internal:5432/apidb

그런 다음 이미지를 만들고 실행합니다.그것은 나에게 효과가 있었다.

않았지만 10 Home 에서 Docker Toolbox 를,10.0.2.2호스트를 이 주소의 VM에 노출시키는 VirtualBox를 사용하기 때문에 그렇습니다.

이것은 실제 질문에 대한 답이 아닙니다.이것이 제가 비슷한 문제를 해결한 방법입니다.솔루션은 전적으로 다음과 같습니다.컨테이너가 통신할 수 있도록 도커 컨테이너 네트워킹을 정의합니다.닉 라보이 덕분에

한 컨테이너와 다른 컨테이너 간에 REST 통화를 수행하고 싶은 다른 사람들을 위해 이 정보를 여기에 둡니다.도커 환경에서 로컬 호스트 대신 무엇을 사용해야 합니까?라는 질문에 답합니다.

해 보십시오.docker network ls

docker network create -d my-net

docker run -d -p 5000:5000 --network="my-net" --name "first_container" <MyImage1:v0.1>

합니다.docker inspect first_container "이 "Networks": "my-net" 이 있어야 합니다.

합니다. docker run -d -p 6000:6000 --network="my-net" --name "second_container" <MyImage2:v0.1>

번째 합니다.docker inspect second_container "이 "Networks": "my-net" 이 있어야 합니다.

두 에 ssh 를에 .docker exec -it second_container sh아니면docker exec -it second_container bash.

두 에서 첫 를 ping 수 ping first_container. 또한, 당신의 코드는 다음과 같이 호출합니다.http://localhost:5000할 수 http://first_container:5000

Linux의 경우 localhost 서비스가 바인딩하는 인터페이스를 변경할 수 없습니다.

우리가 해결해야 할 두 가지 문제가 있습니다.

  1. 호스트의 IP 가져오기
  2. 도커가 로컬 호스트 서비스를 이용할 수 있도록 함

첫 번째 문제는 다른 답변이 제시한 것처럼 쿠몬의 도커 호스트 이미지를 사용하여 해결할 수 있습니다.

다른 컨테이너와 동일한 브리지 네트워크에 이 컨테이너를 추가해야 액세스할 수 있습니다.합니다 ping고를 수 합니다.dockerhost.

bash-5.0# ping dockerhost
PING dockerhost (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.523 ms

더 어려운 문제는 도커가 서비스에 접근할 수 있게 만드는 것입니다.

telnet을 사용하여 호스트의 포트에 액세스할 수 있는지 확인할 수 있습니다(이 포트를 설치해야 할 수도 있음).

문제는 컨테이너가 SSH와 같은 모든 인터페이스에 바인딩되는 서비스에만 액세스할 수 있다는 것입니다.

bash-5.0# telnet dockerhost 22
SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3

그러나 localhost에만 바인딩된 서비스는 액세스할 수 없습니다.

bash-5.0# telnet dockerhost 1025
telnet: can't connect to remote host (172.20.0.2): Connection refused

여기서 적절한 해결책은 서비스를 도커 브리지 네트워크에 바인딩하는 것입니다.그러나 이 답변은 사용자가 이를 변경할 수 없다고 가정합니다.에를 입니다.iptables.

가 와 .ifconfig 이 입니다.docker0 . 로 .br-그 도커가 대신 사용할 겁니다..br-5cd80298d6f4.

이 다리의 이름을 알게 되면 이 다리에서 로컬 호스트로의 라우팅을 허용해야 합니다.보안상의 이유로 기본적으로 비활성화되어 있습니다.

sysctl -w net.ipv4.conf.<bridge_name>.route_localnet=1

이제 우리의 것을 설정합니다.iptables규칙. 컨테이너는 도커 브리지 네트워크의 포트에만 액세스할 수 있으므로 서비스가 실제로 이 네트워크의 포트에 바인딩된 것으로 간주합니다.

를 위해 요청을 <docker_bridge>:port.localhost:port

iptables -t nat -A PREROUTING -p tcp -i <docker_bridge_name> --dport <service_port> -j DNAT --to-destination 127.0.0.1:<service_port>

예를 들어 포트 1025에서의 서비스의 경우.

iptables -t nat -A PREROUTING -p tcp -i br-5cd80298d6f4 --dport 1025 -j DNAT --to-destination 127.0.0.1:1025

이제 컨테이너에서 서비스에 액세스할 수 있습니다.

bash-5.0# telnet dockerhost 1025
220 127.0.0.1 ESMTP Service Ready

--net=host를 사용하여 실행하는 경우 localhost가 정상적으로 작동합니다.기본 네트워킹을 사용하는 경우 정적 IP 172.17.0.1을 사용합니다.

보기 - https://stackoverflow.com/a/48547074/14120621

Windows(윈도우) 사용자의 경우 브리지 네트워크 드라이버를 사용한다고 가정하면 MySQL을 하이퍼-v 네트워크 인터페이스의 IP 주소에 특별히 바인딩하기를 원할 것입니다.

이 됩니다 됩니다.C:\ProgramData\MySQL폴더.

에 대한 0.0.0.0작동하지 않습니다.고 였습니다.10.0.75.1.

편집: GitHub에서 컨셉 시제품을 제작했습니다.체크아웃: https://github.com/sivabudh/system-in-a-box


먼저, 제 대답은 맥을 사용하는 사람과 리눅스를 사용하는 사람의 두 그룹에 맞추어져 있습니다.

Mac에서는 호스트 네트워크 모드가 작동하지 않습니다.IP 별칭을 사용해야 합니다. https://stackoverflow.com/a/43541681/2713729

호스트 네트워크 모드란?참조: https://docs.docker.com/engine/reference/run/ #/network-

둘째, Linux를 사용하시는 분들을 위해(Ubuntu 14.04 LTS를 직접 경험했으며 곧 생산 중인 16.04 LTS로 업그레이드 할 예정입니다), 그렇습니다, 도커 컨테이너 안에서 실행되는 서비스를 다음에 연결할 수 있습니다.localhost도커 호스트(예: 노트북)에서 실행되는 서비스.

어떻게?

핵심은 도커 컨테이너를 실행할 때 호스트 모드로 실행해야 한다는 것입니다.명령어는 다음과 같습니다.

docker run --network="host" -id <Docker image ID>

는 할 때.ifconfig(당신은 필요할 것입니다.apt-get install net-tools기를 당신의 .ifconfig호출 가능) 컨테이너 내부에서 네트워크 인터페이스가 도커 호스트(예: 노트북)의 네트워크 인터페이스와 동일하다는 것을 알 수 있습니다.

참고할 점은 Mac 사용자이지만 Parallels에서 Ubuntu를 실행하므로 Mac을 사용하는 것이 단점은 아닙니다. ;-)

를 이 NGINX 를 A/S MySQL 입니다.localhost.

먼저 이 문제를 해결해야 하는 옵션에 대해서는 이 답변을 참조하십시오.하지만 만약 당신이 사용하면.docker-compose추가할 수 있습니다.network_mode: host를 제공한 합니다를 합니다.127.0.0.1로컬 호스트에 연결합니다.이것은 위의 답변에 설명된 옵션 중 하나일 뿐입니다.아래에서 제가 어떻게 수정했는지 확인하실 수 있습니다.docker-compose.ymlhttps://github.com/geerlingguy/php-apache-container.git:

 ---
 version: "3"
 services:
   php-apache:
+    network_mode: host
     image: geerlingguy/php-apache:latest
     container_name: php-apache
...

+추가한 선을 나타냅니다.


[] 되었습니다.2.2는 둘 다 에서합니다. "host" "host" 는됩니다 "host" 는됩니다입니다.docker-compose.

 ---
 version: "2.2"

 services:
   php-apache:
+    network_mode: "host"
        or
+    network_mode: host
...

Thomas leveil의 답변에 동의하지 않습니다.

mysql을 172.17.42.1에 바인딩하면 호스트의 데이터베이스를 사용하는 다른 프로그램에서 이에 연결하지 못하게 됩니다.이 작업은 모든 데이터베이스 사용자가 도커라이징된 경우에만 수행됩니다.

mysql을 0.0.0.0에 바인딩하도록 하는 것은 db를 외부 세계에 개방할 것이며, 이는 매우 나쁜 일일 뿐만 아니라 원래 질문 작성자가 하고자 하는 것과는 반대입니다.그는 "MySql은 localhost에서 실행되며 포트를 외부로 노출하지 않으므로 localhost에서 바인딩됩니다."라고 명시적으로 말합니다.

ivant의 의견에 답하기

"mysql도 docker0에 바인딩하면 어떨까요?"

이것은 불가능합니다.mysql/mariadb 설명서에는 여러 인터페이스에 바인딩할 수 없다고 명시되어 있습니다.0, 1 또는 모든 인터페이스에만 바인딩할 수 있습니다.

결론적으로 도커 컨테이너에서 호스트의 (localhost 전용) 데이터베이스에 연결할 방법을 찾지 못했습니다.그것은 분명히 아주 흔한 패턴처럼 보이지만, 저는 그것을 어떻게 하는지.

시도해 보기:

version: '3.5'
services:
  yourservice-here:
    container_name: container_name
    ports:
      - "4000:4000"
    extra_hosts: # <---- here
      - localhost:192.168.1.202
      - or-vitualhost.local:192.168.1.202

갖기 위해192.168.1.202,사용하다ifconfig

저는 이게 통했어요.도움이 되길 바랍니다!

7년 만에 질문을 받았는데, 도커가 바뀌었거나 아무도 이런 식으로 시도하지 않았거나 하는 것입니다.그래서 저는 제 자신의 답을 넣을게요.

나는 모든 답이 복잡한 방법을 사용한다는 것을 발견했습니다.오늘 저는 이것이 필요했고, 두 가지 아주 간단한 방법을 찾았습니다.

  • 사용하다ipconfig아니면ifconfig호스트에서 모든 IP 주소를 기록합니다.그 중 적어도 두 개는 컨테이너에서 사용할 수 있습니다.

    • WiFi LAN 어댑터에 고정된 로컬 네트워크 주소가 있습니다.192.168.1.101. 이것은 일 수 있습니다.10.0.1.101. 결과는 라우터에 따라 달라집니다.
    • 에 WSL을 WSL 하는데, WSL 이라는 에가 있습니다.vEthernet소:172.19.192.1
  • 사용하다host.docker.internal 형태 또 의 답변이 대부분의 답변은 OS에 따라 이것 또는 다른 형태의 답변이 있습니다.이 이름은 현재 도커가 전 세계적으로 사용하고 있음을 암시합니다.

세 번째 옵션은 시스템의 WAN 주소, 즉 서비스 공급자가 지정한 IP를 사용하는 것입니다.그러나 IP가 정적이 아니며 라우팅 및 방화벽 설정이 필요한 경우에는 이 작업이 수행되지 않을 수 있습니다.

게이트웨이를 알아야 합니다!로컬 서버에 대한 내 해결책은 아래에 그것을 노출시키는 것이었습니다.0.0.0.0:8000, 그런 다음 서브넷으로 도커를 실행하고 컨테이너를 실행합니다.

docker network create --subnet=172.35.0.0/16 --gateway 172.35.0.1 SUBNET35
docker run -d -p 4444:4444 --net SUBNET35 <container-you-want-run-place-here>

를 수 .http://172.35.0.1:8000

게이트웨이 주소에 연결합니다.

❯ docker network inspect bridge | grep Gateway
                    "Gateway": "172.17.0.1"

호스트의 프로세스가 이 인터페이스 또는 모든 인터페이스에서 수신되고 도커 후에 시작되는지 확인합니다.systemd를 사용하는 경우, 도커 후에 시작되도록 하기 위해 아래를 추가할 수 있습니다.

[Unit]
After=docker.service

❯ python -m http.server &> /dev/null &
[1] 149976

❯ docker run --rm python python -c  "from urllib.request import urlopen;print(b'Directory listing for' in urlopen('http://172.17.0.1:8000').read())" 
True

여기 제 해결책이 있습니다. 제 경우에 효과가 있습니다.

  • mysql로 를 공용 합니다. #bind-address = 127.0.0.1 l.d/etclf.conf.에서

  • mysql을 시작합니다.sudo /etc/init.d/mysql restart

  • .mysql -uroot -proot GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES;

  • sh 스크립트 생성: run_docker.sh

#!빈/
HOSTIP='ip -4 addr show scope global deveth0 | grepinet | awk '{print \$2}' | cut -d / -f 1'

도커 런 - it -d --name web-app \--add-host=local:${HOSTIP} \-p 8080:8080 \-e Database_HOST=${HOSTIP} \-e 데이터베이스_PORT=3306 \-e DATABASE_NAME= demo \-e DATABASE_USER=root \-e DATABASSUE=루트 \soheamak/스프링부츠_ dock_
  
  • 도커와 함께 달립니다.

     : '2.1'

    서비스:
    tomcat war: hosts추가_hosts: -- "로컬 : 10.1.2.232" : springboot_dock_mysql이미지 : soheamak/springboot_dock_
    포트:- 8080:80 환경:- =local- DATABATE_HOST=local -=- DATABASE_USER= 루트 -=- DATABASE_PASWORD= 루트 -=- DATABASE_NAME=- = - DATABASE_PORT=3306

알파인 이미지를 이용하여 호스트 IP를 얻을 수 있습니다.

docker run --rm alpine ip route | awk 'NR==1 {print $3}'

명령을 실행할 때 항상 알파인을 사용하기 때문에 더 일관성이 있습니다.

마리아노의 답변과 마찬가지로 동일한 명령을 사용하여 환경 변수를 설정할 수 있습니다.

DOCKER_HOST=$(docker run --rm alpine ip route | awk 'NR==1 {print $3}') docker-compose up

를 할 수.ifconfig호스트 머신에서 호스트 IP를 확인한 다음 컨테이너 내에서 IP에 연결하면 완벽하게 작동합니다.

CG 그룹과 네임스페이스는 컨테이너 생태계에서 중요한 역할을 하고 있습니다.

네임스페이스는 격리 계층을 제공합니다.각 컨테이너는 개별 네임스페이스에서 실행되며 해당 네임스페이스로 액세스가 제한됩니다.Cgroups는 각 컨테이너의 리소스 사용률을 제어하는 반면 네임스페이스는 프로세스가 해당 리소스를 보고 액세스할 수 있는 내용을 제어합니다.

다음은 여러분이 따를 수 있는 솔루션 접근 방식에 대한 기본적인 이해입니다.

네트워크 네임스페이스 사용

컨테이너가 이미지를 벗어나면 네트워크 인터페이스가 정의되어 생성됩니다.이것은 컨테이너에 고유 IP 주소와 인터페이스를 제공합니다.

$ docker run -it alpine ifconfig

네임스페이스를 호스트로 변경하면 코테이너 네트워크가 해당 인터페이스에 분리된 상태로 유지되지 않으므로 프로세스에서 호스트 시스템 네트워크 인터페이스에 액세스할 수 있습니다.

$ docker run -it --net=host alpine ifconfig

프로세스가 포트에서 수신하면 호스트 인터페이스에서 수신되고 컨테이너에 매핑됩니다.

PID 네임스페이스 사용 Pid 네임스페이스를 변경하면 컨테이너가 정상 범위를 벗어난 다른 프로세스와 상호 작용할 수 있습니다.

이 컨테이너는 자체 네임스페이스에서 실행됩니다.

$ docker run -it alpine ps aux

네임스페이스를 호스트로 변경하면 컨테이너는 시스템에서 실행 중인 다른 모든 프로세스도 볼 수 있습니다.

$ docker run -it --pid=host alpine ps aux

네임스페이스 공유

이는 취약점이 발생할 수 있는 컨테이너 보안 모델에서 벗어나 도청기에 쉽게 접근할 수 있기 때문에 프로덕션에서 이를 수행하는 것은 좋지 않은 관행입니다.이것은 단지 도구를 디버깅하고 컨테이너 보안의 허점을 과소평가하기 위한 것입니다.

첫 번째 컨테이너는 nginx 서버입니다.이렇게 하면 새 네트워크 및 프로세스 네임스페이스가 생성됩니다.이 컨테이너는 새로 만든 네트워크 인터페이스의 포트 80에 바인딩됩니다.

$ docker run -d --name http nginx:alpine

이제 다른 컨테이너가 이 네임스페이스를 재사용할 수 있습니다.

$ docker run --net=container:http mohan08p/curl curl -s localhost

또한 이 컨테이너는 공유 컨테이너의 프로세스와의 인터페이스를 볼 수 있습니다.

$ docker run --pid=container:http alpine ps aux

이렇게 하면 응용프로그램을 변경하거나 재시작하지 않고도 컨테이너에 더 많은 권한을 부여할 수 있습니다.호스트에서 mysql에 연결할 수 있는 것과 유사한 방법으로 애플리케이션을 실행하고 디버깅합니다.하지만, 이 길로 가는 것은 추천하지 않습니다.도움이 되길 바랍니다.

수정사항이 에 병합되지 않을 때까지masterbranch,트 IP하려면:

ip -4 route list match 0/0 | cut -d' ' -f3

(여기 @Mahoney가 제안한 대로).

MySQL에서 컨테이너의 IP에 대한 사용자를 생성하여 해결했습니다.

$ sudo mysql<br>
mysql> create user 'username'@'172.17.0.2' identified by 'password';<br>
Query OK, 0 rows affected (0.00 sec)

mysql> grant all privileges on database_name.* to 'username'@'172.17.0.2' with grant option;<br>
Query OK, 0 rows affected (0.00 sec)

$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
<br>bind-address        = 172.17.0.1

$ sudo systemctl restart mysql.service

에서:jdbc:mysql://<b>172.17.0.1</b>:3306/database_name

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

반응형