Лабораторная работа №4: Сетевое взаимодействие контейнеров
Цель работы
Section titled “Цель работы”Научиться создавать пользовательские (user-defined) сети в Docker и связывать контейнеры для безопасного общения друг с другом по именам, используя встроенный в Docker механизм DNS.
Основные теоретические положения
Section titled “Основные теоретические положения”1. Сеть bridge по умолчанию
Section titled “1. Сеть bridge по умолчанию”Когда Docker устанавливается, он создает сеть bridge. Все контейнеры, запущенные без указания другой сети, попадают в нее. Это удобно для простых случаев, но имеет недостатки:
- Нет изоляции: все контейнеры в этой сети могут общаться друг с другом.
- Нет автоматического service discovery: для обращения к другому контейнеру нужно знать его IP-адрес, который может меняться при перезапуске.
2. Пользовательские сети (user-defined networks)
Section titled “2. Пользовательские сети (user-defined networks)”Рекомендуемый способ организации сетевого взаимодействия.
- Изоляция: Контейнеры, находящиеся в разных пользовательских сетях, не могут общаться друг с другом (если их специально не подключить к обеим сетям). Контейнеры в одной сети могут.
- Встроенный DNS-сервер: Docker автоматически предоставляет DNS-сервис для каждой пользовательской сети. Это позволяет контейнерам обращаться друг к другу по имени контейнера. Например, контейнер
blogсможет найти контейнерdb-mysqlпо DNS-имениdb-mysql. Это и есть Service Discovery. - Рекомендуемая литература: Networking overview (Документация Docker)
3. Симуляция на одной машине
Section titled “3. Симуляция на одной машине”В реальном мире Web-node и Db-node могут быть разными машинами. Docker может работать в swarm-режиме для создания сети между хостами, но это продвинутая тема. Для целей нашего курса мы упростим задачу и будем запускать оба контейнера (блог и БД) на одной виртуальной машине — Web-node, чтобы продемонстрировать принципы сетевого взаимодействия в Docker.
Задания для выполнения
Section titled “Задания для выполнения”-
Подготовка среды (15 мин):
- Убедитесь, что вы работаете на
Web-node. - Остановите и удалите все контейнеры, которые могли остаться от предыдущих работ на
Web-nodeиDb-node. - Убедитесь, что на
Web-nodeскачаны оба образа:ghost:latestиmysql:8.0. Если нет, скачайте:docker pull mysql:8.0.
- Убедитесь, что вы работаете на
-
Создание и запуск контейнеров в одной сети (45 мин):
- На
Web-nodeсоздайте новую пользовательскую сеть типаbridge:Terminal window docker network create ghost-net - Просмотрите список сетей:
docker network ls. - Сначала запустите контейнер базы данных
mysqlв этой сети. Обратите внимание на флаги--networkи--name:Terminal window docker run -d --name db \--network ghost-net \-e MYSQL_ROOT_PASSWORD=mysecretpassword \-v mysql-data:/var/lib/mysql \mysql:8.0- Мы дали ему короткое имя
db. Именно по этому имени к нему будет обращаться блог.
- Мы дали ему короткое имя
- Теперь запустите контейнер
ghost. Ему нужно указать, в какой сети работать, и передать переменные окружения, чтобы он знал, как найти базу данных.Terminal window docker run -d --name blog -p 8080:2368 \--network ghost-net \-e database__client=mysql \-e database__connection__host=db \-e database__connection__user=root \-e database__connection__password=mysecretpassword \-e database__connection__database=ghost \-e url=http://localhost:8080 \ghost:latest- Обратите внимание на
database__connection__host=db. Мы указываем имя контейнера, а не IP-адрес!
- Обратите внимание на
- На
-
Проверка взаимодействия (30 мин ):
- Убедитесь, что оба контейнера запущены:
docker ps. - Зайдите внутрь контейнера
blogс помощью командыdocker exec. Эта команда позволяет выполнить процесс внутри уже запущенного контейнера.Terminal window docker exec -it blog sh - Внутри контейнера
blogустановите утилитуping(в этом образе ее нет по умолчанию) и проверьте доступность контейнераdb:Terminal window # Внутри контейнера blogapt-get update && apt-get install -y iputils-pingping db - Вы должны увидеть, что имя
dbуспешно “пингуется”, разрешаясь во внутренний IP-адрес контейнера MySQL. - Выйдите из контейнера (
exit). - Откройте в браузере
http://<IP-адрес Web-node>:8080и убедитесь, что блог работает. Это подтверждает, чтоghostсмог подключиться кmysqlпо сети.
- Убедитесь, что оба контейнера запущены:
Контрольные вопросы
Section titled “Контрольные вопросы”- Почему рекомендуется использовать пользовательские сети вместо сети
bridgeпо умолчанию? - Как контейнер
blogузнает IP-адрес контейнераdbв этой лабораторной работе? - Можно ли “подключить” уже запущенный контейнер к сети? (Подсказка:
docker network connect). - Что такое Service Discovery в контексте Docker?