Контейнеры Docker и их связывание в сети



Книга Контейнеры Docker и их связывание в сети

В этом руководстве используются файлы Dockerfile с репозиториями GitHub внутри, из этих Dockerfile собираются пользовательские образы и контейнеры. Научимся создавать и использовать в каталоге несколько файлов Dockerfile, создавать из них образы, а из образов  —  контейнеры и связывать контейнеры в сети.


Потребуется



  • Учетная запись Docker Hub.

  • Docker, установленный на локальном компьютере или IDE.

  • Учетная запись GitHub с репозиториями.

  • Базовые знания о Docker и Dockerfile.

  • Основные команды Linux.

  • IDE, например VS Code.


Цели



  • Создать три файла Dockerfile, автоматически подключаемых к Github, причем каждый к своему репозиторию.

  • Создать из трех Dockerfile три пользовательских образа Docker, а из каждого образа  —  по контейнеру.

  • Подтвердить доступ к репозиторию GitHub в каждом контейнере.

  • Один контейнер поместить в сеть Development, два других  —  в сеть Production.

  • Проверить, что контейнер сети Development не взаимодействует с другими контейнерами, а контейнеры сети Production взаимодействуют друг с другом.


Создание трех Dockerfile, автоматически подключаемых к Github


Сначала командой mkdir создаем в CLI каталог для Dockerfile и клонов репозитория GitHub, затем командой cd переходим в этот каталог:



Dockerfile создается прямо в командной строке с помощью vim или nano. Я предпочитаю VS Code. Подробнее о содержимом и параметрах Dockerfile  —  в официальной документации Docker Hub. Наша задача  —  создать три разных Dockerfile, каждый со своим репозиторием GitHub внутри. Затем создать образы и контейнеры Docker, связать один контейнер в сеть Development, а два  —  в сеть Production.


Создаем три Dockerfile  —  Dockerfile.dev, Dockerfile.prod1 и Dockerfile.prod2:



Командой ls выводим три файла текущего рабочего каталога:



В Vim, Nano или другом редакторе открываем файл Dockerfile.dev и начинаем его с официального образа Ubuntu последней версии FROM ubuntu:latest.


Для каждого Dockerfile добавляется репозиторий GitHub, к которому имеется доступ из контейнера. При запуске Ubuntu или любой другой ОС сначала командой RUN apt-get update обновляют пакеты, затем с помощью apt-get install -y git устанавливают Git для запуска команд Git внутри контейнера.


Получается пока такой Dockerile.dev:


FROM ubuntu:latest

RUN apt-get update && apt-get install -y git

Следующей командой в Dockerfile.dev клонируется нужный репозиторий GitHub внутри контейнера. В GitHub копируем URL-адрес репозитория, для первого контейнера возьму свой репозиторий Python:



В Dockerfile.dev запускаем RUN git clone <repo_URL> /repo. Этим /repo указывается, что при создании образа Docker появляется новый каталог repo, в который и отправляется клон репозитория GitHub.


Получился такой Dockerfile.dev:


FROM ubuntu:latest 

RUN apt-get update && apt-get install -y git

RUN git clone <repo_URL> /<new_directory_name>

Вот снимок экрана:



Мы просто клонируем репозиторий в контейнер, поэтому CMD в Dockerfile не нужен.


Повторим процесс создания Dockerfile для Dockerfile.prod1 и Dockerfile.prod2, понадобятся два дополнительных репозитория GitHub. Покажу на скриншотах:


Dockerfile.prod1

Dockerfile.prod2

Создание пользовательского образа Docker из Dockerfile


Чтобы создать три пользовательских образа Docker на основе трех только что созданных Dockerfile, сначала переходим в командной строке к каталогу с файлами Dockerfile.


*Если у вас несколько проектов с несколькими Dockerfile, убедитесь, что находитесь в правильном каталоге с только что созданными Dockerfile:



Создаем пользовательский образ из Dockerfile.dev этой командой:


docker build -t <image_name> -f Dockerfile.dev .

-t  —  это необязательный тег для именования образа. -f  —  это сокращение от find. Оно применяется, когда имеется несколько Dockerfile или у Dockerfile иное имя, нежели Dockerfile. В этом случае в одном каталоге несколько файлов Dockerfile. -f нужен для указания, из какого из них создавать образ. В конце ставится символ ., которым текущему каталогу задается контекст сборки:


Сборка образа Docker для Dockerfile.dev

Для Dockerfile.prod1 и Dockerfile.prod2 процесс повторяется, каждому образу присваивается свой тег-имя и меняется файл для поиска -f:


Сборка образа Docker для Dockerfile.prod1

Сборка Docker для Dockerfile.prod2

Выводим список только что созданных образов и подтверждаем их командой docker images:



Создание контейнера из каждого пользовательского образа


Создадим из каждого образа по контейнеру:


docker run -dt --name <container_name> <image_name>

Разберем эту команду:


docker run нужно для создания и запуска нового контейнера.


-d  —  сокращение от detach. В Docker им указывается на запуск контейнера в фоновом режиме и вывод идентификатора контейнера.


t  —  это TTY, которым выделяется псевдо-TTY для продолжения работы контейнера.


--name <container_name>  —  необязательное присвоение имени контейнера. Если его не присвоить, в Docker контейнеру автоматически присваивается случайное имя.


<image_name>  —  образ, из которого собирается контейнер.


Создаем первый контейнер с образом Dockerfile.dev, его имя может быть другим:


docker run -dt --name w16adv_dev_cont w16adv_dev

Контейнер 1: w16adv_dev_cont

Для создания контейнеров из образов Dockerfile.prod1 и Dockerfile.prod2 процесс повторяется, в команде CLI каждому контейнеру обязательно дается уникальное имя и указывается образ, из которого он создается:


Контейнер 2: w16_adv_prod1_cont

Контейнер 3: w16_adv_prod2_cont

Выводим список только что созданных контейнеров и подтверждаем их командой docker container ls:



Подтверждение доступа к репозиторию GitHub в каждом контейнере


Пока что мы создали три разных контейнера Docker из трех разных Dockerfile, каждый с уникальным репозиторием GitHub.


Доступ к репозиторию внутри каждого контейнера подтверждается командой docker exec с флагами -it для открытия интерактивного терминала, конечным bash открывается одноименная оболочка для работы в контейнере:


docker container exec -it <container_name> bash

Получаем поступ к репозиторию в первом контейнере w16adv_dev_cont:


docker container exec -it w16adv_dev_cont bash

И оказываемся внутри контейнера в корневом каталоге:



Командой ls выводим файловую систему внутри контейнера, в которой должен быть каталог repo  —  он появляется в каждом созданном ранее Dockefile:



Переходим в этот каталог командой cd repo и с помощью ls выводим список файлов репозитория GitHub:


Контейнер 1: подтверждение репозитория GitHub

Этим подтверждается: мы оказались в контейнере 1 w16adv_dev_cont и клонировали в него репозиторий GitHub. Командой exit выходим из первого контейнера и подтверждаем то же для второго и третьего:


Контейнер 2: подтверждение репозитория GitHub

Контейнер 3: подтверждение репозитория GitHub

Создание сети Development


Чтобы контейнеры взаимодействовали, они связываются в сеть. Наша задача  —  изолировать контейнер w16adv_dev_cont от двух других w16adv_prod1_cont и w16adv_prod2_cont, которые бы взаимодействовали друг с другом. Поместим первый контейнер в сеть Development.


Когда создается и запускается контейнер, мы подключаемся к частной виртуальной сети. По умолчанию, если не указано иное, контейнер присваивается драйверу bridge. Все контейнеры в виртуальной сети, например bridge, по умолчанию взаимодействуют друг с другом. Чтобы они не взаимодействовали, их помещают в отдельные сети.


Запускаем docker network inspect bridge и видим, что три контейнера автоматически присвоены этой сети, то есть все они взаимодействуют друг с другом:



Чтобы изолировать контейнер w16adv_dev_cont, поместим его в собственную сеть Development, создаваемую командой docker network create:


docker network create <network_name>


Подключаем его к этой сети командой docker network connect, вместо имени контейнера сгодится идентификатор, а вместо идентификатора сети  —  ее имя:


docker network connect <network_name> <container_name>

Подтверждаем подключение к Development командой docker network inspect Development:


Контейнер 1: подключение к сети Development

Создание сети Production


Для второго и третьего контейнеров w16adv_prod1_cont и w16adv_prod2_cont создадим сеть Production:


docker network create Production

Подключаем к ней контейнеры:


docker network connect <network_name> <container_name>


Подтверждаем подключения сети командой docker container inspect Production:


Контейнеры 2 и 3: подключение к сети Production

Проверяем, что сети Development и Production не взаимодействуют


Один контейнер Development и два Production находятся в разных сетях и не должны взаимодействовать. При выполнении команды docker network inspect контейнерам присваивается IPv4-адрес. Чтобы подтвердить отсутствие взаимодействия контейнеров Production с контейнером Development, зайдем в последний командой docker container exec -it и пропингуем первые, просто используя имя контейнера.


Проверка 1. Development не взаимодействует с Production


Входим в Development-контейнер w16adv_dev_cont:


docker exec -it <container_name> bash


Устанавливаем ping:


apt-get install -y iputils-ping

Пропинговываем второй Production-контейнер w16adv_prod1_cont:


ping <container_name>

Подключиться не получится:



Командой Exit выходим из контейнера Development.


Проверка 2. Production не взаимодействует с Development


Входим во второй Production-контейнер w16adv_prod1_cont:


docker exec -it <container_name> bash

Устанавливаем ping:


apt-get install -y iputils-ping

Пропинговываем Development-контейнер w16adv_dev_cont, и снова подключиться не получится:



Командой Exit выходим из контейнера.


Проверка 3. Production взаимодействует с Production


Production-контейнеры w16adv_prod1_cont и w16adv_prod2_cont находятся в одной сети, поэтому пропинговываются друг другом.


Входим в Production-контейнер w16adv_prod2_cont:


docker exec -it <container_name> bash

Устанавливаем ping:


apt-get install -y iputils-ping

Пропинговываем другой Production-контейнер w16adv_prod1_cont, здесь все проходит успешно, проверка останавливается командой control c:



Вот и все. Мы создали три файла Dockerfile с прямым подключением каждого к своему репозиторию GitHub. Из Dockerfile сделали три пользовательских образа Docker, а из каждого образа  —  по одному контейнеру. Изолировали один контейнер в сети Development и поместили два в Production. Затем проверили, что сеть Development изолирована и контейнеры Production взаимодействуют друг с другом.



276   0  

Comments

    Ничего не найдено.