Network в Docker
Сетевое взаимодействие - это общение между процессами и контейнерами. Сетевая связь Docker в основном используется для установки связи между контейнерами Docker и связи с внешним миром.
Docker обрабатывает связь между контейнерами, создавая сеть мостов по умолчанию, в большинстве случаев этого достаточно для нормальной работы.
Docker позволяет создавать несколько типов сетевых драйверов:
bridge
или Мост это сетевой драйвер по умолчанию. Бридж сеть используется, когда ваши приложения запускаются в автономных контейнерах, которые должны взаимодействовать между собой, наглядный пример Nginx + MySQLhost
или Хост это сетевой драйвер для автономных контейнеров, удаленная сетевая изоляция между контейнером и Docker хостом. Данный драйвер доступен только для docker-swarm с поддержкой Docker 17.06 и выше.overlay/overlay2
или Оверлей Наложенная сеть это сетевой драйвер для соединения несколько демонов Docker между собой и которые позволяют docker-swarm службам взаимодействовать друг с другом. Вы также можете использовать оверлейные сети для облегчения связи между docker-swarm и автономным контейнером или между двумя отдельными контейнерами на разных Docker демонах. Эта стратегия устраняет необходимость выполнения маршрутизации на уровне ОС между этими контейнерамиmacvlan
или Маквлан это сетевой драйвер, который позволяют назначать MAC-адрес контейнеру, делая его отображаемым как физическое устройство в вашей сети. Docker демон направляет трафик на контейнеры по их MAC-адресам. Использование macvlan драйвера иногда является лучшим выбором при работе с устаревшими приложениями, которые ожидают, что они будут напрямую подключены к физической сетиnone
или Нон это сетевой драйвер, который умеет отключать всю сеть для контейнеров. Обычно используется в сочетании с пользовательским сетевым драйверомnetwork plugins
можете установить и использовать сторонние сетевые плагины с Docker контейнерами. Эти плагины доступны в Docker Store или у сторонних поставщиков услуг
Где и что лучше использовать:
bridge
или Мост лучше всего использовать для связи нескольких контейнеров на одном и том же Docker хосте. Можно юзать docker-compose и выберать даную сеть для такой связкиhost
или Хост лучше всего юзать, когда сетевой стек не должен быть изолирован от хоста Docker, но вы хотите, чтобы другие аспекты контейнера были изолированыoverlay/overlay2
или Оверлей Наложенная сеть лучше всего заюзать, когда вам нужны контейнеры, работающие на разных Docker хостах для связи, или, когда несколько приложений работают вместе, используя docker-swarmmacvlan
или Маквлан сети лучше всего использовать, когда вы переходите с VM/дедикейта на контейнеры или хотите, чтобы ваши контейнеры выглядели как физические хосты в вашей сети, каждый с уникальным MAC-адресомnetwork plugins
сетевые плагины позволяют интегрировать Docker со специализированными сетевыми стеками
Соединение контейнеров
При запуске docker-compose.yml
сети создаются автоматически. Вы можете легко проверить это, создав очень простой файл конфигурации:
version: '3.6'
services:
db:
image: mariadb:10.3
environment:
MYSQL_ROOT_PASSWORD: secret
phpmyadmin:
image: phpmyadmin
restart: always
ports:
- 8080:80
environment:
- PMA_HOSTS=db
Давайте запустим его и посмотрим, что произойдет:
docker-compose up -d
Creating network "myexampleproject_default" with the default driver
Pulling db (mariadb:10.3)...
(...)
В первой строке, сеть докеров по умолчанию называется myexampleproject_default
, сеть создана автоматически для этого проекта.
Все контейнеры от этого docker-compose.yml
подключены к этой сети. Это означает, что контейнеры могут легко разговаривать друг с другом.
Как следует это помнить? В сетях докеров, вы можете подключить сервисы, которые находятся в той же сети.
Что, если вы не хотите чтобы контейнеры могли разговаривать друг с другом? Возможно, вы пишете систему, в которой одна часть должна быть скрыта от другой. На практике такие части системы отделяются с помощью AWS VPC
или аналогичных механизмов, но было бы неплохо проверить это на машине разработки.
version: '3.6'
services:
service1-db:
image: mariadb:10.3
environment:
MYSQL_ROOT_PASSWORD: secret
networks:
- service1
service1-web:
image: nginxdemos/hello
ports:
- 80:80
networks:
- service1
- web
service2-db:
image: mariadb:10.3
environment:
MYSQL_ROOT_PASSWORD: secret
networks:
- service2
service2-web:
image: nginxdemos/hello
ports:
- 81:80
networks:
- service2
- web
networks:
service1:
service2:
web:
Мы сделали три различные сети:
service1
service2
web
По одной сети для каждого сервиса и подписали для веб-сервисов. Зачем нам третья сеть? Это необходимо для того, чтобы обеспечить связь между service1-web
и service2-web
. В настоящее время веб-сервисы находятся в двух пользовательских сетях, а service1-db
находятся только в одной пользовательской сети.
Просмотреть сети в Docker
Чтобы проверить какие сети имеются, выполните следующую команду:
docker network ls
NETWORK ID NAME DRIVER SCOPE
6df045e07b11 bridge bridge local
9d45c14e604a host host local
b285e48f2c94 none null local
NETWORK ID
при создании сети, ей присваивается ID, это собственно индификатор сетиNAME
имя сети, можно задать произвольное имяDRIVER
используемый драйвер для созданной сетиSCOPE
где используется
Создать Network в Docker
Давайте создадим сеть, самый простой способ это вызвать команду:
docker network create bridge-network
Или:
docker network create --driver=bridge bridge-network
Вы можете создавать bridge
, overlay
, host
, none
или кастомный network
. По дефолту, создается мост. Проверяем что вышло:
docker network ls
NETWORK ID NAME DRIVER SCOPE
6df045e07b11 bridge bridge local
9d45c14e604a host host local
c8668b3fc7f6 bridge-network bridge local
b285e48f2c94 none null local
Рассмотрим пример создания оверлей-сети:
docker network create -d overlay my-multihost-network
Или:
docker network create --driver overlay overlay_network
Рассмотрим пример создания macvlan сети:
docker network create -d macvlan \
> --subnet=172.16.86.0/24 \
> --gateway=172.16.86.1 \
> -o parent=eth0 \
> my-macvlan-net
Или:
docker network create --subnet 10.1.0.0/16 --gateway=10.1.0.1 --ip-range 10.1.4.0/24 --driver=bridge --label
Проверим созданную сеть на примере контейнера:
docker run -it --name=test_brifge04 --net brifge04 centos:centos7 /bin/bash
Если нужно, контейнеру можно выделить статический IP:
docker run -it --name=test_brifge04_2 --net brifge04 --ip=10.1.4.100 centos:centos7 /bin/bash
При создании сети, можно задавать дополнительные параметры, с ними можно ознакомится:
docker network create --help
Подключить контейнер к сети в Docker
Чтобы подключить контейнер к сети, нужно выполнить следующую команду:
docker network connect YOUR_NETWORK YOUR_CONTAINER
Где:
YOUR_NETWORK
cетьYOUR_CONTAINER
контейнер
Отключить контейнер от сети в Docker
Чтобы отключить контейнер от сети, нужно выполнить следующую команду:
docker network disconnect YOUR_NETWORK YOUR_CONTAINER
Где:
YOUR_NETWORK
cетьYOUR_CONTAINER
контейнер
Инспектор сетей в Docker
Можно получить подробную информацию о сети:
docker network inspect название_сети
[
{
"Name": "bridge-network",
"Id": "c8668b3fc7f6ac9d8694a34d225327f9abb1d195c9757966919ed4adf9b35cea",
"Created": "2018-10-19T08:24:28.511405837Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
Удаление сети в Docker
Для удаления сети, используйте:
docker network rm название_сети
Если нужно удалить все созданные сети которые не используются:
docker network prune