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

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


当前回答

接受的答案对于每个容器的多个网络不适用:

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

172.20.0.4172.18.0.5

下一个最佳答案更接近:

> docker inspect cc54d96d63ea | grep "IPAddress"

"SecondaryIPAddresses": null,
"IPAddress": "",
    "IPAddress": "172.20.0.4",
    "IPAddress": "172.18.0.5",

我喜欢使用jq解析网络JSON:

> 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地址,则变成:

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

 for N in $(docker-compose ps -q) ; do echo "$(docker inspect -f '{{.Config.Hostname}}' ${N}) $(docker inspect -f '{{range $i, $value := .NetworkSettings.Networks}} [{{$i}}:{{.IPAddress}}]{{end}}' ${N})"; done

输出

containerA [networkA:192.168.1.4] [networkB:192.168.2.4]
containerB  [networkA:192.168.1.5]

要获取所有正在运行的容器,请替换第一个命令

for N in $(docker-compose ps -q)

with

 for N in $(docker container ls | awk 'NR>=2' | cut -c1-12 );

获取给定1个特定网络的1个特定容器(具有多个网络)的IP

docker inspect --format='{{range $i, $value := .NetworkSettings.Networks}}{{if eq $i "NETWORKNAME"}}{{.IPAddress}}{{end}}{{end}}' CONTAINERNAME

输出

192.168.1.4

获取给定1个特定网络的所有容器(具有多个网络)的“主机名IP”

for N in $(docker-compose ps -q) ; do echo "$(docker inspect -f '{{.Config.Hostname}}' ${N}) $(docker inspect -f '{{range $i, $value := .NetworkSettings.Networks}}{{if eq $i "intranet"}}{{.IPAddress}}{{end}}{{end}}' ${N})"; done

输出

containerA 192.168.1.4
containerB 192.168.1.5

获取给定1个特定网络的所有容器(具有多个网络)的IP

for N in $(docker-compose ps -q) ; do echo " $(docker inspect -f '{{range $i, $value := .NetworkSettings.Networks}}{{if eq $i "intranet"}}{{.IPAddress}}{{end}}{{end}}' ${N})"; done

输出

192.168.1.4
192.168.1.5

只是另一个经典的解决方案:

docker ps -aq | xargs docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}'

按名称引用容器:

docker run ... --name pg-master

然后按名称获取IP地址:

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

注意!!!Docker Compose用法:

由于Docker Compose为每个集群创建了一个独立的网络,因此下面的方法不适用于Docker Compos。


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

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

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

使用--cidfile=filename运行时,Docker将容器的ID转储为“filename”。

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

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

使用PID文件:

运行带有--cidfile参数的容器时,app.cid文件内容如下:2009年12月29日您可以使用文件内容检查Docker容器:blog-v4git:(开发)✗ docker inspect `cat app.cid`您可以使用内联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种选择”。

使用任意字符串提取IP:

我在这个问题中读到的许多(几乎所有)解决方案都需要用户首先识别<容器名称>或<容器ID>,然后将其提供给他们的解决方案以显示IP的中间步骤。

当容器被重新创建时,IP可以改变,如果发生这种情况,引用它的任何脚本现在都将被破坏。。。。

因此,我需要一种无需手动干预即可提取容器IP的方法,确保脚本始终具有正确的IP,即使每次重新创建容器时都会更改。

解决方案:

#!/bin/bash

# Only need to set "CONTAINERNAME" variable with an arbitrary
# string found in either the Container ID or Image Name and
# it prints container IP. Ensure the string is unique to desired host

CONTAINERNAME='mariadb-blog'
CONTAINERID="$(docker ps | grep -i $CONTAINERNAME | awk '{print $1}')"
CONTAINERIP="$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINERID)"

echo "$CONTAINERIP"

结论:

我已经用自己的Linux Docker Compose主机测试了这个脚本,截至20220722年,它运行可靠。事实上,很容易复制并粘贴脚本,以验证我的结果是否可复制。

请注意:有一个潜在的可靠性弱点:如果你不剪切自己的docker图像并依赖第三方的图像,他们可能会更改图像的命名惯例,并打破脚本中的grep。因此,我建议将任意字符串设置为ContainerName,因为您可以控制它,确保字符串的grep始终成功,并打印IP以提供给脚本。