正如标题所示,我需要能够检索docker托管的IP地址以及从主机到容器的portmap,并在容器内部完成这些工作。


当前回答

如果你启用了docker远程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解析返回的JSON为DESIRED_PORT。

其他回答

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

run --env <key>=<value>

更新:在Mac版Docker上,从18.03版本开始,你可以使用host. Docker .internal作为主机的IP。请看aljabear的回答。对于以前版本的Mac Docker,以下答案可能仍然有用:

在Docker for Mac上,docker0桥不存在,所以这里的其他答案可能不起作用。然而,所有流出的流量都是通过你的父主机路由的,所以只要你试图连接到一个它识别为自己的IP(而docker容器并不认为是自己),你应该能够连接。例如,如果你从父机器运行:

ipconfig getifaddr en0

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

sudo ifconfig lo0 alias 192.168.46.49

然后,您可以在docker容器内使用telnet测试连接。在我的例子中,我想连接到一个远程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容器认为流量的目的地是它自己,它就不会将流量发送到父主机。所以如果有问题,请检查容器内部的环回接口:

sudo ip addr show lo

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

AFAIK,在Docker for Linux(标准发行版)的情况下,主机的IP地址将始终是172.17.0.1(在Docker的主网络上,请参阅评论了解更多)。

最简单的方法是从主机上通过ifconfig(接口docker0)获取:

ifconfig

在docker内部,docker可以执行以下命令:ip -4 route show default | cut -d" " -f3

你可以用下面的命令行在docker中快速运行它:

# 1. Run an ubuntu docker
# 2. Updates dependencies (quietly)
# 3. Install ip package   (quietly)
# 4. Shows (nicely) the ip of the host
# 5. Removes the docker (thanks to `--rm` arg)
docker run -it --rm ubuntu:22.04 bash -c "apt-get update > /dev/null && apt-get install iproute2 -y > /dev/null && ip -4 route show default | cut -d' ' -f3"

Mac和Windows的TLDR

docker run -it --rm alpine nslookup host.docker.internal

... 打印主机的IP地址…

nslookup: can't resolve '(null)': Name does not resolve

Name:      host.docker.internal
Address 1: 192.168.65.2

细节

在Mac和Windows上,可以使用特殊的DNS名称host.docker.internal。

主机有一个不断变化的IP地址(如果没有网络访问,则没有)。从18.03开始,我们的建议是连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。这是为了开发目的,不能在Mac Docker Desktop以外的生产环境中工作。

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

-i,——ip-address主机名地址 -I,——all-ip-addresses主机的所有地址

例如:

$ hostname -i
172.17.0.2

要给变量赋值,可以使用以下一行代码:

IP=$(hostname -i)