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


当前回答

这是一个在Node.js中使用前面提到的EC2元数据实例在AWS EC2实例上运行主机的最简单实现

const cp = require('child_process');
const ec2 = function (callback) {
    const URL = 'http://169.254.169.254/latest/meta-data/local-ipv4';
    // we make it silent and timeout to 1 sec
    const args = [URL, '-s', '--max-time', '1'];
    const opts = {};
    cp.execFile('curl', args, opts, (error, stdout) => {
        if (error) return callback(new Error('ec2 ip error'));
        else return callback(null, stdout);
    })
        .on('error', (error) => callback(new Error('ec2 ip error')));
}//ec2

并用作

ec2(function(err, ip) {
        if(err) console.log(err)
        else console.log(ip);
    })

其他回答

——add-host可能是一个更简洁的解决方案(但没有端口部分,只能使用该解决方案处理主机)。所以,在你的docker运行命令中,做如下的事情:

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

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

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以外的生产环境中工作。

另一种方法是基于traceroute,它在Linux主机上为我工作,例如在一个基于Alpine的容器中:

traceroute -n 8.8.8.8 -m 4 -w 1 | awk '$1~/\d/&&$2!~/^172\./{print$2}' | head -1

它花了一点时间,但列出了第一跳的IP,该IP不是以172开头的。如果没有成功响应,则尝试使用-m 4参数增加测试跳数的限制。

如果你启用了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。

在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'/.$//'`