도커 컨테이너로 호스트 포트 전달
호스트에서 도커 컨테이너 액세스 포트를 열 수 있습니까?구체적으로 호스트에서 MongoDB와 RabbitMQ를 실행하고 있으며 Docker 컨테이너에서 대기열을 듣고 (선택적으로) 데이터베이스에 쓰기 위한 프로세스를 실행하고 싶습니다.
컨테이너에서 호스트로 포트를 전달할 수 있으며(-p 옵션을 통해) 도커 컨테이너 내에서 외부(즉, 인터넷)에 연결할 수 있지만 호스트의 RabbitMQ 및 MongoDB 포트를 외부에 노출하지는 않습니다.
편집: 몇 가지 설명:
Starting Nmap 5.21 ( http://nmap.org ) at 2013-07-22 22:39 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00027s latency).
PORT STATE SERVICE
6311/tcp open unknown
joelkuiper@vps20528 ~ % docker run -i -t base /bin/bash
root@f043b4b235a7:/# apt-get install nmap
root@f043b4b235a7:/# nmap 172.16.42.1 -p 6311 # IP found via docker inspect -> gateway
Starting Nmap 6.00 ( http://nmap.org ) at 2013-07-22 20:43 UTC
Nmap scan report for 172.16.42.1
Host is up (0.000060s latency).
PORT STATE SERVICE
6311/tcp filtered unknown
MAC Address: E2:69:9C:11:42:65 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 13.31 seconds
컨테이너 내에서 인터넷 연결을 위해 다음과 같은 방법을 사용해야 했습니다.방화벽이 도커 컨테이너에서 외부로의 네트워크 연결을 차단하고 있습니다.
편집: 결국 파이프 구조를 사용하여 사용자 지정 브리지를 만들고 브리지 IP에서 서비스를 수신하도록 했습니다.저는 MongoDB와 Rabbit 대신에 이 접근법을 사용했습니다.MQ는 더 많은 유연성을 제공하기 때문에 도커 브리지에서 청취합니다.
간단하지만 상대적으로 안전하지 않은 방법은 다음을 사용하는 것입니다.--net=host
에 대한 선택권.docker run
.
이 옵션을 사용하면 컨테이너가 호스트의 네트워킹 스택을 사용합니다.그런 다음 "localhost"를 호스트 이름으로 사용하여 호스트에서 실행 중인 서비스에 연결할 수 있습니다.
도커 컨테이너의 IP 주소에서 연결을 허용하도록 서비스를 구성할 필요가 없고 포트만 있으면 도커 컨테이너에 연결할 특정 IP 주소나 호스트 이름을 지정할 필요가 없기 때문에 구성이 더 쉽습니다.
예를 들어 다음 명령을 실행하여 테스트할 수 있습니다. 이 명령은 이미지의 호출을 가정합니다.my_image
당신의 이미지는 다음을 포함합니다.telnet
25에 . 포트 25는 다음과 같습니다.
docker run --rm -i -t --net=host my_image telnet localhost 25
이 방법을 사용할 경우 이 페이지의 보안에 대한 주의 사항을 참조하십시오.
https://docs.docker.com/articles/networking/
다음과 같이 표시됩니다.
--net=host - 컨테이너를 별도의 네트워크 스택 내부에 배치하지 않도록 도커에 지시합니다.본질적으로, 이 선택은 도커에게 컨테이너의 네트워킹을 컨테이너화하지 말라고 말합니다!컨테이너 프로세스는 여전히 자체 파일 시스템과 프로세스 목록 및 리소스 제한으로 제한되지만, 빠른 ip addr 명령을 사용하면 기본 도커 호스트에서 "외부"에 상주하며 해당 네트워크 인터페이스에 대한 전체 액세스 권한을 가지고 있음을 알 수 있습니다.이렇게 하면 컨테이너가 호스트 네트워크 스택을 재구성할 수 없습니다. --privileged=true가 필요합니다. 그러나 컨테이너 프로세스는 다른 루트 프로세스와 마찬가지로 낮은 번호의 포트를 열 수 있습니다.또한 컨테이너가 D-bus와 같은 로컬 네트워크 서비스에 액세스할 수 있도록 합니다.이로 인해 컨테이너의 프로세스가 컴퓨터를 다시 시작하는 등 예기치 않은 작업을 수행할 수 있습니다.이 옵션은 주의해서 사용해야 합니다.
도커 호스트가 어댑터를 모든 컨테이너에 노출합니다.최근 Ubuntu를 사용하고 있다고 가정하면
ip addr
네트워크 어댑터 목록이 제공되며, 그 중 하나는 다음과 같습니다.
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 22:23:6b:28:6b:e0 brd ff:ff:ff:ff:ff:ff
inet 172.17.42.1/16 scope global docker0
inet6 fe80::a402:65ff:fe86:bba6/64 scope link
valid_lft forever preferred_lft forever
토끼/몽고에게 해당 IP(172.17.42.1)에 바인딩하도록 지시해야 합니다.그런 다음 컨테이너 내에서 172.17.42.1에 대한 연결을 열 수 있습니다.
코멘트 중 하나에서 언급한 것처럼, 이것은 Mac에서도 작동합니다(아마도 Windows/Linux에서도 작동할 수 있습니다.
컨테이너에서 호스트의 서비스로 연결합니다.
호스트의 IP 주소가 변경되고 있습니다(네트워크 액세스 권한이 없는 경우에는 IP 주소가 변경되지 않음).한 DNS 이름 "DNS"에 하는 것이 .
host.docker.internal
호스트에서 사용하는 내부 IP 주소로 확인됩니다.이는 개발 목적이며 Mac용 Docker Desktop 이외의 운영 환경에서는 작동하지 않습니다.다음을 사용하여 게이트웨이에 도달할 수도 있습니다.
gateway.docker.internal
.
https://docs.docker.com/docker-for-mac/networking/ 에서 인용
이것은 사용하지 않고도 작동했습니다.--net=host
.
SSH 터널을 생성할 수도 있습니다.
docker-compose.yml
:
---
version: '2'
services:
kibana:
image: "kibana:4.5.1"
links:
- elasticsearch
volumes:
- ./config/kibana:/opt/kibana/config:ro
elasticsearch:
build:
context: .
dockerfile: ./docker/Dockerfile.tunnel
entrypoint: ssh
command: "-N elasticsearch -L 0.0.0.0:9200:localhost:9200"
docker/Dockerfile.tunnel
:
FROM buildpack-deps:jessie
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive \
apt-get -y install ssh && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY ./config/ssh/id_rsa /root/.ssh/id_rsa
COPY ./config/ssh/config /root/.ssh/config
COPY ./config/ssh/known_hosts /root/.ssh/known_hosts
RUN chmod 600 /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/config && \
chown $USER:$USER -R /root/.ssh
config/ssh/config
:
# Elasticsearch Server
Host elasticsearch
HostName jump.host.czerasz.com
User czerasz
ForwardAgent yes
IdentityFile ~/.ssh/id_rsa
이쪽은elasticsearch
인 서비스search, )가 .SQL) 및 해당 서비스를 통해 포트 9200을 노출합니다.
TLDR;
로컬 개발의 경우에만 다음을 수행합니다.
- 랩톱/컴퓨터/PC/Mac에서 서비스 또는 SSH 터널을 시작합니다.
- 호스트 이름에 연결할 도커 이미지/컨테이너 구축/실행
host.docker.internal:<hostPort>
": 또있습다니한참고다있"도 있습니다.gateway.docker.internal
내가 시도하지 않은 것.
END_TLDR;
예를 들어 컨테이너에서 이 기능을 사용하는 경우:
PGPASSWORD=password psql -h localhost -p 5432 -d mydb -U myuser
다음으로 변경:
PGPASSWORD=password psql -h host.docker.internal -p 5432 -d mydb -U myuser
그러면 호스트 시스템에서 실행 중인 서비스에 마법처럼 연결됩니다.당신은 필요없다니습가사를 사용할 .--net=host
또는-p "hostPort:ContainerPort"
또는-P
배경
자세한 내용은 https://docs.docker.com/docker-for-mac/networking/ #사용 사례 및 해결 방법을 참조하십시오.
Windows 10에서 AWS RDS Postgres 인스턴스에 대한 SSH 터널과 함께 사용했습니다.사용에서 변경하기만 하면 되었습니다.localhost:containerPort
에서 의용에까지.host.docker.internal:hostPort
.
도커 컨테이너에서 LDAP-서버에 액세스하는 데 비슷한 문제가 있었습니다.컨테이너에 고정 IP를 설정하고 방화벽 규칙을 추가했습니다.
docker-compose.yml:
version: '2'
services:
containerName:
image: dockerImageName:latest
extra_hosts:
- "dockerhost:192.168.50.1"
networks:
my_net:
ipv4_address: 192.168.50.2
networks:
my_net:
ipam:
config:
- subnet: 192.168.50.0/24
iptables 규칙:
iptables -A INPUT -j ACCEPT -p tcp -s 192.168.50.2 -d $192.168.50.1 --dport portnumberOnHost
컨테이너 내부 액세스dockerhost:portnumberOnHost
MongoDB 및 RabbitMQ가 호스트에서 실행 중인 경우 포트가 도커 내에 없으므로 포트가 이미 노출되어 있어야 합니다.
필요하지 않습니다.-p
옵션을 사용하여 컨테이너에서 호스트로 포트를 노출합니다.기본적으로 모든 포트가 노출됩니다.-p
옵션을 사용하면 컨테이너의 포트를 호스트 외부에 노출할 수 있습니다.
그래서, 내 생각엔 당신은 필요 없을 것 같아요.-p
전혀 그리고 그것은 잘 작동하고 있을 것입니다 :)
host.docker.internal
또는gateway.docker.internal
일반적으로 도커 맥 데스크톱 컨테이너에 매우 잘 작동하지만, 이것은 또한 그것이 설정하는 수용된 수신기에 매우 인색한 카프카에 관한 한 실패합니다.
socat를 실행하여 컨테이너 내부의 9092 포트를 호스트로 전달하여 이 문제를 우회했습니다.
apt-get install -y socat && socat tcp-l:9092,fork tcp:host.docker.internal:9092 &
기본적으로 저는 카프카를 실행하는 컨테이너 1개와 카프카에 연결해야 하는 앱 컨테이너 1개를 가지고 있습니다.앱 컨테이너 kafka 브로커 설정하기["host.docker.internal:9092"]
작동하지 않습니다.그래서 저는 카프카 브로커들을["localhost:9092"]
socat을 사용하여 포트를 호스트로 포워딩합니다. 호스트는 카프카 컨테이너로 포트 포워딩을 수행합니다.
저는 많은 시행착오 끝에 이 해결책에 도달했습니다.이것이 누군가에게 도움이 되기를 바랍니다!
올바른 질문에 답하고 있는지는 잘 모르겠지만, ssh 터널링을 통해 컨테이너 내부에서 원격 서비스에 대한 액세스를 허용해야 하는 경우 다음과 같이 작동합니다.
원격 호스트의 서비스가 포트 8081에서 액세스할 수 있다고 가정하고 ssh로 연결하고 다음과 같은 터널을 생성합니다(시작할 때 0.0.0).
ssh ubuntu@remoteIp -L 0.0.0.0:8080:localhost:8081
이렇게 하면 컴퓨터에 액세스할 수 있는 모든 사용자가 포트 8080에 연결하여 연결된 서버의 포트 8081에 액세스할 수 있습니다.
그런 다음 컨테이너 내부에서 "host.docker.internal"을 사용합니다. 예:
curl host.docker.internal:8081
이렇게 약간 다른 솔루션을 사용하면 어떨까요?
services:
kubefwd:
image: txn2/kubefwd
command: ...
app:
image: bash
command:
- sleep
- inf
init: true
network_mode: service:kubefwd
참조: txn2/kubewd: 현지 개발을 위한 벌크 포트 포워딩 쿠베르네테스 서비스.
오늘날의 모든 플랫폼에서 사용하기 쉬운 방법host.docker.internal
먼저 Docker run 명령부터 시작하겠습니다.
docker run --add-host=host.docker.internal:host-gateway [....]
또는 Docker Compose를 사용할 때 서비스에 다음을 추가합니다.
extra_hosts:
- "host.docker.internal:host-gateway"
이러한 도커 합성 파일의 전체 예는 다음과 같습니다.
version: "3"
services:
your_service:
image: username/docker_image_name
restart: always
networks:
- your_bridge_network
volumes:
- /home/user/test.json:/app/test.json
ports:
- "8080:80"
extra_hosts:
- "host.docker.internal:host-gateway"
networks:
your_bridge_network:
다시 말하지만, 그것은 단지 예시일 뿐입니다.그러나 이 도커 이미지가 포트 80에서 서비스를 시작하는 경우 포트 8080의 호스트에서 사용할 수 있습니다.
사용 사례에서 더 중요한 것은 도커 컨테이너가 호스트 시스템에서 제공하는 서비스를 사용하려는 경우 이 특수 기능을 사용할 수 있다는 것입니다.host.docker.internal
해당 으로 ( Docker 됩니다. 해당 이름은 자동으로 내부 Docker IP 주소로 확인됩니다.docker0
인터페이스)를 선택합니다.
어쨌든, 예를 들어...또한 호스트 시스템에서 웹 서비스를 실행합니다(포트 80).이제 도커 컨테이너 내에서 해당 서비스에 액세스할 수 있습니다.사용해 보십시오.nc -vz host.docker.internal 80
.
사용하지 않고 모두 사용network_mode: "host"
.
언급URL : https://stackoverflow.com/questions/17770902/forward-host-port-to-docker-container
'it-source' 카테고리의 다른 글
전용 생성자가 있는 Java Springbean (0) | 2023.08.29 |
---|---|
단추를 클릭하여 표 행의 내용 가져오기 (0) | 2023.08.29 |
jQuery를 사용하여 형제 요소를 선택하려면 어떻게 해야 합니까? (0) | 2023.08.24 |
jQuery 위치 href (0) | 2023.08.24 |
EmptyError: 순서에 요소가 없습니다. (0) | 2023.08.24 |