如何从Docker容器中获取Docker主机的IP地址

正如标题所说。 我需要能够检索到docker主机的IP地址和从主机到容器的portmaps,并在容器内部执行此操作。

/sbin/ip route|awk '/default/ { print $3 }' 

正如@MichaelNeale所注意到的那样,在Dockerfile使用这个方法是没有意义的(除非在构build期间我们需要这个IP),因为这个IP将在Dockerfile期间被硬编码。

Docker for Mac上docker0桥不存在,所以上面的答案将不起作用。 但是,所有传出stream量都是通过您的父母主机进行路由的,所以只要您尝试连接到一个识别为自身的IP(并且Docker容器不认为是自己),您应该能够连接。 例如,如果你从父机运行这个运行:

 ipconfig getifaddr en0 

这应该显示您的Mac在其当前networking上的IP,并且您的Docker容器也应该能够连接到此地址。 如果这个IP地址有变化,这当然是一个痛苦的问题,但是你可以添加一个自定义的回送IP到你的Mac上,而容器在父机器上不会这样做。

 sudo ifconfig lo0 alias 192.168.46.49 

然后您可以使用telnettestingdocker容器内的连接。 在我的情况下,我想连接到远程xdebug服务器:

 telnet 192.168.46.49 9000 

现在,当stream量进入你的Mac地址为192.168.46.49(并且所有stream量离开你的容器确实通过你的Mac),你的Mac会认为IP本身。 当你完成使用这个IP,你可以像这样删除回送别名:

 sudo ifconfig lo0 -alias 192.168.46.49 

需要注意的一件事是,如果Docker容器认为stream量的目的地本身,则不会将stream量发送到父级主机。 因此,如果您遇到问题,请检查容器内部的回送接口:

 sudo ip addr show lo 

在我的情况下,这表明inet 127.0.0.1/8这意味着我不能在127.*范围内使用任何IP。 这就是为什么我在上面的例子中使用了192.168.* 。 确保您使用的IP与您自己的networking上的某些东西没有冲突。

Docker for Mac上 ,从版本17.06(最新,截至撰写本文)开始,您可以使用docker.for.mac.localhost作为主机的IP。

文件

例如,我有我的主机上设置的环境variables:

 MONGO_SERVER=docker.for.mac.localhost 

在我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 

对于那些在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 

--add-host可能是一个更清洁的解决scheme(但没有端口部分,只有主机可以用这个解决scheme来处理)。 所以,在你的docker run命令,做一些事情:

 docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [my container] 

(从https://stackoverflow.com/a/26864854/127400

唯一的方法是在创build容器时将主机信息作为环境传递

 run --env <key>=<value> 

如果启用了tcp://0.0.0.0:4243 remote API (例如通过-H tcp://0.0.0.0:4243 )并知道主机的主机名或IP地址,可以用很多bash来完成。

在我的容器的用户的bashrc

 export hostIP=$(ip r | awk '/default/{print $3}') export containerID=$(awk -F/ '/docker/{print $NF;exit;}' /proc/self/cgroup) export proxyPort=$( curl -s http://$hostIP:4243/containers/$containerID/json | node -pe 'JSON.parse(require("fs").readFileSync("/dev/stdin").toString()).NetworkSettings.Ports["DESIRED_PORT/tcp"][0].HostPort' ) 

第二行从本地/proc/self/cgroup文件中获取容器ID。

第三行curl到主机(假设你使用4243作为docker的端口),然后使用节点parsing返回的JSON为DESIRED_PORT

使用https://docs.docker.com/machine/install-machine/

a)$ docker-machine ip

b)获取一台或多台机器的IP地址。

  $ docker-machine ip host_name $ docker-machine ip host_name1 host_name2 

这是在AWS中运行Docker的另一种select。 该选项避免使用apk添加curl包并节省宝贵的7mb空间。 使用内build的wget(单片BusyBox二进制文件的一部分):

 wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4