docker: network


Docker Network Overview
Сети Docker изнутри: как Docker использует iptables и интерфейсы Linux
Differences between user-defined bridges and the default bridge
Legacy container links

Для обеспечения функционирования сети Docker может использовать следующие виды драйверов:
bridge — драйвер используемый по умолчанию, т. е. если вы не указываете какую сеть использовать,то данная сеть создается автоматически. Данный тип сети используется, когда ваши приложения/сервисы запущенные в контейнерах должны коммуницировать между собой.
host — контейнер использует сетевой стэк хоста. Разделение пространства имен отсутствует, и все интерфейсы на хосте могут использоваться непосредственно контейнером.
overlay — данный тип сети соединяет несколько docker демонов вместе и позволяет swarm службам взаимодействовать. Также overlay можно использовать для обеспечения взаимодействия между swarm сервисом и отдельным контейнером или между контейнерами запущенных на отдельных docker демонах. Данная стратегия удаляет необходимость использования маршрутизации пакетов между контейнерами на уровне хостовой тачки.
none — с данным типом настройки вся сеть контейнера отключается, как правило используется с кастомным сетевым драйвером.
macvlan — сети macvlan позволяют назначать MAC-адрес контейнеру, делая его отображаемым как физическое устройство в вашей сети. Демон Docker направляет трафик на контейнеры по их MAC-адресам.
network plugins — можно использовать драйвера от третьей стороны. Они достпуны по ссылке

docker network ls — показывает список сетей на хостовой машине
docker network inspect ИМЯ_сети — показ конфиг сети, в том числе можно узнать какие контейнеры в данной сети
Докер при инсталяции по умолчанию создаёт host,none,bridge сети с одноименными названиями:

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
6034db82cb41        bridge              bridge              local
264f2aabb021        host                host                local
6dc0c3621ab8        none                null                local

а также виртуальный интерфейс docker0 на хостовой тачке. Затем вешается приватный ip, по умолчанию — 172.17.0.1/16 или любой ip из сети 172.17.0.0 — 172.17.255.255 на интерфейс docker0, главное ip будет выбран так чтоб не конфликтовать с ip адресами уже сконфигурированными на хостовой тачке.
Все контейнры по дефолту добавляются в сеть ‘bridge’. Для каждого контейнера создается интерфейс вида vethBLABLABLA, который добавляется в сеть ‘bridge’, а также объединяется в bridge с интерфейсом docker0, см ‘brctl show’ и ‘ip a’ на хостовой тачке. Все контейнеры в одной виртуальной сети могут общаться без проблем.
Пример:

1. Запускаем два контейнера:
docker container run -dit --rm --name node1 busybox sh
docker container run -dit --rm --name node2 busybox sh

2. Проверяем:
docker network inspect bridge -f {{.Containers}}
map[9f3fcdc8e7858be934bc8138435766614292c3c7e45f9a945d884bcb7962fc32:{node2 4621e8476ea1c2e836f3b427572f5d6abf4559f32d274c83c8b54908ecd28fb7 02:42:ac:11:00:03 172.17.0.3/16 } efa9665b2761ab375db57ea22c6749a3796d0e3b62924dc619891ad6af086e84:{node1 9c4597ba718ec403f40580d7b1ba660d704c58ea67631769b6c467089a297dbc 02:42:ac:11:00:02 172.17.0.2/16 }]

brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02423cff741b	no		veth28587c1
							vethb18581c

docker network create ИМЯ_СЕТИ — создать новую сеть.
По умолчанию будет использоваться bridge driver, т.е. будет добавлен новый сетевой интерфейс вида br-BLABLABLA (можно самому менять с помощью опции ‘-o com.docker.network.bridge.name=МОЁ_ИМЯ_ИНТЕРФЕЙСА’) на хостовой тачке. А при добавлении контейнера в данную сеть, его интерфейс будет объединяться в bridge с данным итерфейсом.
Чтоб создать сеть опредленного типа нужно исп. команду:
docker network create -d bridge/macvlan/ipvlan/overlay
сети типа host,none могут существовать только в единственном экземпляре на хосте, а т.к. докер по умолчанию их создает, то создать самостоятельно дополнительные сети данного типа не получится.

После создания сети контейнер можно добавить в сеть командой:
docker network connect ИМЯ_сети ИМЯ/id_контейнера — добавить контейнер в сеть
либо указать явно имя сети опцией —network или —net при создании контейнра

docker container run --net ИМЯ_сети ИМЯ_образа


docker network disconnect ИМЯ_СЕТИ ИМЯ/id_контейнера — удалить контейнер из сети
Пример:

1. bridge
docker network create -d bridge mybrdnet
docker container run --rm -d --name nginx -p"8080:80" --network=mybrdnet nginx
Проверяем:
в браузере --> http://ТВОЙ_ip_АДРЕС:8080

docker network inspect mybrdnet -f {{.Containers}}
map[346ea9c7f4a70b47e01fb96c69f68ff496082726dd3ae996ca19cd78e7529dc7:{nginx 1ea9a1dca65b064e680e326032c3341213eaf83509089d4992ed6bb41294ba57 02:42:ac:12:00:02 172.18.0.2/16 }]

2. host
docker container run --rm -d --name myhost2 --network=host nginx
Проверяем:
в браузере --> http://ТВОЙ_ip_АДРЕС

3. none
docker container run --rm -d --name myhost3 --network=none nginx

4. Есть еще такой вариант использования одного сетевого пространства имён несколькими контейнерами.
--net=container:ИМЯ/ID_контейнера - с данной опцией не создается сетевого пространства для контейнра, 
вместо этого контейнер начитает использовать сетевое пространство другого контейнера.
Пример:
docker container run --rm -itd --name baseitem -p 80:80 busybox sh
docker container run --rm -d --name webitem --net=container:baseitem nginx
Проверяем:
в браузере --> http://ТВОЙ_ip_АДРЕС

Docker имеет свой собственный DNS. Т.е. в одной виртуальной сети контейнеры могут общаться по имени, кроме дефолтной сети ‘bridge’, в ней нет DNS.
Пример:

Запускаем два контейнера:
docker container run -dit --rm --name node1 busybox sh
docker container run -dit --rm --name node2 busybox sh

Создаем сеть и указываем пару параметров - сеть,шлюз:
docker network create node_network --gateway=172.21.1.1 --subnet=172.21.1.0/24

Добавлем в нее раннее созданные контейнеры:
docker network connect node_network node1
docker network connect node_network node2

Проверяем:
docker network inspect node_network -f {{.Containers}}
map[2d59f25218735e8f500cf4f9c4c0464caab9a67784ae24eaa26f95369367382d:{node2 4db022b18726bae2aaab494f24687458bc19f049dc06474387f0450fb3989359 02:42:ac:15:01:03 172.21.1.3/24 } f55ffc946ab55c2e1937cc65f583f34f0b4c2c514294430b54cecfab8be19c2b:{node1 e2e060fb65496d67ce0dc47afd5da62d2a3486fe42eb69021f67e499344aadd0 02:42:ac:15:01:02 172.21.1.2/24 }]

Пингуем контейнеры по имени:
docker container exec node2 ping -c 3 -n node1
PING node1 (172.21.1.2): 56 data bytes
64 bytes from 172.21.1.2: seq=0 ttl=64 time=0.236 ms
64 bytes from 172.21.1.2: seq=1 ttl=64 time=0.083 ms
64 bytes from 172.21.1.2: seq=2 ttl=64 time=0.144 ms
--- node1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.083/0.154/0.236 ms

docker container exec node1 ping -c 3 -n node2
PING node2 (172.21.1.3): 56 data bytes
64 bytes from 172.21.1.3: seq=0 ttl=64 time=0.231 ms
64 bytes from 172.21.1.3: seq=1 ttl=64 time=0.251 ms
64 bytes from 172.21.1.3: seq=2 ttl=64 time=0.310 ms
--- node2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.231/0.264/0.310 ms

Видим, что контейнеры способны пинговать друг друга по имени по сети 172.21.1.0/24, которую мы раннее создали - node_network

Удалим из сети node_network оба контейнера node1 и node2:
docker network disconnect node_network node1
docker network disconnect node_network node2

Проверяем:
docker network inspect node_network -f {{.Containers}}
map[]

Пингуем по имени:
docker container exec node1 ping -c 3 node2
>ping: bad address 'node2' 
docker container exec node2 ping -c 3 node1
>ping: bad address 'node1'

Для проброса портов с хостовой тачки в контейнер используются ключи -p и -P в команде docker container run

docker container run --rm -d --name webitem -p 80:80 nginx
docker container ls>CONTAINER ID        IMAGE               COMMAND CREATED             STATUS              PORTS                NAMES
9a0909a853b4        nginx               "nginx -g 'daemon of…"   7 seconds ago       Up 6 seconds        0.0.0.0:80->80/tcp   webitem

Ключ -p принимает значения:
— container_port — 80
— host_port:container_port — 80:80
— ip_host:host_port:container_port —
0.0.0.0:80:80
127.0.0.1:80:80
192.168.10.10:80:80
— ip_host::container_port —
192.168.10.10::80

Ключ -P используется для автоматического мапинга портов в случаях, когда используются опция EXPOSE в Dockerfile или ключ —expose в docker container run.

docker container run --rm -dit -P --expose=20-22 --expose=25 --expose=110 --name baseitem busybox sh
 docker container ls -a>CONTAINER ID        IMAGE               COMMAND             CREATED          STATUS              PORTS
  NAMES
0e8378dc1721        busybox             "sh"                5 seconds ago       Up 4 seconds        0.0.0.0:32772->20/tcp, 0.0.0.0:32771->21/tcp, 0.0.0.0:32770->22/tcp, 0.0.0.0:32769->25/tcp, 0.0.0.0:32768->110/tcp   baseitem

Чтоб узнать какие порты проброшены с хостовой тачки в контейнер используется команда:
docker container port ИМЯ/ID_контэйнер

docker container port baseitem
110/tcp -> 0.0.0.0:32768
20/tcp -> 0.0.0.0:32772
21/tcp -> 0.0.0.0:32771
22/tcp -> 0.0.0.0:32770
25/tcp -> 0.0.0.0:32769

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *