How to get a Docker container's IP address from the host?
创建新容器后,是否可以运行命令从主机获取容器的IP地址?
基本上,一旦Docker创建了容器,我就要滚动自己的代码部署和容器配置脚本。
现代Docker客户端语法:
1 | docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id |
旧Docker客户端语法:
1 | docker inspect --format '{{ .NetworkSettings.IPAddress }}' container_name_or_id |
只返回IP地址。
如注释所述:如果您在Windows上,请在大括号周围使用双引号
您可以使用
例子:
1 2 | CID=$(docker run -d -p 4321 base nc -lk 4321); docker inspect $CID |
首先获取容器ID:
1 | docker ps |
(第一列用于容器ID)
使用容器ID运行:
1 | docker inspect <container ID> |
在底部的"networksettings"下,可以找到"ipaddress"
或者只是这样做:
1 | docker inspect <container id> | grep"IPAddress" |
只需在一个命令中获取所有容器名称及其IP地址。
1 | docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq) |
如果您使用的是
1 | docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq) |
输出将是:
1 2 3 | /containerA - 172.17.0.4 /containerB - 172.17.0.3 /containerC - 172.17.0.2 |
在您的
1 2 3 | docker-ip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}'"$@" } |
然后,要获取容器的IP地址,只需执行以下操作:
1 | docker-ip YOUR_CONTAINER_ID |
对于Docker的新版本,请使用以下内容:
1 2 3 | docker-ip() { docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'"$@" } |
显示所有容器的IP地址:
1 | docker inspect --format='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -aq) |
在Docker 1.3+中,您还可以通过以下步骤进行检查:
输入正在运行的Docker:
1 2 3 4 5 6 7 8 9 | 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 |
从Docker 1.10.3版开始,构建20F81DD
除非您告诉Docker,否则Docker总是在网桥网络中启动您的容器。所以您可以尝试下面的命令:
1 | docker network inspect bridge |
然后返回一个containers部分,该部分将显示该运行容器的IP地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | [ { "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" } } ] |
执行:
1 | docker ps -a |
这将显示活动的Docker图像:
1 2 | 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值:
1 | docker inspect <CONTAINER ID> | grep -w"IPAddress" | awk '{ print $2 }' | head -n 1 | cut -d"," -f1 |
"172.170.2"
基于我喜欢的一些答案,我决定将它们合并到一个函数中,以获取所有IP地址,另一个用于特定容器。它们现在在我的
1 2 3 4 5 6 7 | 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地址。
1 2 | docker-ips docker-ip YOUR_CONTAINER_ID |
按名称引用容器:
1 | docker run ... --name pg-master |
然后按名称获取IP地址:
1 | MASTER_HOST=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' pg-master) |
Docker是在Go内部生成的,它也使用Go语法进行查询。
要检查特定容器的IP地址,需要运行命令(-f for format选项)
对于容器ID或名称,可以运行命令
我编写了下面的bash脚本,从运行在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 } |
您应该将变量网络更改为自己的网络名称。
这里是我今天在Python中开发的一个解决方案,使用"docker-inspect-container"JSON输出作为数据源。
我有很多容器和基础设施需要检查,我需要以快速而漂亮的方式从任何容器中获取基本的网络信息。这就是我写这个剧本的原因。
重要提示:由于版本1.9,Docker允许您创建多个网络并将其连接到容器上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #!/usr/bin/python import json import subprocess import sys try: CONTAINER = sys.argv[1] except Exception as e: print" \tSpecify the container name, please." print"\t\tEx.: script.py my_container " 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" [%s]" % network print" {}{:>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']) |
输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ 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 |
1 | docker inspect --format '{{ .NetworkSettings.IPAddress }}' <containername or containerID here> |
如果将容器部署到默认网桥网络,则上述方法有效。
但是,如果使用自定义网桥网络或覆盖网络,我发现下面的功能更好:
1 | docker exec <containername or containerID here> /sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' |
要扩展ko-dos的答案,这里有一个别名来列出所有容器名称及其IP地址:
1 | 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' |
如果使用Docker工具箱安装Docker,则可以使用Kitematic应用程序获取容器IP地址:
快速回答(有效):获取容器名称或ID:
1 | sudo docker container ls |
然后执行(获取IP):
1 | sudo docker inspect <container_ID Or container_name> |grep 'IPAddress' |
获取端口:
1 | sudo docker inspect <container_ID Or container_name> |grep 'Port' |
注意!!!!对于docker compose用法:
由于docker compose为每个集群创建了一个独立的网络,下面的方法不适用于
最优雅和简单的方法是将shell函数定义为投票最多的答案@wouterd's:
1 2 3 | dockip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}'"$@" } |
Docker可以将容器ID写入类似Linux程序的文件:
使用
Docker运行PID等效部分
1 | --cidfile="app.cid": Write the container ID to the file |
使用PID文件
您可以使用文件内容检查Docker容器:
正在提取容器ip inline python脚本:
sys.stdout.write(json.load(sys.stdin)[0]['NetworkSettings']['IPAddress'])"
172.17.0.2
更人性化的形式
1 2 3 4 5 6 7 8 9 10 | #!/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']) |
http://networkstatic.net/10-examples-of-how-to-get-docker-container-ip-地址/
这里有10个获取Docker容器IP地址的备选方案。
对于Windows 10:
1 | docker inspect --format"{{ .NetworkSettings.IPAddress }}" containerId |
要获取容器的IP地址和主机端口:
1 | docker inspect containerId | awk '/IPAddress/ || /HostPort/' |
输出:
1 2 3 4 5 | "HostPort":"4200" "HostPort":"4200" "SecondaryIPAddresses": null, "IPAddress":"172.17.0.2", "IPAddress":"172.17.0.2", |
为了完整起见:
我真的很喜欢--format选项,但起初我不知道这个选项,所以我使用了一个简单的python one行程序来获得相同的结果:
1 | docker inspect <CONTAINER> |python -c 'import json,sys;obj=json.load(sys.stdin);print obj[0]["NetworkSettings"]["IPAddress"]' |
用途:
1 | docker inspect $CID | grep IPAddress | grep -v null| cut -d '"' -f 4 | head -1 |
如果您忘记了容器ID或者不想使用shell命令进行操作,那么最好使用类似于ui的portainer。
https://portainer.io网站/
1 2 | $ 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。
用于Windows容器
1 | docker exec <container> ipconfig |
其中
您可以使用
对于那些从谷歌(Google)来寻找从终端执行命令的解决方案(而不是通过脚本)的人来说,jid(一个具有自动完成和建议功能的交互式JSON向下钻取实用工具)可以让您用更少的输入实现相同的目标。
1 | docker inspect $CID | jid |
键入tabkbbd.net tabkbbd,您将看到以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | [Filter]> .[0].NetworkSettings { "Bridge":"", "EndpointID":"b69eb8bd4f11d8b172c82f21ab2e501fe532e4997fc007ed1a997750396355d5", "Gateway":"172.17.0.1", "GlobalIPv6Address":"", "GlobalIPv6PrefixLen": 0, "HairpinMode": false, "IPAddress":"172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway":"", "LinkLocalIPv6Address":"", "LinkLocalIPv6PrefixLen": 0, "MacAddress":"02:42:ac:11:00:02", "Networks": { "bridge": { "Aliases": null, "EndpointID":"b69eb8bd4f11d8b172c82f21ab2e501fe532e4997fc007ed1a997750396355d5", "Gateway":"172.17.0.1", "GlobalIPv6Address":"", |
键入.ipa tabkbbkbd,您将看到以下内容:
1 2 | [Filter]> .[0].NetworkSettings.IPAddress "172.17.0.2" |
结合前面的答案和基于Docker映像名称查找容器ID。
1 | docker inspect --format '{{ .NetworkSettings.IPAddress }}' `docker ps | grep $IMAGE_NAME | sed 's/\|/ /' | awk '{print $1}'` |
这将列出主机上的所有容器IP:
1 | sudo docker ps -aq | while read line; do sudo docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $line ; done |
1 | docker inspect <container id> | grep -i ip |
例如:
1 | docker inspect 2b0c4b617a8c | grep -i ip |
我必须按Docker容器名称提取Docker容器IP地址,以便在部署脚本中进一步使用。为此,我编写了以下bash命令:
1 | docker inspect $(sudo docker ps | grep my_container_name | head -c 12) | grep -e "IPAddress"\:[[:space:]]"[0-2] | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' |
假设将它放在bash脚本中很方便,这将期望我的容器名作为参数…
检查对我不起作用。可能是因为我使用了
不管怎样,我觉得这个很好用:
1 | docker exec -i -t NAME /sbin/ifconfig docker0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' |
接受的答案不适用于每个容器的多个网络:
1 2 3 | > docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' cc54d96d63ea 172.20.0.4172.18.0.5 |
下一个最好的答案是更接近:
1 2 3 4 5 6 | > docker inspect cc54d96d63ea | grep"IPAddress" "SecondaryIPAddresses": null, "IPAddress":"", "IPAddress":"172.20.0.4", "IPAddress":"172.18.0.5", |
我喜欢用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | > docker inspect cc54d96d63ea | jq -r 'map(.NetworkSettings.Networks) []' { "proxy": { "IPAMConfig": null, "Links": [ "server1_php_1:php", "server1_php_1:php_1", "server1_php_1:server1_php_1" ], "Aliases": [ "cc54d96d63ea", "web" ], "NetworkID":"7779959d7383e9cef09c970c38c24a1a6ff44695178d314e3cb646bfa30d9935", "EndpointID":"4ac2c26113bf10715048579dd77304008904186d9679cdbc8fcea65eee0bf13b", "Gateway":"172.20.0.1", "IPAddress":"172.20.0.4", "IPPrefixLen": 24, "IPv6Gateway":"", "GlobalIPv6Address":"", "GlobalIPv6PrefixLen": 0, "MacAddress":"02:42:ac:14:00:04", "DriverOpts": null }, "webservers": { "IPAMConfig": null, "Links": [ "server1_php_1:php", "server1_php_1:php_1", "server1_php_1:server1_php_1" ], "Aliases": [ "cc54d96d63ea", "web" ], "NetworkID":"907a7fba8816cd0ad89b7f5603bbc91122a2dd99902b504be6af16427c11a0a6", "EndpointID":"7febabe380d040b96b4e795417ba0954a103ac3fd37e9f6110189d9de92fbdae", "Gateway":"172.18.0.1", "IPAddress":"172.18.0.5", "IPPrefixLen": 24, "IPv6Gateway":"", "GlobalIPv6Address":"", "GlobalIPv6PrefixLen": 0, "MacAddress":"02:42:ac:12:00:05", "DriverOpts": null } } |
要列出每个容器的IP地址,则变为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | for s in `docker ps -q`; do echo `docker inspect -f"{{.Name}}" ${s}`: docker inspect ${s} | jq -r 'map(.NetworkSettings.Networks) []' | grep"IPAddress"; done /server1_web_1: "IPAddress":"172.20.0.4", "IPAddress":"172.18.0.5", /server1_php_1: "IPAddress":"172.20.0.3", "IPAddress":"172.18.0.4", /docker-gen: "IPAddress":"172.18.0.3", /nginx-proxy: "IPAddress":"172.20.0.2", "IPAddress":"172.18.0.2", |
如果您需要一个特定的方便别名来获取特定的容器IP,请使用此别名和接受的答案一起使用
1 | alias dockerip='f(){ docker inspect $1|grep -i"ipaddress.*[12]*\.[0-9]*"|sed -e"s/^ *//g" -e"s/[",]//g" -e"s/[*,]//g" -e"s/[a-zA-Z: ]//g" | sort --unique; unset -f f; }; f' |
然后你可以用
1 | dockerip <containername> |
您还可以使用containerID而不是containerName
btw接受了很好的答案,不能产生一个干净的输出,所以我对它进行了编辑,并使用了这样的方法;
1 | alias dockerips='for NAME in $(docker ps --format {{.Names}}); do echo -n"$NAME:"; docker inspect $NAME|grep -i"ipaddress.*[12]*\.[0-9]*"|sed -e"s/^ *//g" -e"s/[",]//g" -e"s/[_=*,]//g" -e"s/[a-zA-Z: ]//g"| sort --unique;done' |
编辑:根据注释更新到python 3.7。
还没有人提出Docker python API。获取IP地址的Docker API解决方案相当简单。
1 2 3 4 5 | import docker client = docker.DockerClient(base_url='unix://var/run/docker.sock') x_container = client.containers(filters={"name":"x_container"})[0] x_ip_addr = x_container["NetworkSettings"]["Networks"]["NETWORK_NAME"]["IPAddress"] |
不难找到,但很有用。此外,这可以很容易地修改,以查找分配给不同网络上容器的所有IP。
此脚本将获取所有正在运行的容器的IPv4地址,而无需进一步处理或解释结果。如果您不需要容器名称,您可以删除"echo-n$name:"行。非常适合自动化或填充变量。
1 2 3 4 5 6 7 | #!/bin/sh for NAME in $(docker ps --format {{.Names}}) do echo -n"$NAME:" docker inspect $NAME | grep -i"ip.*[12]*\.[0-9]*" | \ sed -e 's/^ *//g' -e 's/[",]//g' -e 's/[a-zA-Z: ]//g' done |
如果您想这样做,也可以创建别名:
1 | alias dockerip='for NAME in $(docker ps --format {{.Names}}); do echo -n"$NAME:"; docker inspect $NAME|grep -i"ip.*[12]*\.[0-9]*"|sed -e"s/^ *//g" -e"s/[*,]//g" -e"s/[a-zA-Z: ]//g"' |
Docker Inspect用于打印所有容器IP及其各自的名称
1 | docker ps -q | xargs -n 1 docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} {{ .Name }}' | sed 's/ \// /' |
如果您想快速查看所有Docker IP地址,或者不输入实例名,您可以黑客
1 2 3 4 5 6 7 8 9 10 11 12 | function docker-ips() { docker ps | while read line; do if `echo $line | grep -q 'CONTAINER ID'`; then echo -e"IP ADDRESS\t$line" else CID=$(echo $line | awk '{print $1}'); IP=$(docker inspect -f"{{ .NetworkSettings.IPAddress }}" $CID); printf"${IP}\t${line} " fi done; } |
这是由安德鲁约翰斯顿在码头吉特胡伯提出的一项建议:https://github.com/docker/docker/issues/8786
1 | docker inspect --format"{{ .NetworkSettings.Networks.mynetwork.IPAddress }}" <containername or containerID here> |
上述内容适用于Windows容器,其中已使用
1 | docker create network mynetwork |
接受的答案正好涵盖了要输入的内容,但是这里有一个小的改进:
1 2 3 | docker container inspect \ --format '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' \ $container_id_or_name |
这使用了
对于那些想知道如何查找其他值的人,我经常使用以下方法将任何Docker格式的语法输出到JSON中:
1 | docker container inspect --format '{{json .}}' $container_id_or_name | jq . |
您可能需要安装
Basically, once Docker creates the container, I want to roll my own code deployment and container configuration scripts.
我回答的主要原因是这个评论对我来说是一个巨大的危险信号。它表明您的图像不包含运行应用程序所需的所有内容,这是处理容器时的一个大反模式。多年来,有十几个客户机,我还没有找到一个真实的用例,通过Docker主机的内部IP地址直接连接到一个容器,而Docker主机没有更好的选择。相反,如果容器中有需要运行的启动后配置,则通常使用入口点脚本来完成。
还有一个危险信号表明你绕过了Docker的网络模型。使用Docker网络,有两种选择。首先,在容器之间通信时,这是通过用户创建的网络完成的,并使用Docker的内置DNS以名称或网络别名而不是通过重新创建容器时将更改的IP地址连接到容器。对于从Docker外部到容器的通信,这是通过将Docker主机的端口发布到容器,然后连接到该端口上的主机,而不是直接连接到容器来完成的。如果您坚持使用这两个选项,那么您应该能够在不知道应用程序内部IP地址的情况下访问应用程序。
在Windows PowerShell中尝试:
1 | docker inspect -f"{{ .NetworkSettings.Networks.nat.IPAddress }}" <container id> |
加
- 高雅语法
- 灵活(一旦你放弃了JQ,你可以在任何地方使用它,这里有JSON,非常有用)
- 强大的
减
- 需要安装JQ(例如apt get install JQ)
1 2 3 | for containerId in $(sudo docker ps -a | cut -f1 -d' ' | grep -v CONTAINER); do echo" ContainerId - $containerId >> $(sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' $containerId)" done |