제목대로 도 커가 호스트하는 IP 주소와 호스트에서 컨테이너로 포트 맵을 검색하고 컨테이너 내부에서 IP 주소를 검색 할 수 있어야합니다.
답변
/sbin/ip route|awk '/default/ { print $3 }'
@MichaelNeale에서 알 수 있듯이이 Dockerfile
IP는 빌드 시간 동안 하드 코딩되므로 빌드 시간 동안이 IP가 필요한 경우를 제외하고는 이 방법을 사용하는 것이 의미가 없습니다 .
답변
버전 18.03부터는 host.docker.internal
호스트 IP로 사용할 수 있습니다 .
의 작품 Mac 용 부두 노동자 , Windows 용 부두 노동자 , 그리고 아마도 다른 플랫폼뿐만 아니라.
이 업데이트는 docker.for.mac.localhost
17.06 이후 버전 및 docker.for.mac.host.internal
17.12 이후 버전 의 Mac 전용 업데이트 이며 해당 플랫폼에서도 작동합니다.
Mac 및 Windows 설명서에서 와 같이 개발 목적으로 만 사용됩니다.
예를 들어 호스트에 환경 변수가 설정되어 있습니다.
MONGO_SERVER=host.docker.internal
내 docker-compose.yml
파일에는 다음이 있습니다.
version: '3'
services:
api:
build: ./api
volumes:
- ./api:/usr/src/app:ro
ports:
- "8000"
environment:
- MONGO_SERVER
command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi
답변
업데이트 : Mac 용 Docker에서 버전 18.03부터 host.docker.internal 을 호스트의 IP로 사용할 수 있습니다 . allanberry의 답변을 참조하십시오 . Mac 용 Docker의 이전 버전에서는 다음과 같은 대답이 여전히 유용 할 수 있습니다.
Mac 용 Docker에는 docker0
브리지가 없으므로 다른 답변이 작동하지 않을 수 있습니다. 그러나 모든 나가는 트래픽은 부모 호스트를 통해 라우팅되므로 IP에 연결하려고 시도하는 한 자체적으로 인식되고 Docker 컨테이너는 자신을 생각하지 않습니다. 연결할 수 있어야합니다. 예를 들어 상위 머신에서 이것을 실행하는 경우 :
ipconfig getifaddr en0
현재 네트워크에있는 Mac의 IP가 표시되고 도커 컨테이너도이 주소에 연결할 수 있어야합니다. 이 IP 주소가 변경되면 당연히 고통 스럽지만 부모 컴퓨터에서 다음과 같은 작업을 수행하여 컨테이너 자체가 아니라고 생각하는 사용자 정의 루프백 IP를 Mac에 추가 할 수 있습니다.
sudo ifconfig lo0 alias 192.168.46.49
그런 다음 텔넷을 사용하여 도커 컨테이너 내에서 연결을 테스트 할 수 있습니다. 제 경우에는 원격 xdebug 서버에 연결하고 싶었습니다.
telnet 192.168.46.49 9000
이제 트래픽이 192.168.46.49로 지정된 Mac으로 들어오고 컨테이너를 떠나는 모든 트래픽이 Mac을 통과하면 Mac은 IP 자체라고 가정합니다. 이 IP 사용을 마치면 다음과 같이 루프백 별명을 제거 할 수 있습니다.
sudo ifconfig lo0 -alias 192.168.46.49
주의해야 할 점은 도커 컨테이너가 트래픽의 대상이 자신이라고 생각하면 부모 호스트에 트래픽을 보내지 않는다는 것입니다. 따라서 문제가 발생하면 컨테이너 내부의 루프백 인터페이스를 확인하십시오.
sudo ip addr show lo
필자의 경우 inet 127.0.0.1/8
이는 127.*
범위 내의 IP를 사용할 수 없음을 나타 냅니다. 그래서 192.168.*
위의 예에서 사용 했습니다. 사용하는 IP가 자신의 네트워크에있는 것과 충돌하지 않는지 확인하십시오.
답변
AWS에서 Docker를 실행하는 경우 컨테이너의 내부에서 호스트 의 인스턴스 메타 데이터 를 계속 사용할 수 있습니다.
curl http://169.254.169.254/latest/meta-data/local-ipv4
예를 들면 다음과 같습니다.
$ docker run alpine /bin/sh -c "apk update ; apk add curl ; curl -s http://169.254.169.254/latest/meta-data/local-ipv4 ; echo"
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
v3.3.1-119-gb247c0a [http://dl-cdn.alpinelinux.org/alpine/v3.3/main]
v3.3.1-59-g48b0368 [http://dl-cdn.alpinelinux.org/alpine/v3.3/community]
OK: 5855 distinct packages available
(1/4) Installing openssl (1.0.2g-r0)
(2/4) Installing ca-certificates (20160104-r2)
(3/4) Installing libssh2 (1.6.0-r1)
(4/4) Installing curl (7.47.0-r0)
Executing busybox-1.24.1-r7.trigger
Executing ca-certificates-20160104-r2.trigger
OK: 7 MiB in 15 packages
172.31.27.238
$ ifconfig eth0 | grep -oP 'inet addr:\K\S+'
172.31.27.238
답변
유일한 방법은 컨테이너를 만들 때 호스트 정보를 환경으로 전달하는 것입니다
run --env <key>=<value>
답변
은 --add-host
더 청소기 솔루션이 될 수있다 (그러나 포트 부분없이 목적으로 만 호스트는이 솔루션을 처리 할 수 있습니다). 따라서 귀하의 docker run
명령으로 다음과 같이하십시오.
docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [my container]
답변
자동으로 수행하고자하는 대부분의 응용 프로그램에 대한 표준 것이 가장 좋습니다 : 그렇지 . 대신 컨테이너를 실행하는 사람이 외부 호스트 이름 / IP 주소를 구성 (예 : 환경 변수 또는 구성 파일)으로 주입합니다. 사용자가 이것을 주입하도록 허용하면 가장 휴대하기 쉬운 디자인이됩니다.
왜 이렇게 어려운가요? 컨테이너는 설계 상 호스트 환경과 응용 프로그램을 분리하기 때문입니다. 네트워크는 기본적으로 해당 컨테이너에 네임 스페이스로 지정되며 호스트의 세부 정보는 컨테이너 내부에서 실행되는 프로세스로부터 완전히 신뢰되지 않을 수 있습니다.
특정 상황에 따라 다른 옵션이 있습니다.
컨테이너가 호스트 네트워킹으로 실행중인 경우 호스트의 라우팅 테이블을 직접보고 기본 경로를 확인할 수 있습니다. 에서 이 질문에 나를 예는 다음 작품 :
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
컨테이너의 호스트 네트워킹에서이를 보여주는 예는 다음과 같습니다.
docker run --rm --net host busybox /bin/sh -c \
"ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'"
Docker Desktop의 일부 버전에서는 내장 VM에 DNS 항목을 삽입했습니다.
getent hosts host.docker.internal | awk '{print $1}'
클라우드 환경에서 실행중인 경우 클라우드 공급자 (예 : AWS)에서 메타 데이터 서비스를 확인할 수 있습니다.
curl http://169.254.169.254/latest/meta-data/local-ipv4
외부 / 인터넷 주소를 원하는 경우 다음과 같은 원격 서비스를 쿼리 할 수 있습니다.
curl ifconfig.co
이들 각각에는 한계가 있으며 특정 시나리오에서만 작동합니다. 가장 이식성이 좋은 옵션은 IP 주소를 구성으로 주입하여 컨테이너를 실행하는 것입니다. 예를 들어 ip
호스트 에서 이전 명령을 실행하고 환경 변수로 주입 하는 옵션 이 있습니다.
export HOST_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
docker run --rm -e HOST_IP busybox printenv HOST_IP
