我可以在Docker容器内获取IP地址吗?

66

如何在容器内获取容器的IP地址?

'docker inspect $hostname ...' 不适用,因为我没有共享 /var/run/docker.sock 主机文件到容器中。


用于什么样的使用场景?如果是用于服务器,通常只需查看本地IP以获取传入请求。 - loganfsmyth
我将把IP发送到另一个容器(例如,nginx),并从nginx创建上游(重定向子域http请求)到第一个容器。 - Kroid
我认为通常你会使用链接来实现这个功能?比如当你启动nginx容器时,你可以指定--link firstcontainer:firstcontainer,然后在nginx中,你可以直接代理到主机名firstcontainer,因为链接将自动设置DNS以将其解析为firstcontainer IP。 - loganfsmyth
我无法链接,因为我首先运行了nginx容器。这似乎很奇怪,但在我的情况下这是正确的操作。 - Kroid
好的,只是想确认一下是否有原因。 - loganfsmyth
11个回答

126

我可以通过以下方式找到IP地址:

hostname -i

当然,如果有多个接口,则可能不完全准确。

编辑

注意:根据hostname man页面,hostname -i使用DNS解析IP地址,而hostname -I显示除环回之外的所有地址,不依赖于DNS,并且推荐使用。

在我所有的Docker容器中,-i-I返回相同的结果(但在我的桌面上不是这种情况)。


1
太棒了,我没想到这么简单 :) - Sebastian Łaskawiec
7
应该将此选为答案。 - sithumc
5
更加准确地说,hostname -i | awk '{print $1}' 的原因是因为存在一个尾随空格(可能会有多个IP地址)。 - Romuald Brunet
2
@RomualdBrunet 应该是 hostname -I | awk '{print $1}',因为 -i 只会给出单个 IP,而 -I 则会给出多个(如果有的话)。 - Deepak Deore
1
当我将一个 Docker 容器连接到两个网络时,hostname -ihostname -I 都返回 172.18.0.2 172.19.0.2(但 hostname -I 返回一个尾随空格)。我认为 hostname -i 的行为取决于 DNS 的配置方式。 - Victor Roetman

59

由于IP地址在 /etc/hosts 的第一行中,您可以在容器中执行 awk 命令来打印 /etc/hosts 的第一行的第一个单词。

$ awk 'END{print $1}' /etc/hosts
172.17.0.14

3
这似乎不再是真的了。在Docker引擎1.10.3上的一个容器中,/etc/hosts文件将我的IP地址作为最后一行,并将环回地址作为第一行。 - Victor Roetman
3
现在使用命令awk 'END{print $1}' /etc/hosts似乎能完成任务。 - user2915097
12
不一定是真的,并且非常不安全。 - D.Shawley
awk 太过复杂了,也许一个简单的 sed 命令就能满足需求(我猜是去除空格?)sed -i 's/[ \t]*$//' "$1" - Sandburg

5

为什么不使用更简单的方法,例如:

grep "`hostname`" /etc/hosts|awk '{print $1}'

或者

grep "$HOSTNAME" /etc/hosts|awk '{print $1}'

如果您的主机名恰好是其他主机名的子字符串,则会返回多个IP地址。 - user100464

3

通常情况下,您可以使用Linux程序ifconfig获取IP地址和其他网络详细信息。但是您的容器可能没有此程序,因此您需要通过apt-getyum或您所使用的发布版软件包管理器进行安装。获取IP地址的基本管道如下:

ifconfig eth0 | grep "inet addr:" | cut -d : -f 2 | cut -d " " -f 1

一个容器不一定会有eth0接口。 - user100464
2
一个容器也不一定安装了 ifconfig - kiltek

1

我找到了解决我的问题的方法:

/sbin/ip route|awk '/scope/ { print $9 }'

它会打印类似于:“172.17.0.135”的内容。

1

如果容器支持"hostname"命令,这可能在某些容器上起作用。

docker ps 获取(容器ID)

docker exec -it (容器ID)hostname -i


1
猜得不错,但还是错了。问题明确说明他们不能在容器内部运行docker命令。 - user100464

1
你还可以在/etc/hosts中查找以容器ID结尾的行并打印第一个字段:
sed -n 's/^\([0-9\.]*\)[[:blank:]]*[0-9a-f]\{12,\}$/\1/p' /etc/hosts

我会使用awk,但是在Debian:jessie中的标准awk不支持像{12,}这样的正则表达式量词。


1
如果你更喜欢使用ip而不是ifconfig,在Linux上可以这样做:
ip addr | grep inet | tr -s ' ' | cut -d ' ' -f 3

这只是获取所有IP地址和接口,仅搜索以“inet”开头的内容,并仅返回第三列。作为一个很好的副作用,这也包括子网掩码!(例如,“172.17.0.2/16”)如果您不想要子网掩码,可以使用:
ip addr | grep inet | tr -s ' ' | cut -d ' ' -f 3 | tr -d '/'

注意: 这显示容器中的所有IP地址。你可以使用awksed来删除127.0.0.1/16和其他不需要的IP地址。 :)


1
FROM alpine

# Upgrade grep so that it supports -Po flags
RUN apk add --no-cache --upgrade grep

ENV IPADDRESS "ip a show eth0 | grep -Po 'inet \K[\d.]+'"

0
Linux的ip命令非常有用。
ip a s eth0 | grep -E -o 'inet [0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' | cut -d' ' -f2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接