programing

도커 컨테이너에서 호스트 포트에 액세스하는 방법

bestprogram 2023. 8. 20. 12:17

도커 컨테이너에서 호스트 포트에 액세스하는 방법

젠킨스가 작동하는 도커 컨테이너를 가지고 있습니다.빌드 프로세스의 일부로 호스트 시스템에서 로컬로 실행되는 웹 서버에 액세스해야 합니다.호스트 웹 서버(포트에서 실행되도록 구성할 수 있음)를 젠킨스 컨테이너에 노출할 수 있는 방법이 있습니까?

Linux 시스템에서 기본적으로 도커를 실행하고 있습니다.

업데이트:

아래의 @larsks 답변 외에도 호스트 시스템에서 호스트 IP의 IP 주소를 가져오려면 다음 작업을 수행합니다.

ip addr show docker0 | grep -Po 'inet \K[\d.]+'

모든 플랫폼용

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

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

이는 개발 목적이며 Docker Desktop 외부의 프로덕션 환경에서는 작동하지 않습니다.

Linux 주의 사항

Linux의 Docker에서 이 기능을 활성화하려면 다음을 추가합니다.--add-host=host.docker.internal:host-gateway의 신에게에.docker명령을 사용하여 기능을 클릭합니다.

리눅스의 Docker Composite에서 이 작업을 실행하려면 컨테이너 정의에 다음 행을 추가하십시오.

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

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

이전 버전의 MacOS 및 Windows Docker용

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

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

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

이전 버전의 MacOS Docker용

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 있는▁if우경인127.0.0.1연결을 허용하지 않습니다.

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

테스트하기 위해 다음과 같은 작업을 실행할 수 있습니다.curl -X GET 123.123.123.123:3000용기 안에.

재부팅할 때마다 별칭이 재설정되므로 필요한 경우 시작 스크립트를 만듭니다.

솔루션 및 기타 문서는 여기에서 확인할 수 있습니다. https://docs.docker.com/desktop/networking/ #모두를 위한 사용 사례 및 해결 방법

기본적으로 Linux의 수 .docker0에서 이 경로가 .컨테이너 내부에서 이 경로가 기본 경로가 됩니다.

예를 들어, 내 시스템에서:

$ ip addr show docker0
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::f4d2:49ff:fedd:28a0/64 scope link 
       valid_lft forever preferred_lft forever

그리고 컨테이너 내부:

# ip route show
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0  src 172.17.0.4 

간단한 셸 스크립트를 사용하여 이 IP 주소를 추출하는 것은 매우 쉽습니다.

#!/bin/sh

hostip=$(ip route show | awk '/default/ {print $3}')
echo $hostip

당신은 수야할있다다음습니수도해를 해야 할 수도 있습니다."를 수정해야 할 .iptables도커 컨테이너로부터의 연결을 허용하는 호스트의 규칙입니다.다음과 같은 방법으로 해결할 수 있습니다.

# iptables -A INPUT -i docker0 -j ACCEPT

이렇게 하면 도커 컨테이너에서 호스트의 모든 포트에 액세스할 수 있습니다.참고:

  • iptables 규칙은 순서가 지정되어 있으며, 이 규칙은 앞에 나오는 다른 규칙에 따라 올바른 작업을 수행할 수도 있고 수행하지 않을 수도 있습니다.

  • (a) 수신 중인 호스트 서비스에만 액세스할 수 있습니다.INADDR_ANY 0) 또는 (으)로 중인 (으)로 표시됩니다.docker0interface 이름


MacOS 또는 Windows 18.03+에서 Docker를 사용하는 경우 매직 호스트 이름에 연결할 수 있습니다.host.docker.internal.


할 수 . 예를 들어 "Linux"와 "Linux"를 설정하면 .--net=host localhost가 호트가같다니습다와 .localhost컨테이너 내부에서 컨테이너화된 서비스는 비동일화된 서비스처럼 작동하며 추가 구성 없이 액세스할 수 있습니다.

사용하다--net="host"의 신의에docker run에 명령, 음다localhost도커 컨테이너에서 도커 호스트를 가리킵니다.

답은...

를 바꿉니다.http://127.0.0.1또는http://localhost와 함께http://host.docker.internal.

왜요?

도커 문서의 출처입니다.

구글 검색을 통해 여기까지 오게 되었는데, 댓글을 뒤지고 보니 도커 컨테이너 내부의 복제품인데, 기계의 로컬 호스트에 연결하려면 어떻게 해야 합니까?나는 이것을 복제로 닫는 것에 투표했지만, 사람들(나를 포함해서!)은 종종 댓글을 주의 깊게 읽기보다는 답을 스크롤 다운하기 때문에, 여기 짧은 대답이 있습니다.

시스템의 주부터 시작할 수 20.04의 – 할 수도 있습니다.host.docker.internal자동으로 작동하지는 않지만 다음 실행 플래그를 지정해야 합니다.

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

도커 구성이 포함된 솔루션:호스트 기반 서비스에 액세스하려면 다음을 사용할 수 있습니다.network_mode매개 변수 https://docs.docker.com/compose/compose-file/ #network_mode

version: '3'
services:
  jenkins:
    network_mode: host

EDIT 2020-04-27: 로컬 개발 환경에서만 사용할 것을 권장합니다.

EDIT 2021-09-21: IHaveHandInMyResignation은 Mac과 Windows에서 작동하지 않는다고 썼습니다.이 옵션은 Linux에서만 지원됩니다.

저는 정확히 그 을 하기 위해 도커 컨테이너를 만들었습니다. https://github.com/qoomon/docker-host

dns를 수 예를 들어 " " " " " " " " " " " " " " " " " 입니다.curl http://dockerhost:9200

현재 Mac 및 윈도우즈에서 이 작업을 수행하는 가장 쉬운 방법은 호스트 시스템의 IP 주소로 확인되는 호스트를 사용하는 것입니다.안타깝게도 아직 리눅스에서는 작동하지 않습니다(2018년 4월 기준).

저는 다양한 솔루션을 조사해 보았는데, 이것이 가장 덜 진부한 솔루션이라는 것을 알게 되었습니다.

  1. 브리지 게이트웨이 IP의 정적 IP 주소를 정의합니다.
  2. 를 게트를추항추목다로에 합니다.extra_hostsdirection.

유일한 단점은 이 작업을 수행하는 여러 네트워크 또는 프로젝트가 있는 경우 해당 IP 주소 범위가 충돌하지 않도록 해야 한다는 것입니다.

다음은 도커 구성 예제입니다.

version: '2.3'

services:
  redis:
    image: "redis"
    extra_hosts:
      - "dockerhost:172.20.0.1"

networks:
  default:
    ipam:
      driver: default
      config:
      - subnet: 172.20.0.0/16
        gateway: 172.20.0.1

그런 다음 호스트 이름 "dockerhost"를 사용하여 컨테이너 내부에서 호스트의 포트에 액세스할 수 있습니다.

이러한 모든 네트워킹 정크에 대한 더 간단한 해결책은 서비스에 도메인 소켓을 사용하는 것입니다.호스트에 연결하려는 경우 소켓을 볼륨으로 마운트하면 됩니다.postgresql의 경우 다음과 같이 단순했습니다.

docker run -v /var/run/postgresql:/var/run/postgresql

그런 다음 네트워크 대신 소켓을 사용하도록 데이터베이스 연결을 설정합니다.말 그대로 그렇게 쉽습니다.

위해서docker-compose를 생성하는 으로, 사용 한 솔루션은 브지네트킹사컨간너전네생다성를니합크트워용에리테이을워용입니다. 승인된 솔루션은 다음을 사용합니다.docker0가 컨이너출인구스가작않동습다니지가 아니기 .docker0대신 다음과 같이 임의로 생성된 인터페이스 ID입니다.

$ ifconfig

br-02d7f5ba5a51: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.32.1  netmask 255.255.240.0  broadcast 192.168.47.255

안타깝게도 해당 랜덤 ID는 예측할 수 없으며 구성 시 네트워크를 다시 생성해야 할 때마다 변경됩니다(예: 호스트 재부팅). 저의 이에대내해은서알전에네만것다구입니성는하들을 구성하는 입니다.iptables해당 범위를 허용합니다.

파일 스니펫 작성:

version: "3.7"

services:
  mongodb:
    image: mongo:4.2.2
    networks:
    - mynet
    # rest of service config and other services removed for clarity

networks:
  mynet:
    name: mynet
    ipam:
      driver: default
      config:
      - subnet: "192.168.32.0/20"

환경에 필요한 경우 서브넷을 변경할 수 있습니다.로 임로선택습다니했의다를 선택했습니다.192.168.32.0/20을 이용하여docker network inspect기본적으로 생성되는 항목을 확인합니다.

를 구성합니다.iptables호스트에서 개인 서브넷을 소스로 허용:

$ iptables -I INPUT 1 -s 192.168.32.0/20 -j ACCEPT

한 가장 간단한 것입니다.iptables규칙. 예를 들어 대상 포트별로 다른 제한을 추가할 수 있습니다.하는 것이 할 때 iptables 을 유지하는 iptables 규대작것행때복마잊십오시지할이는.

이 접근 방식은 반복 가능하므로 자동화할 수 있다는 장점이 있습니다. ansible's 용사합니다를는을 합니다.template하여 my 한 다음 " " " " " 를 합니다.iptables그리고.shell모듈을 사용하여 방화벽 규칙을 각각 구성하고 유지합니다.

이것은 오래된 질문이고 많은 답을 가지고 있었지만, 그 중 어느 것도 제 맥락에 충분히 맞지 않습니다.이 경우 컨테이너는 매우 얇고 컨테이너 내에서 호스트의 IP 주소를 추출하는 데 필요한 네트워킹 도구가 없습니다.

그리고 는 한또, --net="host"접근 방식은 매우 대략적인 접근 방식으로, 여러 컨테이너로 네트워크를 잘 격리하려는 경우에는 적용할 수 없습니다.

에 있는 호스트의 에 그서제방호측스호에트스와 함께 에 전달하는 것입니다.--add-host매개변수:

$ docker run --add-host=docker-host:`ip addr show docker0 | grep -Po 'inet \K[\d.]+'` image_name

또는 호스트의 IP 주소를 환경 변수에 저장하고 나중에 다음 변수를 사용합니다.

$ DOCKERIP=`ip addr show docker0 | grep -Po 'inet \K[\d.]+'`
$ docker run --add-host=docker-host:$DOCKERIP image_name

그리고 그다음에docker-host파일에 되며, 할 수 있습니다.

저(Windows 10, Docker Engine v19.03.8)의 경우 https://stackoverflow.com/a/43541732/7924573 와 https://stackoverflow.com/a/50866007/7924573 가 혼합되어 있었습니다.

  1. host/ip을 host.syser.internal로 변경합니다.
    예: LOGER_URL = "http://host.dller.internal:8085/log"
  2. network_mode를 bridge로 설정합니다(포트 포워딩을 유지하려는 경우, host를 사용하지 않는 경우).
    version: '3.7' services: server: build: . ports: - "5000:5000" network_mode: bridge 또는 다음과 같은 방법으로 사용합니다.--net="bridge"도커-스캐너를 사용하지 않는 경우(https://stackoverflow.com/a/48806927/7924573) 와 유사).
    이전 답변에서 지적한 바와 같이:이는 로컬 개발 환경에서만 사용해야 합니다.
    자세한 내용은 https://docs.docker.com/compose/compose-file/ #network_mode 및 https://docs.docker.com/docker-for-windows/networking/ #사용 사례 및 해결 방법을 참조하십시오.

두 가지 방법으로 호스트 시스템에서 실행 중인 로컬 웹 서버에 액세스할 수 있습니다.

  1. 공개 IP를 사용한 접근 방식 1

    호스트 시스템 공용 IP 주소를 사용하여 Jenkins 도커 컨테이너의 웹 서버에 액세스합니다.

  2. 호스트 네트워크를 사용한 접근 2

    "--net host"를 사용하여 호스트의 네트워크 스택에 Jenkins 도커 컨테이너를 추가합니다.호스트의 스택에 배포된 컨테이너는 호스트 인터페이스에 대한 전체 액세스 권한을 가집니다.호스트 시스템의 개인 IP 주소를 사용하여 도커 컨테이너의 로컬 웹 서버에 액세스할 수 있습니다.

NETWORK ID          NAME                      DRIVER              SCOPE
b3554ea51ca3        bridge                    bridge              local
2f0d6d6fdd88        host                      host                local
b9c2a4bc23b2        none                      null                local

네트워크를 사용하여 Eg: docker run --net host -it ubuntu그리고 실행ifconfig도커 컨테이너에서 연결할 수 있는 모든 사용 가능한 네트워크 IP 주소를 나열합니다.

예: 로컬 호스트 시스템에서 anginx 서버를 시작했으며 Ubuntu 도커 컨테이너에서 nginx 웹 사이트 URL에 액세스할 수 있습니다.

docker run --net host -it ubuntu

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a604f7af5e36        ubuntu              "/bin/bash"         22 seconds ago      Up 20 seconds                           ubuntu_server

전용 네트워크 IP 주소를 사용하여 Ubuntu 도커 컨테이너에서 Nginx 웹 서버(로컬 호스트 시스템에서 실행 중)에 액세스합니다.

root@linuxkit-025000000001:/# curl 192.168.x.x -I
HTTP/1.1 200 OK
Server: nginx/1.15.10
Date: Tue, 09 Apr 2019 05:12:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 26 Mar 2019 14:04:38 GMT
Connection: keep-alive
ETag: "5c9a3176-264"
Accept-Ranges: bytes

거의 7년 만에 도커가 바뀌었거나 아무도 이런 식으로 시도하지 않았다는 질문이 나왔습니다.그래서 저는 제 대답을 포함하겠습니다.

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

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

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

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


PS: 비록질문과 꽤 동일하지만, 저는 여기에 이 답을 올렸습니다. 저는 처음에 이 글을 발견했습니다. 그래서 저의 답을 잊어버릴 수도 있기 때문에 여기에도 글을 올립니다.

가장 간단한 옵션은 로컬 네트워크에서 컴퓨터의 IP 주소를 사용하는 것이었습니다(라우터에서 할당).

이것은 다음을 사용하여 찾을 수 있습니다.ifconfig

ifconfig

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        options=400<CHANNEL_IO>
        ether f0:18:98:08:74:d4 
        inet 192.168.178.63 netmask 0xffffff00 broadcast 192.168.178.255
        media: autoselect
        status: active

그리고 인터넷 주소를 사용했습니다.이것은 제가 제 컴퓨터의 모든 포트를 연결하는 데 효과가 있었습니다.

두 개의 도커 이미지가 "이미" 생성되어 있고 서로 통신하기 위해 두 개의 컨테이너를 배치하려는 경우.

이를 위해 각 컨테이너를 고유한 --이름으로 편리하게 실행하고 --link 플래그를 사용하여 컨테이너 간의 통신을 사용할 수 있습니다.그러나 도커를 빌드하는 동안에는 이 정보를 얻을 수 없습니다.

당신이 나와 같은 시나리오에 있을 때, 그리고 그것은 당신의 것입니다.

docker build -t "centos7/someApp" someApp/ 

그것은 당신이 시도할 때 깨집니다.

curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz

"호스트 경로"를 반환하지 않고 "host/wget"에 갇히게 됩니다.

도커에서 설정한 보안 때문에 기본적으로 컨테이너에서 호스트 또는 호스트에서 실행 중인 다른 컨테이너로의 통신이 금지됩니다.이것은 저에게 매우 놀라운 일이었습니다. 로컬 기계에서 작동하는 도커 기계의 에코시스템이 너무 많은 장애물 없이 서로에게 접근할 수 있을 것입니다.

이에 대한 설명은 다음 설명서에 자세히 설명되어 있습니다.

http://www.dedoimedo.com/computers/docker-networking.html

네트워크 보안을 낮추어 이동하는 데 도움이 되는 두 가지 빠른 해결 방법이 제공됩니다.

가장 간단한 방법은 방화벽을 해제하거나 모두 허용하는 것입니다.즉, systemctl stop firewall, iptables -F 또는 동등한 명령을 실행할 수 있습니다.

언급URL : https://stackoverflow.com/questions/31324981/how-to-access-host-port-from-docker-container