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

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


当前回答

注意!!!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种选择”。

其他回答

如果您想快速查看所有Docker IP地址,或者不键入实例名称,可以破解Docker ps命令,将其添加到~/.bashrc文件中:

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}\n"
        fi
    done;
}

这来自Andrew Johnstone在Docker GitHub上的提议:https://github.com/docker/docker/issues/8786

没有人提及的最佳方法是为容器分配主机名。

docker run -d --hostname localcontainerhostname imageName

这将为您提供ip地址,但您可能还是希望使用主机名

nslookup localcontainerhostname

这对我有用,我正在运行docker工具箱18.09.3,在windows 10家庭版:

键入命令“docker machine ls”

λdocker机器lsNAME活动驱动程序状态URL群集DOCKER错误default*virtualbox正在运行tcp://192.168.98.100:2376版本8.09.6

它将在URL列下显示实际IP。例如,“192.168.98.100”

使用任意字符串提取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以提供给脚本。

这是我今天用Python开发的一个解决方案,使用docker inspect容器JSON输出作为数据源。

我有很多容器和基础设施需要检查,我需要从任何容器中以快速、漂亮的方式获取基本的网络信息。这就是我写这个剧本的原因。

重要提示:从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