도커 컨테이너에서 호스트 포트에 액세스하는 방법
jenkins를 실행하는 도커 컨테이너가 있습니다. 빌드 프로세스의 일부로 호스트 시스템에서 로컬로 실행되는 웹 서버에 액세스해야합니다. 호스트 웹 서버 (포트에서 실행되도록 구성 할 수있는)가 jenkins 컨테이너에 노출 될 수있는 방법이 있습니까?
편집 : Linux 시스템에서 기본적으로 docker를 실행하고 있습니다.
최신 정보:
아래 @larsks 응답 외에도 호스트 컴퓨터에서 호스트 IP의 IP 주소를 얻으려면 다음을 수행하십시오.
ip addr show docker0 | grep -Po 'inet \K[\d.]+'
Linux에서 Docker를 기본적으로 실행하는 경우 docker0
인터페이스 의 IP 주소를 사용하여 호스트 서비스에 액세스 할 수 있습니다 . 컨테이너 내부에서 기본 경로가됩니다.
예를 들어, 내 시스템에서 :
$ 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
Docker 컨테이너의 연결을 허용하기 위해 호스트 의 규칙 을 수정해야 할 수도 있습니다 . 이와 같은 것이 트릭을 수행합니다.
# iptables -A INPUT -i docker0 -j ACCEPT
이렇게하면 Docker 컨테이너에서 호스트의 모든 포트에 액세스 할 수 있습니다. 참고 :
iptables 규칙이 순서화되어 있으며이 규칙은 다른 규칙이 무엇인지에 따라 올바른 작업을 수행하거나 수행하지 않을 수 있습니다.
(a) 청취 중
INADDR_ANY
(일명 0.0.0.0)이거나docker0
인터페이스 에서 명시 적으로 청취중인 호스트 서비스에만 액세스 할 수 있습니다.
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
위해 컨테이너 내부 와 같은 것을 실행할 수 있습니다 .
별칭은 재부팅 할 때마다 재설정되므로 필요한 경우 시작 스크립트를 작성하십시오.
Solution and more documentation here: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
Use --net="host"
in your docker run
command, then localhost
in your docker container will point to your docker host.
Solution with docker-compose: For accessing to host-based service you can use network_mode
parameter https://docs.docker.com/compose/compose-file/#network_mode
version: '3'
services:
jenkins:
network_mode: host
Currently the easiest way to do this on Mac and Windows is using host host.docker.internal
, that resolves to host machine's IP address. Unfortunately it does not work on linux yet (as of April 2018).
I created a docker container for doing exactly that https://github.com/qoomon/docker-host
You can then simply use container name dns to access host system e.g. curl http://dockerhost:9200
We found that a simpler solution to all this networking junk is to just use the domain socket for the service. If you're trying to connect to the host anyway, just mount the socket as a volume, and you're on your way. For postgresql, this was as simple as:
docker run -v /var/run/postgresql:/var/run/postgresql
Then we just set up our database connection to use the socket instead of network. Literally that easy.
You can access the local webserver which is running in your host machine in two ways.
Approach 1 with public IP
Use host machine public IP address to access webserver in Jenkins docker container.
Approach 2 with the host network
Use "--net host" to add the Jenkins docker container on the host's network stack. Containers which are deployed on host's stack have entire access to the host interface. You can access local webserver in docker container with a private IP address of the host machine.
NETWORK ID NAME DRIVER SCOPE
b3554ea51ca3 bridge bridge local
2f0d6d6fdd88 host host local
b9c2a4bc23b2 none null local
Start a container with the host network Eg: docker run --net host -it ubuntu
and run ifconfig
to list all available network IP addresses which are reachable from docker container.
Eg: I started a nginx server in my local host machine and I am able to access the nginx website URLs from Ubuntu docker container.
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
Accessing the Nginx web server (running in local host machine) from Ubuntu docker container with private network IP address.
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
I've explored the various solution and I find this the least hacky solution:
- Define a static IP address for the bridge gateway IP.
- Add the gateway IP as an extra entry in the
extra_hosts
directive.
The only downside is if you have multiple networks or projects doing this, you have to ensure that their IP address range do not conflict.
Here is a Docker Compose example:
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
You can then access ports on the host from inside the container using the hostname "dockerhost".
When you have two docker images "already" created and you want to put two containers to communicate with one-another.
For that, you can conveniently run each container with its own --name and use the --link flag to enable communication between them. You do not get this during docker build though.
When you are in a scenario like myself, and it is your
docker build -t "centos7/someApp" someApp/
That breaks when you try to
curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz
and you get stuck on "curl/wget" returning no "route to host".
The reason is security that is set in place by docker that by default is banning communication from a container towards the host or other containers running on your host. This was quite surprising to me, I must say, you would expect the echosystem of docker machines running on a local machine just flawlessly can access each other without too much hurdle.
The explanation for this is described in detail in the following documentation.
http://www.dedoimedo.com/computers/docker-networking.html
Two quick workarounds are given that help you get moving by lowering down the network security.
The simplest alternative is just to turn the firewall off - or allow all. This means running the necessary command, which could be systemctl stop firewalld, iptables -F or equivalent.
Hope this information helps you.
참고URL : https://stackoverflow.com/questions/31324981/how-to-access-host-port-from-docker-container
'Programing' 카테고리의 다른 글
파이프와 함께 서브 프로세스 명령을 사용하는 방법 (0) | 2020.05.06 |
---|---|
jQuery를 사용하여 테이블 셀 값을 얻는 방법은 무엇입니까? (0) | 2020.05.06 |
동적 프로그래밍을 사용하여 가장 긴 하위 시퀀스를 결정하는 방법은 무엇입니까? (0) | 2020.05.06 |
sh에서 'find'의 '-prune'옵션을 사용하는 방법은 무엇입니까? (0) | 2020.05.06 |
String, StringBuffer 및 StringBuilder (0) | 2020.05.06 |