Сеть

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

Запускает контейнер в сети по умолчанию

Docker включает поддержку сетевых контейнеров за счет использования сетевых драйверов. По умолчанию Docker предоставляет вам два сетевых драйвера: драйверы bridge и overlay. Вы также можете написать подключаемый модуль сетевого драйвера, чтобы вы могли создавать свои собственные драйверы, но это сложная задача.

Каждая установка Docker Engine автоматически включает три сети по умолчанию. Вы можете перечислить их:

$ docker network ls

NETWORK ID          NAME                DRIVER
18a2866682b8        none                null
c288470c46f6        host                host
7b369448dccb        bridge              bridge

Сеть с именем bridge является специальной сетью. Если вы не укажете иначе, Docker всегда запускает ваши контейнеры в этой сети. Пытается это сейчас:

$ docker run -itd --name=networktest ubuntu

74695c9cea6d9810718fddadc01a727a5dd3ce6a69d09752239736c030599741
bridge1

Проверка сети — это простой способ узнать IP-адрес контейнера.

$ docker network inspect bridge

[
    {
        "Name": "bridge",
        "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.1/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": {
                "Name": "networktest",
                "EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "9001"
        },
        "Labels": {}
    }
]

Вы можете удаляет контейнер из сети, отключив контейнер. Для этого вы указываете как имя сети, так и имя контейнера. Вы также можете использовать идентификатор контейнера. Однако в этом примере имя работает быстрее.

$ docker network disconnect bridge networktest

Хотя вы можете отключить контейнер от сети, вы не можете удаляет встроенную сеть bridge с именем bridge. Сети — это естественный способ изолировать контейнеры от других контейнеров или других сетей. Итак, когда вы приобретете опыт работы с Docker, создаёт свои собственные сети.

Создаёт свою собственную мостовую сеть

Docker Engine изначально поддерживает как мостовые, так и оверлейные сети. Мостовая сеть ограничена одним хостом, на котором работает Docker Engine. Оверлейная сеть может включать в себя несколько хостов и является более сложной темой. Для этого примера создаёт мостовую сеть:

$ docker network create -d bridge my_bridge

Флаг -d указывает Docker использовать драйвер bridge для новой сети. Вы могли бы оставить данный флаг выключенным, т. к. bridge является значением по умолчанию для этого флага. Go вперед и перечислите сети на вашем компьютере:

$ docker network ls

NETWORK ID          NAME                DRIVER
7b369448dccb        bridge              bridge
615d565d498c        my_bridge           bridge
18a2866682b8        none                null
c288470c46f6        host                host

Если вы осмотрите сеть, в ней ничего нет.

$ docker network inspect my_bridge

[
    {
        "Name": "my_bridge",
        "Id": "5a8afc6364bccb199540e133e63adb76a557906dd9ff82b94183fc48c40857ac",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {
                    "Subnet": "10.0.0.0/24",
                    "Gateway": "10.0.0.1"
                }
            ]
        },
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

Добавляет контейнеры в сеть

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

Запускает контейнер с базой данных PostgreSQL и передать ему флаг --net=my_bridge, чтобы подключить его к вашей новой сети:

$ docker run -d --net=my_bridge --name db training/postgres

Если вы осмотрите свой my_bridge, вы увидите, что к нему прикреплен контейнер. Вы также можете проверяет свой контейнер, чтобы увидеть, где он подключен:

$ docker inspect --format='{{json .NetworkSettings.Networks}}'  db

{"my_bridge":{"NetworkID":"7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99",
"EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"10.0.0.1","IPAddress":"10.0.0.254","IPPrefixLen":24,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}

Теперь запускает уже знакомое вам веб-приложение. На данный раз не указывайте сеть.

$ docker run -d --name web training/webapp python app.py
bridge2

В какой сети работает ваше приложение web? Проверяет приложение, чтобы убедиться, что оно работает в сети по умолчанию bridge.

$ docker inspect --format='{{json .NetworkSettings.Networks}}'  web

{"bridge":{"NetworkID":"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812",
"EndpointID":"508b170d56b2ac9e4ef86694b0a76a22dd3df1983404f7321da5649645bf7043","Gateway":"172.17.0.1","IPAddress":"10.0.0.2","IPPrefixLen":24,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:02"}}

Затем получает IP-адрес вашего web

$ docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

172.17.0.2

Теперь открывает оболочку для работающего контейнера db:

$ docker container exec -it db bash

root@a205f0dd33b2:/# ping 172.17.0.2
ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
^C
--- 172.17.0.2 ping statistics ---
44 packets transmitted, 0 received, 100% packet loss, time 43185ms

Через некоторое время используйте CTRL-C, чтобы завершает ping, и обратите внимание, что проверка связи не удалась. Это потому, что два контейнера работают в разных сетях. Вы можете это исправить. Затем используйте команду exit, чтобы закрыть контейнер.

Сеть Docker позволяет вам подключать контейнер к любому количеству сетей. Вы также можете прикрепить уже запущенный контейнер. Go вперед и прикрепите работающее приложение web к my_bridge.

$ docker network connect my_bridge web
bridge3

Снова открывает оболочку в приложении db и пытается выполняет команду ping. На данный раз просто используйте имя контейнера web, а не IP-адрес.

$ docker container exec -it db bash

root@a205f0dd33b2:/# ping web
PING web (10.0.0.2) 56(84) bytes of data.
64 bytes from web (10.0.0.2): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from web (10.0.0.2): icmp_seq=2 ttl=64 time=0.060 ms
64 bytes from web (10.0.0.2): icmp_seq=3 ttl=64 time=0.066 ms
^C
--- web ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.060/0.073/0.095/0.018 ms

ping показывает, что он связывается с другим IP-адресом, адресом в my_bridge, который отличается от его адреса в сети bridge.

Следующие шаги

Теперь, когда вы знаете, как сетевые контейнеры, см. как управлять контейнерами данных.