Docker隐藏调用容器的IP

免责声明:

我是一个networking新手。 原谅我,如果我不使用适当的词汇来形容我的问题。

语境:

所以我有几个在CoreOS上运行的应用程序容器(Docker)。 每个容器必须具有不同的IAMangular色。 由于在同一个主机上可能会有N个不同的IAMangular色运行,因此使用EC2实例元数据( http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2- instance-metadata.html )来检索实例凭证。 每个容器都需要一组不同的凭证(因为每个容器都有不同的angular色)。

为了解决这个问题,我偶然发现这个项目https://github.com/dump247/docker-ec2-metadata这是一个Go代理拦截(使用iptables规则)调用http://169.254.169.254/latest / meta-data / iam / security-credentials /,并根据调用容器的IAMangular色提供适当的凭据。

iptables规则(请参阅https://github.com/dump247/docker-ec2-metadata/blob/master/README.md )重新路由呼叫是:

# Get the host IP address. You can use a different mechanism if you wish. # Note that IP can not be 127.0.0.1 because DNAT for loopback is not possible. PROXY_IP=$(ifconfig eth0 | grep -Eo "inet addr:[0-9.]+" | grep -Eo "[0-9.]+") # Port that the proxy service runs on. Default is 18000. PROXY_PORT=18000 # Drop any traffic to the proxy service that is NOT coming from docker containers iptables \ -I INPUT \ -p tcp \ --dport ${PROXY_PORT} \ ! -i docker0 \ -j DROP # Redirect any requests from docker containers to the proxy service iptables \ -t nat \ -I PREROUTING \ -p tcp \ -d 169.254.169.254 --dport 80 \ -j DNAT \ --to-destination ${PROXY_IP}:${PROXY_PORT} \ -i docker0 

由于我们在CoreOS上运行,我们想要在Docker容器中部署这个代理。 我们不希望直接在EC2主机上安装代理。

假设我有2个容器运行2个具有不同IAMangular色的应用程序:

  • containerA:IP:172.17.0.7,IAMangular色:roleA
  • containerB:IP:172.17.0.8,IAMangular色:roleB

当代理拦截到http://169.254.169.254/latest/meta-data/iam/security-credentials/的请求时,代理需要知道请求容器的IP(例如172.17.0.8),以便使用Docker客户端( https://github.com/fsouza/go-dockerclient )检索请求容器的IAMangular色(使用环境variables传递给容器,例如: docker run -e IAM_ROLE=arn:aws:iam::123456789012:role/roleA --name containerA myapp

问题:

当代理在EC2主机上原生运行时,检索请求容器的IP(在我们的例子中,172.17.0。[7,8])工作得很好。 这是我的心智模型,当代理在主机上本地运行时会发生什么情况:

containerA调用http://169.254.169.254- > iptables路由发生 – >调用被redirect到localhost:18000 – >代理容器将containerA的IP视为传入请求的源

但是,当代理在Docker容器中运行时,它不能很好地工作。 请注意,我使用docker run -p 18000:18000 -v /var/run/docker.sock:/var/run/docker.sock ec2-metadata-proxy启动代理docker run -p 18000:18000 -v /var/run/docker.sock:/var/run/docker.sock ec2-metadata-proxy

当代理在Docker容器中运行时,请求容器的IP是docker0接口的IP(例如172.17.42.1),从而无法确定请求容器。 再次,这里是我的智能模型,当代理在一个容器中运行时会发生什么:

containerA调用http://169.254.169.254- > iptables路由发生 – >调用被redirect到localhost:18000 – >调用代理容器的Docker路由 – >代理容器将docker0的IP看作传入请求的源

题:

如何确保代理将看到的IP地址是请求容器(例如containerA)的IP地址,而不是docker0接口的IP地址?

经过一番尝试,我发现在--net=host模式下运行代理容器解决了这个问题。

通过使用此选项,代理容器与主机共享相同的networking堆栈,从而绕过docker0网桥。