如何获取Docker容器的IP地址


原文地址:如何获取Docker容器的IP地址

本篇文章分享如何获取Docker容器的IP地址。本篇文章分享了两种获取Docker容器IP地址的方法。

想知道正在运行的Docker容器的IP地址是什么?您可以检查正在运行的容器以获取该信息。

sudo docker container inspect container_name_or_ID

不知道容器的名称或ID?使用命令sudo docker ps

inspect命令为您提供了有关要检查的容器的许多详细信息。移至末尾并查看此Networks部分以获取容器的IP地址。

您也可以使用grep命令获取与字符串“ IPAddress”匹配的行。

如何获取Docker容器的IP地址

如果您的容器具有多个IP地址,请不要惊慌。这并不稀奇。要了解这一点,您需要了解容器之间如何通信。

我将在下一节中向您解释,然后介绍一些其他方法来获取正在运行的Docker容器的IP地址。

Docker容器如何通信?

Docker是使用容器化技术将软件打包并交付给大众的工具。软件可以有多种用途,从可能的简单文本处理到完整的Web服务器(托管您的私人文件)。这些软件中的每一个都细分为微服务,然后打包为容器。根据软件的用途,一项服务可能需要与另一项服务进行通信。

例如,考虑WordPress。有两种服务,一种是为前端提供服务的Web服务器,另一种是后端(即数据库)。前端必须与数据库进行通信,否则它将无法正常工作。

通过使至少两个与这两个容器中的每一个关联的网络接口来实现此通信,这两个接口都连接到同一网络。该网络称为“docker network”。

Docker网络

将docker网络视为可用IP地址的池。如果两个容器使用同一池中的IP地址,则它们将能够相互通信。

网络主要有两种类型,默认或预定义的网络以及用户定义的网络。

您可以使用以下命令获取网络列表

docker network ls

考虑下面的清单:

❯ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
272ff2e44dc2   bridge    bridge    local
5e4a3f5e99dd   host      host      local
cdaef1e49ddc   none      null      local

忽略最后两个,而专注于第一个网络。bridge如果未明确指定任何容器,则该网络是每个容器将要连接的默认网络。您可以通过运行docker network inspect bridge命令来获取有关此网络的更多详细信息。

我将对输出进行过滤,因为在本演示中,我不需要所有inspect即将爆炸的数据。

❯ docker network inspect -f '{{json .IPAM.Config}}' bridge | jq -r .[].Subnet
172.17.0.0/16

如果您尚未安装jq,请使用发行版的软件包管理器进行安装。

这些Docker网络中的每个网络都有一个子网,对于bridge网络而言,此子网为172.17.0.0/16。这意味着总共有65,534-1 = 65,533个可用主机或IP地址。我扣除了一个,因为172.17.0.1已分配给网关。您也可以使用以下命令看到它

docker network inspect -f '{{json .IPAM.Config}}' bridge | jq -r .[].Gateway

检查您的Docker容器的IP地址

您可以通过两种方法检查与容器关联的IP地址,以下是所有方法的列表,包括命令示例。

方法1:通过检查容器

inspectdocker的子命令非常有用。可以使用docker container inspect [CONTAINER ID]|[CONTAINER NAME]命令检查容器。

检查容器意味着从端口,环境变量到安装点,cgroup数据等获取有关容器的尽可能多的信息。可以从中提取IP地址。

如果inspect在容器上运行该命令,则将获得大量JSON格式的信息。向下滚动,直到找到密钥NetworkSettings,然后在其中寻找子密钥IPAddress。那是您容器的IP地址。

要执行的命令如下所示

docker container inspect [CONTAINER ID]|[CONTAINER NAME]

这是我的输出(已截断)

> docker container inspect ubuntu-ip
.
.
.
"NetworkSettings": {
.
.
.
            "IPAddress": "172.17.0.2",
.
.
.

您可以像这样过滤输出,而不是滚动浏览所有内容:

docker container inspect -f '{{ .NetworkSettings.IPAddress }}' CONTAINER_ID_OR_NAME

这是一个过滤后的输出:

❯ docker container inspect -f '{{ .NetworkSettings.IPAddress }}' ubuntu-ip 
172.17.0.2

如果要获取与特定网络关联的IP地址,请使用以下命令

docker container inspect -f '{{ .NetworkSettings.Networks.[NETWORK NAME].IPAddress }}' CONTAINER_ID_OR_NAME

样本输出:

❯ docker container inspect -f '{{ .NetworkSettings.Networks.bridge.IPAddress }}' ubuntu-ip 
172.17.0.2

方法2:使用容器的外壳

这是最简单的方法,但我也不推荐这样做

在这种方法中,您将stdin | stdout附加到容器上,然后运行ip命令(或其他一些命令,这些命令显示与NIC关联的IP地址)。

我不建议这样做的原因是许多图像都很轻巧,并且不包含ip命令(或类似命令)。

ubuntu:20.04图像为例,启动一个如下容器

docker run --rm --name ubuntu-ip -d ubuntu:20.04 sleep 1d

为了保持容器运行,我使用了sleep 1d命令。

现在,在容器内启动shell进程,并像这样附加您的stdin | stdout

docker exec -ti ubuntu-ip sh

进入此容器后,尝试运行ipifconfig。您会看到类似以下内容:

❯ docker exec -ti ubuntu-ip sh
# ip
sh: 1: ip: not found
# ifconfig
sh: 2: ifconfig: not found

要使这些命令生效,您需要安装相关的软件包。要获取ip命令,请安装iproute2软件包并以以下方式重新运行命令ip a

# apt update -qq                                       
6 packages can be upgraded. Run 'apt list --upgradable' to see them.
# apt install iproute2 -yqq
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

现在,您可以看到与卡关联的IP地址eth0@if5为172.17.0.2。

注意该容器所属的网络。由于没有创建用户定义的网络并将其连接到此容器,因此将其连接到网桥网络,这就是为什么此IP的网络为172.17.0.0的原因。

这种方法确实有效,尽管它工作更多且重复性不高,但很直观。与该方法相比,下一种方法应该更好。

方法3:通过检查网络本身

每当容器连接到网络时,从网络上也可以看到该连接的容器,以及分配给这些容器的IP地址。

由于我的容器已连接到桥接网络,因此可以使用以下命令检查网络

docker network inspect [NETWORK NAME][NETWORK ID]

在这里,我将使用名称代替ID, bridge

docker network inspect bridge

这次Containers,我们将使用向下jq过滤的输出,而不是向下滚动到该部分。

❯ docker network inspect bridge | jq .[].Containers
{
  "1c76f35ce42ca0d31cfcc79da80eadfa4f69cb82e292e249ee1bd75d83a8e4ba": {
    "Name": "ubuntu-ip",
    "EndpointID": "44d6b85348d6274b4ee779f9d3617d184ccfd3bad228ee652141d9b4157c50ae",
    "MacAddress": "02:42:ac:11:00:02",
    "IPv4Address": "172.17.0.2/16",
    "IPv6Address": ""
  },
  "50a4f195d8eae6b6b714e8aa058c6058dbe91d0a272c8ca826d4442df1c63885": {
    "Name": "ip",
    "EndpointID": "d4e72a4df81ee7023386df9d96676d9c291e2902349eb453338b8e0145a610fd",
    "MacAddress": "02:42:ac:11:00:03",
    "IPv4Address": "172.17.0.3/16",
    "IPv6Address": ""
  }
}

为了演示这一点,我部署了另一个名为的容器ip。您可以在上面的JSON对象中看到容器和IP地址。现在,在这里提取特定容器的IP有点困难。

如果您知道容器的id,你可以使用jq这样的

docker network inspect bridge | jq '.[].Containers."[CONTAINER ID]".IPv4Address'

这是一个例子

❯ docker network inspect bridge | jq '.[].Containers."1c76f35ce42ca0d31cfcc79da80eadfa4f69cb82e292e249ee1bd75d83a8e4ba".IPv4Address' -r
172.17.0.2/16

大多数情况下,您不记得容器ID,因此,如果您仅想从容器名称获取IP,就需要一些知识jq(或者只是重复使用以下命令)。

docker network inspect -f '{{json .Containers}}' bridge | \
    jq '..|if type == "object" and has("Name") then select(.Name=="[CONTAINER NAME]") | .IPv4Address else empty end' -r

将容器名称放在select函数中,然后观察魔术发生的情况。

❯ docker network inspect -f '{{json .Containers}}' bridge | \
    jq '..|if type == "object" and has("Name") then select(.Name=="ubuntu-ip") | .IPv4Address else empty end' -r

172.17.0.2/16

您更喜欢哪种方法?方法1可能

这些都是获取Docker容器IP地址的所有方法。第二种方法虽然不能直观地再现。在大多数情况下,这是最常用的第一种方法,因为它最容易完成工作。

但是有时候您可能需要检查将某些容器连接到某个网络并获取该网络上的IP地址。在这种情况下,检查网络并获取IP很有意义。您可以从这样的网络中获取分配给它们的所有容器名称和IP

❯ docker network inspect -f '{{json .Containers}}' bridge | \
    jq '.. | if type=="object" and has("Name") then {(.Name): .IPv4Address} else empty end'

{
  "ubuntu-ip": "172.17.0.2/16"
}
{
  "ip": "172.17.0.3/16"
}

切换bridge到其他网络,您将获得所有容器及其IP地址,如下所示。

今天就这样。希望本文对您有所帮助。如果您有任何疑问,请在下面的评论中让我知道。

评论

登录后评论

服务器优惠活动

Top