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

问题描述 投票:273回答:17

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

docker ip
17个回答
267
投票
/sbin/ip route|awk '/default/ { print $3 }'

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


2
投票

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

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

2
投票

在linux中你可以运行

HOST_IP=`hostname -I | awk '{print $1}'`

在macOS中,您的主机不是Docker主机。 Docker将在VirtualBox中安装它的主机操作系统。

HOST_IP=`docker run busybox ping -c 1 docker.for.mac.localhost | awk 'FNR==2 {print $4}' | sed s'/.$//'`

0
投票

如果在Service Fabric群集上运行Windows容器,则可以通过环境变量Fabric_NodeIPOrFQDN获取主机的IP地址。 Service Fabric environment variables


0
投票

我就是这样做的。在这种情况下,它会在docker镜像中的/ etc / hosts中添加一个hosts条目,指向taurus-host到我的本地机器IP ::

TAURUS_HOST=`ipconfig getifaddr en0`
docker run -it --rm -e MY_ENVIRONMENT='local' --add-host "taurus-host:${TAURUS_HOST}" ...

然后,从Docker容器中,脚本可以使用主机名taurus-host来到我托管docker容器的本地机器。


0
投票

也许我创建的容器也很有用https://github.com/qoomon/docker-host

您可以简单地使用容器名称dns来访问主机系统,例如curl http://dockerhost:9200,所以不需要麻烦任何IP地址。


0
投票

我使用的解决方案基于“服务器”,它在收到http请求时返回Docker主机的外部地址。

在“服务器”上:

1)启动jwilder / nginx-proxy

# docker run -d -p <external server port>:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

2)启动ipify容器

# docker run -e VIRTUAL_HOST=<external server name/address> --detach --name ipify osixia/ipify-api:0.1.0

现在,当容器向服务器发送http请求时,例如

# curl http://<external server name/address>:<external server port>

ipify通过http标头“X-Forwarded-For”返回Docker主机的IP地址

示例(ipify服务器名称为“ipify.example.com”并在端口80上运行,docker host具有IP 10.20.30.40):

# docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
# docker run -e VIRTUAL_HOST=ipify.example.com --detach --name ipify osixia/ipify-api:0.1.0

在容器内,您现在可以调用:

# curl http://ipify.example.com
10.20.30.40

0
投票

在Ubuntu上,hostname命令可以使用以下选项:

  • -i--ip-address地址为主机名
  • -I--all-ip-addresses主人的所有地址

例如:

$ hostname -i
172.17.0.2

要分配给变量,可以使用以下单行:

IP=$(hostname -i)

-5
投票

随着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

119
投票

在Docker for Mac上,从版本18.03开始,您可以使用host.docker.internal作为主机的IP。

请注意,与documentation一样,“这是出于开发目的[s],并且不适用于Docker for Mac之外的生产环境。”这是因为,在Docker for Mac中,“您无法在主机上看到docker0接口。此接口实际上位于虚拟机内。”

这是docker.for.mac.localhost的更新,自17.06版本开始提供,docker.for.mac.host.internal,自17.12版本开始提供,可能仍然有效。

例如,我在主机上设置了环境变量:

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

78
投票

更新:在Docker for Mac上,从版本18.03开始,您可以使用host.docker.internal作为主机的IP。见allanberry's answer。对于以前版本的Docker for Mac,以下答案可能仍然有用:

在Docker for Mac上,docker0桥不存在,因此这里的其他答案可能不起作用。但是,所有传出流量都通过您的父主机进行路由,因此只要您尝试连接到它自己识别的IP(并且Docker容器不认为它本身),您就应该能够连接。例如,如果从父机器运行此命令:

ipconfig getifaddr en0

这应该会显示当前网络上Mac的IP,并且您的docker容器也应该能够连接到此地址。如果这个IP地址发生变化,这当然是一种痛苦,但你可以在你的Mac上添加一个自定义的环回IP,容器认为它本身不是通过在父机器上做这样的事情:

sudo ifconfig lo0 alias 192.168.46.49

然后,您可以使用telnet在docker容器中测试连接。在我的情况下,我想连接到远程xdebug服务器:

telnet 192.168.46.49 9000

现在,当流量进入你的Mac,地址为192.168.46.49(并且所有离开你的容器的流量都通过你的Mac)你的Mac将假设IP本身。使用完此IP后,可以删除环回别名,如下所示:

sudo ifconfig lo0 -alias 192.168.46.49

需要注意的一件事是,如果docker容器认为流量的目的地本身就不会向父主机发送流量。如果遇到问题,请检查容器内的loopback接口:

sudo ip addr show lo

在我的情况下,这显示inet 127.0.0.1/8这意味着我不能在127.*范围内使用任何IP。这就是我在上面的例子中使用192.168.*的原因。确保您使用的IP与您自己网络上的某些内容不冲突。


39
投票

对于在AWS中运行Docker的用户,主机的instance meta-data仍然可以从容器内部获得。

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

22
投票

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

run --env <key>=<value>

19
投票

--add-host可能是一个更清洁的解决方案(但没有端口部分,只有主机可以使用此解决方案处理)。所以,在你的docker run命令中,做一些像:

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

(来自https://stackoverflow.com/a/26864854/127400


6
投票

Docker for Mac我想从容器连接到主机上的服务

主机具有更改的IP地址(如果您没有网络访问权限,则为无)。从18.03开始,我们建议连接到特殊DNS名称host.docker.internal,该名称解析为主机使用的内部IP地址。

网关也可以作为gateway.docker.internal访问。 https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds


6
投票

如果你想在IP上使用真正的IP地址(不是桥梁Windows)并且你有docker 18.03(或更近期),请执行以下操作:

在主机上运行bash,映像名称为nginx(适用于Alpine Linux distribution):

 docker run -it nginx /bin/ash

然后在容器内运行

/ # nslookup host.docker.internal

Name:      host.docker.internal
Address 1: 192.168.65.2

192.168.65.2是主机的IP - 而不是spinus接受的答案中的桥接IP。

我在这里使用host.docker.internal

主机具有更改的IP地址(如果您没有网络访问权限,则为无)。从18.03开始,我们建议连接到特殊DNS名称host.docker.internal,该名称解析为主机使用的内部IP地址。这是出于开发目的,不适用于Docker for Windows之外的生产环境。


5
投票

如果您启用了docker remote API(例如通过-Htcp://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。

第三行卷曲到主机(假设你使用4243作为docker的端口),然后使用node解析DESIRED_PORT返回的JSON。

© www.soinside.com 2019 - 2024. All rights reserved.