English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Подключение контейнеров Docker

前面我们实现了通过网络端口来访问运行在 docker 容器内的服务。

容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。

下面我们来实现通过端口连接到一个 docker 容器。

网络端口映射

我们创建了一个 python 应用的容器。

w3codebox@w3codebox:~$ docker run -d -P training/webapp python app.py
fce072cc88cee71b1cdceb57c2821d054a4a59f67da6b416fceb5593f059fc6d

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

我们使用 -P 参数创建一个容器,使用 docker ps 可以看到容器端口 5000 绑定主机端口 32768。

w3codebox@w3codebox:~$ docker ps
CONTAINER ID    IMAGE               COMMAND            ...           PORTS                     NAMES
fce072cc88ce    training/webapp     "python app.py"    ...     0.0.0.0:32768->5000/tcp   grave_hopper

我们也可以使用 -p 标识来指定容器端口绑定到主机端口。

两种方式的区别是:

  • -P :是容器内部端口随机映射到主机的高端口。

  • -p : 是容器内部端口绑定到指定的主机端口。

w3codebox@w3codebox:~$ docker run -d -p 5000:5000 training/webapp python app.py
33e4523d30aaf0258915c368e66e03b49535de0ef20317d3f639d40222ba6bc0
w3codebox@w3codebox:~$ docker ps
CONTAINER ID        IMAGE               COMMAND           ...           PORTS                     NAMES
33e4523d30aa        training/webapp     "python app.py"   ...   0.0.0.0:5000->5000/tcp    berserk_bartik
fce072cc88ce        training/webapp     "python app.py"   ...   0.0.0.0:32768->5000/tcp   grave_hopper

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1。

w3codebox@w3codebox:~$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
95c6ceef88ca3e71eaf303c2833fd6701d8d1b2572b5613b5a932dfdfe8a857c
w3codebox@w3codebox:~$ docker ps
CONTAINER ID        IMAGE               COMMAND           ...     PORTS                                NAMES
95c6ceef88ca        training/webapp     "python app.py"   ...  5000/tcp, 127.0.0.1:5001->5000/tcp   adoring_stonebraker
33e4523d30aa        training/webapp     "python app.py"   ...  0.0.0.0:5000->5000/tcp               berserk_bartik
fce072cc88ce       training/webapp     "python app.py"   ...    0.0.0.0:32768->5000/tcp              grave_hopper

Таким образом, мы можем получить доступ к порту 5000 контейнера через 127.0.0.1:5001.

В примере выше, по умолчанию используются порты tcp, если нужно использовать порт udp, можно добавить /udp

w3codebox@w3codebox:~$ docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
6779686f06f6204579c1d655dd8b2b31e8e809b245a97b2d3a8e35abe9dcd22a
w3codebox@w3codebox:~$ docker ps
ИДЕНТИФИКАЦИОННЫЙ НОМЕР КОНТЕЙнера       ОБРАЗ               КOMАНДА           ...   ПОРТы                                ИМЯ
6779686f06f6        training/webapp     "python app.py"   ...   5000/tcp, 127.0.0.1:5000->5000/udp   drunk_visvesvaraya
95c6ceef88ca        training/webapp     "python app.py"   ...    5000/tcp, 127.0.0.1:5001->5000/tcp   adoring_stonebraker
33e4523d30aa        training/webapp     "python app.py"   ...     0.0.0.0:5000->5000/tcp               berserk_bartik
fce072cc88ce       training/webapp     "python app.py"   ...    0.0.0.0:32768->5000/tcp              grave_hopper

docker port Эта команда позволяет быстро увидеть绑定 портов.

w3codebox@w3codebox:~$ docker port adorable_stonebraker 5000
127.0.0.1:5001

Интерконнекция контейнеров Docker

Перенаправление портов не единственный способ подключения Docker к другому контейнеру.

Docker имеет систему соединений, которая позволяет соединять несколько контейнеров, делиться информацией о соединениях.

Связь Docker создает父子 отношения, где родительский контейнер может видеть информацию о детском контейнере.

Имя контейнера

Когда мы создаем контейнер, Docker автоматически даёт ему имя. Кроме того, мы можем использовать --name идентификатор для命名 контейнера, например:

w3codebox@w3codebox:~$ docker run -d -P --name w3codebox training/webapp python app.py
43780a6eabaaf14e590b6e849235c75f3012995403f97749775e38436db9a441

Мы можем использовать docker ps Эта команда позволяет увидеть имена контейнеров.

w3codebox@w3codebox:~$ docker ps -l
CONTAINER ID     IMAGE           COMMAND           ...    PORTS                     NAMES
43780a6eabaa     training/webapp   "python app.py"  ...     0.0.0.0:32769->5000/tcp   w3codebox

Создание новой сети

Сначала создадим новую сеть Docker.

$ docker network create -d bridge test-net

Описание параметров:

-dПараметр指定ирует тип сети Docker, который может быть bridge или overlay.

Тип сети overlay используется в режиме Swarm, в этом разделе вы можете пропустить его.

Подключение контейнера

Запустите контейнер и подключите его к新建ленной сети test-net:

$ docker run -itd --name test1 --network test-net ubuntu /bin/bash

Откройте новый терминал и запустите еще один контейнер, добавьте его в сеть test-net:

$ docker run -itd --name test2 --network test-net ubuntu /bin/bash

Нажмите на изображение, чтобы увидеть его в увеличенном виде:

Давайте проверим, установлена ли взаимосвязь между контейнерами test1 и test2 с помощью команды ping.

Если в контейнерах test1 и test2 отсутствует команда ping, выполните следующую команду для установки ping (здесь можно сразу установить в одном контейнере, создать из него образ и затем запустить эти два контейнера с новым образом):

apt-get update
apt install iputils-ping

В контейнере test1 введите следующую команду:

Нажмите на изображение, чтобы увидеть его в увеличенном виде:

Аналогично, контейнер test2 также успешно подключился к:

Нажмите на изображение, чтобы увидеть его в увеличенном виде:

Таким образом, контейнеры test1 и test2 установили взаимосвязь.

Если у вас несколько контейнеров, которые необходимо взаимосвязать, рекомендуется использовать Docker Compose, о чем будет gesagt позже.

Настройка DNS

Мы можем добавить следующий контент в файл /etc/docker/daemon.json на хосте, чтобы настроить DNS для всех контейнеров:

{
  "dns" : [
    "114.114.114.114",
    "8.8.8.8"
  ]
}

После настройки DNS контейнера автоматически будет настроен на 114.114.114.114 и 8.8.8.8.

После настройки вам нужно перезагрузить docker, чтобы изменения вступили в силу.

Чтобы проверить, настроен ли DNS контейнера, можно использовать следующую команду, которая выведет информацию о DNS контейнера:

$ docker run -it --rm ubuntu cat etc/resolv.conf

Нажмите на изображение, чтобы увидеть его в увеличенном виде:

Ручная настройка конфигурации контейнера

Если вы хотите настроить DNS только для указанного контейнера, вы можете использовать следующую команду:

$ docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu

Описание параметров:

--rm: Автоматически очищать файловую систему контейнера при его выходе.

-h ИМЯ_ХОСТА или --hostname=ИМЯ_ХОСТА: Установить имя хоста контейнера, которое будет записано в /etc/hostname и /etc/hosts внутри контейнера.

--dns=IP_ADRESA: Добавить DNS-сервер в /etc/resolv.conf контейнера, чтобы контейнер использовал этот сервер для разрешения всех имен хостов, которые не находятся в /etc/hosts.

--dns-search=DOMEN: Установить доменную зону поиска контейнера, когда зона поиска установлена в .example.com, при поиске хоста с именем host, DNS также будет искать host.example.com.

Нажмите на изображение, чтобы увидеть его в увеличенном виде:

Если при запуске контейнера не указан --dns и --dns-searchDocker по умолчанию использует /etc/resolv.conf на хост-машинах для конфигурации DNS контейнеров.