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


1407

创建新容器后,是否可以运行命令以从主机获取容器的IP地址?

基本上,一旦Docker创建了容器,我就想推出自己的代码部署和容器配置脚本。


28
我只是想确保其他菜鸟不会犯错,并尝试从映像而不是容器中获取IP。确保获得CID或容器ID并进行查询;通过'docker ps'的CID。
Paul Gregoire

反之亦然?主机IP或来自容器的呼叫?
Somnath Muluk,

Answers:


2323

--format的选项inspect就派上用场了。

现代Docker客户端语法为:

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id

旧的Docker客户端语法为:

docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name_or_id

这些命令将返回Docker容器的IP地址。

如注释中所述:如果在Windows上,请在花括号周围使用双引号"而不是单引号'


34
这是一个更好的解决方案。如果可能,仅询问您的需求!
MikeyB 2014年

8
<no value>使用Fig / Boot2Docker在Mac上获得响应
cevaris 2014年

2
@cevaris <no value>如果尝试对未运行的容器运行此命令,则会得到提示。在执行此操作之前,请确保您的容器正在运行。
TheJediCowboy

55
!警告!这不再起作用了。新格式特定于容器,并遵循表格{{ .NetworkSettings.Networks.$network.IPAddress }}。默认似乎是桥接,但是在docker-compose下,这将是一个特定的名称,这取决于您的应用程序的名称(我认为是从--project-name标志开始的,尽管这也将取决于哪种类型的网络配置您已设置)。我在此处的答案中写了完整的答案stackoverflow.com/questions/17157721/…–
Dunk

5
也许我是一只困羊,但有关双引号的警告并不足够大胆而含糊其词,不足以引起我的注意。也许提供两个标记为Linux和Windows的示例。我从字面上看只是键入示例,检查了也使用单引号的文档然后用Google搜索了错误。我确定我并不孤单。
Wyck

513

您可以使用docker inspect <container id>

例如:

CID=$(docker run -d -p 4321 base nc -lk 4321);
docker inspect $CID

67
为了提取IP,您可以执行以下操作docker inspect $CID | grep IPAddress | cut -d '"' -f 4,它可以正常工作:)
creack 2013年

9
综上所述,此shell别名应列出所有容器ID及其ip:alias dockerip='docker ps | tail -n +2 | while read cid b; do echo -n "$cid\t"; docker inspect $cid | grep IPAddress | cut -d \" -f 4; done'
ko-dos

64
如@ user3119830所提到的,有一个新的检查选项。现在,您可以通过docker inspect -format '{{ .NetworkSettings.IPAddress }}' ${CID}
creack

16
请注意。不建议使用单破折号,因此-format将变为--format。
jamtur01 2014年

7
docker inspect -format '{{ .NetworkSettings.IPAddress }}' ${CID}是新语法。-format不推荐使用,则变为--format
Devy

408

首先获取容器ID:

docker ps

(第一列是容器ID)

使用容器ID运行:

docker inspect <container ID>

在底部的“网络设置”下,您可以找到“ IP地址”

或只是做:

docker inspect <container id> | grep "IPAddress"

5
太糟糕了,在我的一个实例(以开头docker run -it MYCONTAINER /bin/bash)上,的输出inspect没有section NetworkSettings
艾瑞克(Eric)

3
这在Windows 10上不起作用。您还需要使用ipconfig找出DockerNAT的IP地址。
ntiedt

@Eric您也可以为此检查网桥:docker network inspect bridge | grep Gateway | grep -o -E '[0-9.]+'
TomaszKapłoński'18

5
我非常喜欢该... | grep IP解决方案,而不是获取IP所需的所有格式细节。+1
d8aninja

1
@Eric-您已将容器image混淆了。该命令实际上是docker run -it MYIMAGE(不是容器名称);如果这样做,docker inspect MYIMAGE您将获得有关图像的静态信息。您需要找到正在运行的容器的名称(或使用其他容器的ID)。在我的系统上,从该映像创建的第一个此类容器默认为name MYIMAGE_1,因此docker inspect MYIMAGE_1NetworkSettings 也是如此。
制造商史蒂夫·

214
docker inspect CONTAINER_ID | grep "IPAddress"

您可以添加-i到grep来忽略大小写,那么即使是以下情况也可以使用:

docker inspect CONTAINER_ID | grep -i "IPaDDreSS"

5
这个答案与其他22个相比如何更好/有所不同?
sds

这绝对不是最佳答案。WouterD的答案就是您要寻找的答案。
M.Vanderlee

7
@ M.Vanderlee此答案的命令更容易记住,这使其成为IMO的更好答案。
huysentruitw

1
@WouterHuysentruit当然可以,但是您会获得多个条目和实际的“ IPAddress”文本。未经进一步操作,您将无法在脚本中使用它。
M.Vanderlee '18

你是对的。在问题的背景下,另一个答案更合适。
huysentruitw

133

仅通过一个命令即可获取所有容器名称及其IP地址。

docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq)

如果您使用docker-compose的命令将是这样的:

docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

输出将是:

/containerA - 172.17.0.4
/containerB - 172.17.0.3
/containerC - 172.17.0.2

5
我真的很喜欢这个,但是它不适用于Docker Compose,这与拥有自己的网络有关。改为{{.NetworkSettings.IPAddress }}改为{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}
clockworkgeek

这是我使用的变体:docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -aq | xargs) | sed -e '/^$/d'。该sed(1)删除空线的容器存在,但不具有IP地址。
NYCeyes

97

将此shell脚本添加到您的~/.bashrc文件或相关文件中:

docker-ip() {
  docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$@"
}

然后,要获取容器的IP地址,只需执行以下操作:

docker-ip YOUR_CONTAINER_ID

对于新版本的Docker,请使用以下命令:

docker-ip() {
        docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$@"
}

5
Template parsing error: template: :1:19: executing "" at <.NetworkSettings.IPA...>: map has no entry for key "NetworkSettings"
saiyancoder

这对我有用,但是需要source ~/.bash_profile
penny chan

1
如果您不检查正在运行的容器,而只是检查一个映像,则会收到此错误...映像没有IPAddress ...可怕的错误消息,是的
dagelf

37

显示所有容器的IP地址:

docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)

37

在Docker 1.3+中,您还可以使用以下命令进行检查:

输入正在运行的Docker(Linux):

docker exec [container-id or container-name] cat /etc/hosts
172.17.0.26 d8bc98fa4088
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.17 mysql

对于Windows:

docker exec [container-id or container-name] ipconfig

1
或者只是docker exec [container-name-or-id] ip a
Stephan Richter

对于Windowsdocker exec [container-id or container-name] ipconfig
GreatAndPowerfulOz

27

从Docker版本1.10.3开始,构建20f81dd

除非您另行告知Docker,否则Docker始终会在网桥网络中启动容器。因此,您可以在下面尝试以下命令:

docker network inspect bridge

然后应该返回一个“容器”部分,其中将显示该正在运行的容器的IP地址。

[
    {
        "Name": "bridge",
        "Id": "40561e7d29a08b2eb81fe7b02736f44da6c0daae54ca3486f75bfa81c83507a0",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16"
                }
            ]
        },
        "Containers": {
            "025d191991083e21761eb5a56729f61d7c5612a520269e548d0136e084ecd32a": {
                "Name": "drunk_leavitt",
                "EndpointID": "9f6f630a1743bd9184f30b37795590f13d87299fe39c8969294c8a353a8c97b3",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        }
    }
]

如果您的容器部分为空,这意味着什么?但是容器已经启动并运行了。
StackEdd

24

执行:

docker ps -a

这将显示活动的docker映像:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                       PORTS               NAMES
3b733ae18c1c        parzee/database     "/usr/lib/postgresql/"   6 minutes ago       Up 6 minutes                 5432/tcp            serene_babbage

使用容器ID值:

docker inspect <CONTAINER ID> | grep -w "IPAddress" | awk '{ print $2 }' | head -n 1 | cut -d "," -f1

“ 172.17.0.2”


23

根据我喜欢的一些答案,我决定将它们合并为一个函数,以获取所有IP地址,并为特定容器获取另一个IP地址。它们现在在我的.bashrc文件中。

docker-ips() {
    docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq)
}

docker-ip() {
  docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$@"
}

第一个命令提供所有容器的IP地址,第二个命令提供特定容器的IP地址。

docker-ips
docker-ip YOUR_CONTAINER_ID

16

参考容器的名称:

docker run ... --name pg-master

然后按名称获取IP地址:

MASTER_HOST=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' pg-master)

15

我编写了以下Bash脚本,以获取在下运行的所有容器的IP地址表docker-compose

function docker_container_names() {
    docker ps -a --format "{{.Names}}" | xargs
}

# Get the IP address of a particular container
dip() {
    local network
    network='YOUR-NETWORK-HERE'
    docker inspect --format "{{ .NetworkSettings.Networks.$network.IPAddress }}" "$@"
}

dipall() {
    for container_name in $(docker_container_names);
    do
        local container_ip=$(dip $container_name)
        if [[ -n "$container_ip" ]]; then
            echo $(dip $container_name) " $container_name"
        fi
    done | sort -t . -k 3,3n -k 4,4n
}

您应该将变量网络更改为您自己的网络名称。


1
Tuong Le从这里的答案stackoverflow.com/questions/17157721/…避免了必须在dip()中指定网络:docker inspect --format'{{range .NetworkSettings.Networks}} {{。IPAddress}} {{end} }'“ $ @”
JoanComasFdz

1
@JoanComasFdz,您救了我,非常感谢!
Chagai Friedlander

14

这是一个快速的工作答案:

获取您的容器名称或ID:

docker container ls

然后获取IP:

docker inspect <container_ID Or container_name> |grep 'IPAddress'

获取端口:

docker inspect <container_ID Or container_name> |grep 'Port'

13

Docker是用Go编写的,它也使用Go语法进行查询。

要检查特定容器的IP地址,您需要运行命令(-f对于“格式”):

docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_id_or_name

对于容器ID或名称,可以运行以下命令

docker container ls

它将列出每个正在运行的容器。


1
这是非常有用的。在哪里可以找到编写自己的Go查询的文档?
Michael Hoffmann

12

这是我今天在Python中使用docker inspect containerJSON输出作为数据源开发的解决方案。

我有很多容器和基础结构需要检查,我需要以快速,美观的方式从任何容器中获取基本的网络信息。这就是为什么我制作这个脚本。

重要信息:从1.9版开始,Docker允许您创建多个网络并将其附加到容器。

#!/usr/bin/python

import json
import subprocess
import sys

try:
    CONTAINER = sys.argv[1]
except Exception as e:
    print "\n\tSpecify the container name, please."
    print "\t\tEx.:  script.py my_container\n"
    sys.exit(1)

# Inspecting container via Subprocess
proc = subprocess.Popen(["docker","inspect",CONTAINER],
                      stdout=subprocess.PIPE,
                      stderr=subprocess.STDOUT)

out = proc.stdout.read()
json_data = json.loads(out)[0]

net_dict = {}
for network in json_data["NetworkSettings"]["Networks"].keys():
    net_dict['mac_addr']  = json_data["NetworkSettings"]["Networks"][network]["MacAddress"]
    net_dict['ipv4_addr'] = json_data["NetworkSettings"]["Networks"][network]["IPAddress"]
    net_dict['ipv4_net']  = json_data["NetworkSettings"]["Networks"][network]["IPPrefixLen"]
    net_dict['ipv4_gtw']  = json_data["NetworkSettings"]["Networks"][network]["Gateway"]
    net_dict['ipv6_addr'] = json_data["NetworkSettings"]["Networks"][network]["GlobalIPv6Address"]
    net_dict['ipv6_net']  = json_data["NetworkSettings"]["Networks"][network]["GlobalIPv6PrefixLen"]
    net_dict['ipv6_gtw']  = json_data["NetworkSettings"]["Networks"][network]["IPv6Gateway"]
    for item in net_dict:
        if net_dict[item] == "" or net_dict[item] == 0:
            net_dict[item] = "null"
    print "\n[%s]" % network
    print "\n{}{:>13} {:>14}".format(net_dict['mac_addr'],"IP/NETWORK","GATEWAY")
    print "--------------------------------------------"
    print "IPv4 settings:{:>16}/{:<5}  {}".format(net_dict['ipv4_addr'],net_dict['ipv4_net'],net_dict['ipv4_gtw'])
    print "IPv6 settings:{:>16}/{:<5}  {}".format(net_dict['ipv6_addr'],net_dict['ipv6_net'],net_dict['ipv6_gtw'])

输出为:

$ python docker_netinfo.py debian1

[frontend]

02:42:ac:12:00:02   IP/NETWORK        GATEWAY
--------------------------------------------
IPv4 settings:      172.18.0.2/16     172.18.0.1
IPv6 settings:            null/null   null

[backend]

02:42:ac:13:00:02   IP/NETWORK        GATEWAY
--------------------------------------------
IPv4 settings:      172.19.0.2/16     172.19.0.1
IPv6 settings:            null/null   null

请在脚本中更改为python2.7,python3现在已普遍使用或编写了两个版本
42n4

我将更新我的Gist,并在收到后立即在此处发布。实际上,此包装器是为Python 2.7设计的。感谢您的反馈!
ivanleoncz

9
docker inspect --format '{{ .NetworkSettings.IPAddress }}' <containername or containerID here>

如果将容器部署到默认桥网络,则以上方法适用。

但是,如果使用自定义网桥网络或覆盖网络,我发现以下方法可以更好地工作:

docker exec <containername or containerID here> /sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'

9

为了扩展ko-dos的答案,下面是一个别名,用于列出所有容器名称及其IP地址:

alias docker-ips='docker ps | tail -n +2 | while read -a a; do name=${a[$((${#a[@]}-1))]}; echo -ne "$name\t"; docker inspect $name | grep IPAddress | cut -d \" -f 4; done'

1
可以将其简化很多,可以docker ps -q用来避免tail--format避免使用grep。另外,您可以传递多个容器ID docker inspect而不是在shell中循环。
布莱恩(Bryan)

1
docker ps -q只显示容器的数字ID,但我认为使用它们的名称更好。tail只是为了摆脱第一行(表头),仍然是必需的。不过,我可以使用--formatdocker ps | tail -n +2 | while read -a a; do name=${a[$((${#a[@]}-1))]}; echo -ne "$name\t"; docker inspect --format="{{.NetworkSettings.IPAddress}}" $name | cut -d \" -f 4; done。但这似乎并没有太大的改善……这grep是更具可读性的IMO。
马可·罗伊

1
稍作更改的版本,它首先在一行中列出IP,并列出容器名称:docker ps | 尾-n +2 | 而读-aa; 做name = $ {a [$(($ {#a [@]}-1))]}; 码头工人检查$ name | grep“ IPAddress。* [0-9] \ +” | cut -d \“ -f 4 | tr” \ n“”“; echo -e” \ t $ {name}“;完成
Gilead

docker inspect $cid | grep IPAddress | cut -d '"' -f 4 | tail -n 1
结尾

9

我用这种简单的方法

docker exec -it <container id or name> hostname -i

例如

ubuntu@myhost:~$ docker exec -it 3d618ac670fe hostname -i
10.0.1.5

7

如果使用Docker Toolbox安装了Docker,则可以使用Kitematic应用程序获取容器IP地址:

  1. 选择容器
  2. 点击设置
  3. 单击端口选项卡。

对我来说,IP地址位于“主机名/端口”选项卡上,但这仍然是一个非常有用的答案!请注意,docker inspect在运行docker toolbox时,该功能不起作用。它会报告一个IP地址,但它不是您的服务将使用的正确地址。
约兰·Roseen

7

要获取容器的IP地址和主机端口:

docker inspect containerId | awk '/IPAddress/ || /HostPort/'

输出:

    "HostPort": "4200"
                    "HostPort": "4200"
        "SecondaryIPAddresses": null,
        "IPAddress": "172.17.0.2",
                "IPAddress": "172.17.0.2",

7

注意!!!用于Docker Compose的用法:

由于Docker Compose为每个群集创建一个隔离的网络,因此以下方法不适用于docker-compose


最优雅,最简单的方法是定义shell函数,这是目前投票最多的@ WouterD's答案:

dockip() {
  docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$@"
}

Docker可以将容器ID写入Linux程序这样的文件:

运行时--cidfile=filename,Docker将容器的ID转储到“文件名”。

有关更多信息,请参见“ Docker运行PID等效部分 ”。

--cidfile="app.cid": Write the container ID to the file

使用PID文件:

  1. 运行带有--cidfile参数的容器,app.cid文件内容如下:

    a29ac3b9f8aebf66a1ba5989186bd620ea66f1740e9fe6524351e7ace139b909
    
  2. 您可以使用文件内容来检查Docker容器:

    blog-v4 git:(develop) ✗ docker inspect `cat app.cid`
    
  3. 您可以使用内联Python脚本提取容器IP:

    $ docker inspect `cat app.cid` | python -c "import json;import sys;\
    sys.stdout.write(json.load(sys.stdin)[0]['NetworkSettings']['IPAddress'])"
    172.17.0.2
    

这是一种更人性化的形式:

#!/usr/bin/env python
# Coding: utf-8
# Save this file like get-docker-ip.py in a folder that in $PATH
# Run it with
# $ docker inspect <CONTAINER ID> | get-docker-ip.py

import json
import sys

sys.stdout.write(json.load(sys.stdin)[0]['NetworkSettings']['IPAddress'])

有关更多信息,请参见“ 获取Docker容器IP地址的10种方法 ”。


6

对于Windows 10:

docker inspect --format "{{ .NetworkSettings.IPAddress }}"  containerId

5

这将列出主机上的所有容器IP:

sudo docker ps -aq | while read line;  do sudo docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $line ; done

5

Docker inspect用于打印所有容器ip及其各自的名称

docker ps -q | xargs -n 1 docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} {{ .Name }}' | sed 's/ \// /'

5

仅出于完整性考虑:

我真的很喜欢这个--format选项,但是起初我并不了解它,所以我使用了一个简单的Python单行代码来获得相同的结果:

docker inspect <CONTAINER> |python -c 'import json,sys;obj=json.load(sys.stdin);print obj[0]["NetworkSettings"]["IPAddress"]'

这是最酷的答案。还看到另外一个答案- stackoverflow.com/a/36306632/432903
prayagupd

5

将先前的答案与基于Docker映像名称查找容器ID相结合:

docker inspect --format '{{ .NetworkSettings.IPAddress }}' `docker ps | grep $IMAGE_NAME | sed 's/\|/ /' | awk '{print $1}'`

4

采用:

docker inspect $CID | grep IPAddress | grep -v null| cut -d '"' -f 4 | head -1

这是实际的单行适当命令。这就是我得到的。 $ docker inspect c4591485328d | grep IPAddress | grep -v null| cut -d '"' -f 4 | head -1 172.17.0.2
Jayant Bhawal '16年

4

对于Windows容器使用

docker exec <container> ipconfig

容器<container>名称ID在哪里。

您可以使用docker ps查找容器的ID。


请记住使用“ -rm”,否则它会慢慢吞噬具有未删除层的硬盘驱动器空间。在几乎所有情况下,最好将“ -rm”与“ run”配对。
Contango

@Contango:“ docker exec”在已经运行的容器中执行命令。它没有--rm开关。docs.docker.com/engine/reference/commandline/exec
kirodge

4

如果您忘记了容器ID或不想使用Shell命令进行操作,最好使用类似于Portainer的UI。

https://portainer.io/

$ docker volume create portainer_data
$ docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

在这里,您可以找到有关容器以及IP的所有信息。


4
尽管此链接可以回答问题,但在Stack Overflow上不鼓励仅链接的答案,但是您可以通过将链接的重要部分放入答案中来改善此答案,这可以确保如果更改链接,您的答案仍然是答案或删除:)
WhatsThePoint
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.