ИТ Блог. Администрирование серверов на основе Linux (Ubuntu, Debian, CentOS, openSUSE)

Как получить IP-адрес Docker-контейнера

Установить Docker 1.11 на Ubuntu 16.04 LTS x64

Хотите знать, какой IP-адрес у вашего запущенного док-контейнера? Вы можете проверить работающий контейнер, чтобы получить эту информацию.

sudo docker container inspect container_name_or_ID
Не знаете название или идентификатор контейнера? Используйте команду sudo docker ps.

Команда inspect дает вам много подробностей об исследуемом контейнере. Подойдите к концу и загляните в раздел Networks, чтобы получить IP-адрес контейнера.

Вы также можете использовать команду grep, чтобы получить только строки, соответствующие строке «IPAddress».

Не пугайтесь, если у вашего контейнера более одного IP-адреса. В этом нет ничего необычного. Чтобы понять это, вам нужно понять, как контейнеры взаимодействуют друг с другом.

Мы объясним вам это в следующем разделе, а затем расскажу о некоторых других методах получения IP-адреса работающего контейнера докеров.

 

Как сообщаются докер-контейнеры?

Docker – это инструмент для упаковки и доставки программного обеспечения в массы с использованием технологии контейнеризации. Программное обеспечение может иметь множество целей, от, возможно, простой обработки текста до полноценного веб-сервера, на котором размещаются ваши личные файлы. Каждое из этих программ разбивается на микросервисы, а затем упаковывается в контейнеры. В зависимости от назначения программного обеспечения одной службе может потребоваться взаимодействие с другой.

Например, рассмотрим WordPress. Есть две службы: одна – это веб-сервер, обслуживающий интерфейс, а другая – бэкэнд, база данных. Интерфейс должен взаимодействовать с базой данных, иначе он просто не будет работать.

Эта связь достигается за счет наличия по крайней мере двух сетевых интерфейсов, связанных с каждым из этих двух контейнеров, причем оба интерфейса подключены к одной и той же сети. Эта сеть называется «докер-сетью».

 

Сеть докеров

Думайте о сети докеров как о пуле доступных 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.

Мы собираемся отфильтровать вывод, поскольку для этой демонстрации мне не нужны все данные.

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

Если у вас не установлен jq, установите его с помощью диспетчера пакетов вашего дистрибутива.

У каждой из этих сетей докеров есть подсеть, в случае 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

 

Проверка IP-адреса вашего док-контейнера

Есть несколько способов проверить IP-адрес [а], связанный с вашим контейнером, вот их список, включая примеры команд.

Метод 1: осматривая контейнер

В суб-команде inspect в docker чрезвычайно полезны. Контейнер можно проверить с помощью команды docker container inspect [CONTAINER ID]|[CONTAINER NAME].

Проверка контейнера означает получение как можно большего количества информации о контейнере, от портов, переменных среды до точек монтирования, данных контрольной группы и т. д. Из него можно извлечь 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 (или другую команду, которая показывает IP-адреса, связанные с сетевыми адаптерами).

Причина, по которой мы не рекомендуем это делать, заключается в том, что многие изображения довольно легкие и не содержат команды ip (или чего-то подобного).

Возьмите изображение ubuntu:20.04 в качестве примера, запустите контейнер, как показано ниже

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

 

Чтобы контейнер работал, мы использовали команду sleep 1d.

Теперь запустите процесс оболочки внутри контейнера и прикрепите свой stdin | stdout вот так

docker exec -ti ubuntu-ip sh

 

Попав в этот контейнер, попробуйте запустить ip или ifconfig. Вы увидите что-то вроде следующего:

❯ 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]

 

Здесь вместо идентификатора мы будем использовать имя, 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. Вы можете увидеть контейнеры и IP-адреса в указанном выше объекте JSON. Теперь извлечь IP-адрес конкретного контейнера здесь немного сложнее.

Если вы знаете идентификатор контейнера, вы можете использовать jq это так

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

 

Вот пример

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

 

В большинстве случаев вы не можете вспомнить идентификатор контейнера, поэтому, если вы хотите получить 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

Это были все методы, с помощью которых вы можете получить 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-адреса, как это.

На сегодня все. Надеюсь, эта статья была для вас полезной. Если у вас есть какие-либо вопросы, дайте мне знать в комментариях ниже.

Exit mobile version