Обзор
Что касается собственной сети Docker по умолчанию, разные контейнеры Docker на одном хосте могут напрямую взаимодействовать с мостом docker0, что нормально, в то время как контейнеры Docker на разных хостах могут быть сопоставлены только с портами на хосте.Для связи иногда используется этот метод. очень неудобно и даже не соответствует нашим требованиям, поэтому приходится напрямую общаться между Docker-контейнерами, расположенными на разных физических машинах, используя свои IP-адреса. Кроме того, если контейнеры Docker размещены на разных физических хостах, мы неизбежно столкнемся с проблемами межузловой связи с контейнерами Docker. Попробуем эту статью.
Примечание:Эта статья была впервые опубликована на моем официальном аккаунтеCodeSheep,МожетНажмитеилисканированиеследующеебудь остороженЗаходи подписывайся ↓ ↓ ↓
Сценарий построения
Как показано на рисунке ниже, у нас есть два физических хоста 1 и хост 2. Мы запускаем контейнер CentOS на соответствующих хостах. После успешного завершения два контейнера работают на двух хостах, и назначается IP-адрес по умолчанию. На рисунке показано, что это также сеть по умолчанию самого Docker.
Как на этом этапе контейнеры Docker на двух хостах могут взаимодействовать напрямую через IP-адреса?
Решение, которое сразу же приходит на ум, — использоватьдобавить маршрутДля обеспечения прямой связи между двумя контейнерами Centos. давай попробуем
Анализ принципа работы схемы
Поскольку IP-адрес контейнера используется для маршрутизации, необходимо избегать использования контейнерами на разных хостах одного и того же IP-адреса, поэтому мы должны назначить разные подсети для разных хостов, чтобы гарантировать это. Итак, мы создаем схему маршрутизации для связи между двумя контейнерами, как показано на следующем рисунке.
Конфигурации следующие:
- IP-адрес узла 1: 192.168.145.128.
- IP-адрес узла 2: 192.168.145.129.
- Подсеть, назначенная контейнеру Docker на хосте 1: 172.17.1.0/24.
- Подсеть, назначенная контейнеру Docker на хосте 2: 172.17.2.0/24.
После этой настройки контейнеры Docker на двух хостах определенно не будут использовать один и тот же IP-адрес, чтобы избежать конфликтов IP.
мы следующиеОпределите два правила маршрутизацииПросто:
- Все пакеты, предназначенные для 172.17.1.0/24, перенаправляются на хост 1.
- Все пакеты, предназначенные для 172.17.2.0/24, перенаправляются на хост 2.
Подводя итог, процесс передачи пакетов данных между двумя контейнерами выглядит следующим образом:
- Пакет данных, отправленный из контейнера1 в контейнер2, сначала отправляется на «шлюз» docker0 контейнера1, а затем, найдя маршрут хоста 1, становится известно, что пакет данных нужно отправить на хост 2, а затем пакет данных достигает хоста 2, затем перенаправляется на docker0 хоста 2 и, наконец, передает пакет данных в container2; обратный принцип тот же и больше не повторяется.
Это то, что мы имеем в виду, давайте попробуем и посмотрим, работает ли это.
фактический тест
- 0x01 Настройте docker0 на хосте 1 и хосте 2 соответственно.
Редактировать на хосте 1/etc/docker/daemon.json
файл, добавьте содержимое:"bip" : "ip/netmask"
{ "bip", "172.17.1.252/24" }
Редактировать на хосте 2/etc/docker/daemon.json
файл, добавьте содержимое:"bip" : "ip/netmask"
{ "bip", "172.17.2.252/24" }
- 0x02 Перезапустите службу Docker.
Выполните следующие команды как на хосте 1, так и на хосте 2, чтобы перезапустить службу Docker, чтобы измененный сетевой сегмент docker0 вступил в силу.
systemctl restart docker
- 0x03 Добавить правила маршрутизации
Добавьте правила маршрутизации на хосте 1 следующим образом:
route add -net 172.17.2.0 netmask 255.255.255.0 gw 192.168.145.129
Правила маршрутизации, добавленные на хосте 2, следующие:
route add -net 172.17.1.0 netmask 255.255.255.0 gw 192.168.145.128
- 0x04 Настроить правила iptables
Добавьте следующие правила для хоста 1:
iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -s 172.17.1.0/24 ! -d 172.17.0.0/16 -j MASQUERADE
Добавьте следующие правила на хост 2:
iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -s 172.17.2.0/24 ! -d 172.17.0.0/16 -j MASQUERADE
- 0x05 Запустить контейнер
Запустите контейнер Centos на хосте 1:
docker run -it --name container1 centos /bin/bash
Запустите контейнер Centos на хосте 2:
docker run -it --name container2 centos /bin/bash
- 0x06 Прямая связь между контейнерами
Хорошо, теперь два контейнера могут пинговать друг друга
постскриптум
В этой статье обсуждается возможная схема прямой связи между контейнерами Docker между разными хостами в локальной сети. Конечно, есть много готовых решений для реализации межхостового контейнерного взаимодействия, например фланель.личное частное облакоЭта схема также используется.
Дополнительные статьи автора о SpringBt находятся здесь:
- Мониторинг приложений Spring Boot на практике
- Приложения SpringBoot развертываются во внешнем контейнере Tomcat.
- Практика поисковой системы ElasticSearch в SpringBt
- Предварительное изучение совместного программирования Kotlin+SpringBoot
- Практика ведения журнала Spring Boot
- Элегантное кодирование SpringBoot: благословение Ломбока
Если вам интересно, вы также можете уделить время прочтению некоторых статей автора о контейнеризации и микросервисах:
- Используйте стек технологий K8S для создания личного частного облака Серийная статья
- Подробная конфигурация сервера Nginx из списка конфигураций
- Строительство центра мониторинга визуализации контейнеров Docker
- Использование ELK для создания контейнерного центра журналов приложений Docker
- Практика фреймворка RPC: Apache Thrift
- Практика фреймворка RPC: Google gRPC
- Построение микросервисного центра отслеживания цепочки вызовов
- Контейнеры Docker обмениваются данными между хостами
- Предварительное исследование кластера Docker Swarm
- Несколько рекомендаций по эффективному написанию Dockerfile