fbpx

Каталог статей

Каталог статей для размещения статей информационного характера

Как выучить

Изучите Docker за 5 дней (День 3 – Хранилище и сети)

Изучите Docker за 5 дней (День 3 – Хранилище и сети)

Добро пожаловать в третью статью моего цикла “Изучаем Docker за 5 дней”. В предыдущих частях мы узнали о некоторых важных концепциях Docker, а также о том, как использовать некоторые из его основных команд. Теперь пришло время углубиться в тему и узнать, как использовать сети и хранилища.

Я предполагаю, что вы уже имеете четкое представление о том, из чего состоит Docker, и, по крайней мере, знаете, как загрузить образ и запустить контейнер. Если это не так, я приглашаю вас прочитать две предыдущие статьи этого цикла:

Помните, что вам необходимо иметь запущенный Docker, чтобы применить на практике те возможности, о которых я буду рассказывать здесь. Как я уже говорил в прошлой статье, вы можете использовать для этого Play with Docker, если не хотите тратить время на установку всего необходимого.

Хранение в Docker

До сих пор мы могли запускать контейнер на основе определенного образа (Nginx). Но в этом контейнере нет никакого содержимого, созданного нами. Мы хотим подправить этот образ и включить в него наши файлы, код и конфигурации. Можем ли мы это сделать? Конечно, можем! Но для этого нам нужно нечто под названием “хранилище”.

Используя хранилище в Docker, мы можем сохранять данные или файлы из хост-системы в наши контейнеры и наоборот. Для этого мы можем использовать либо Bind Mounts, либо Volumes. Это совершенно одно и то же, но разное (что?). Позвольте мне объяснить это вкратце:

  • Bind Mounts : используются для хранения файлов и каталогов в контейнере. Чаще всего вы будете использовать их для файлов вашего проекта.
  • Тома : используются для хранения данных. Вы будете использовать их для своих баз данных.

Короче говоря: Используйте Bind Mounts для файлов проекта и Volumes для данных.

То, что я только что объяснил, не претендует на то, чтобы быть очень конкретным, научно-обобщающим определением Bind Mounts и Volumes – проверьте официальную документацию, если вам это нужно – Это просто способ обобщить все.

Использование bind mounts с контейнером Nginx

В предыдущей статье мы узнали, как запустить контейнер nginx с помощью этой команды:

Отлично! Но наверняка вы хотите, чтобы этот nginx-сервер работал с вашим контентом. Не знаю! Может быть, вы хотите показать кота, играющего на клавиатуре, вот так:

Чтобы достичь этого, в качестве первого шага нам нужно подготовить активы в нашей хост-системе, которые мы хотим, чтобы контейнер загрузил. К счастью для вас, у меня уже есть готовые файлы, и вы можете загрузить их отсюда. Это zip-файл, поэтому сначала его нужно разархивировать и перейти в его корневую папку с помощью “cd”.

Перечислите файлы внутри этой папки, используя “ls”, чтобы мы могли видеть, какие файлы или каталоги здесь находятся. Вы должны увидеть только один каталог “html”, а если вы перечислите файлы внутри этого каталога, то увидите три файла или веб-актива. Вся эта папка

Давайте немного проанализируем то, что мы сделали. Как видите, единственным отличием является аргумент “-v”: $(pwd)/html:/usr/share/nginx/html . Здесь мы видим два пути Unix, разделенные двоеточием. Первый путь – это каталог с хост-машины, который вы хотите смонтировать; второй – путь к каталогу назначения в контейнере. Обратите внимание, что для пути к хосту используется $(pwd), это транспонирование команды Unix “pwd”, которая используется для получения текущего рабочего каталога, или, другими словами, где вы сейчас находитесь. Если бы мы не использовали эту команду, нам пришлось бы записывать весь абсолютный путь.

В нескольких словах, то, что мы делаем здесь, это просим docker:

Взять все, что находится внутри пути: /html с моей хост-машины и смонтировать его на следующий путь к контейнерам: /usr/share/nginx/html .

С этого момента и далее, любое изменение, которое вы сделаете в ваших HTML файлах с хост-машины, будет автоматически отражено в HTML файлах из вашего контейнера. Вы можете проверить это, немного подправив файл index.html с помощью вашего любимого редактора. Например, попробуйте изменить заголовок. Когда вы обновите браузер, вы увидите, как изменения вступят в силу на вашей странице. Круто, да?

Использование томов с образом Mongo

Как я уже объяснял, одной из особенностей контейнеров Docker является их “разрушаемость”, то есть мы можем быстро удалить любой контейнер, не оставив после себя никаких следов. Это полезно для многих ситуаций, но как это отразится, когда нам нужно сохранить какие-то данные? Значит ли это, что как только мы удалим контейнер БД, все наши данные исчезнут навсегда? Мы этого точно не хотим.

К счастью для нас, команда Docker придумала для этого решение под названием “Volumes”. В общем смысле, тома – это определенные единицы хранения, управляемые движком Docker, которые мы можем использовать для сохранения любых необходимых данных.

Большинство существующих образов баз данных уже имеют настроенные по умолчанию тома. Однако здесь мы научимся создавать свои собственные тома и использовать их в наших контейнерах DB.

Сначала запустим контейнер mongo с помощью этой команды:

Здесь нет ничего нового, мы просто запускаем контейнер mongo в “режиме отсоединения”, имя контейнера – “myMongo”. Этот образ по умолчанию имеет два назначенных тома. Мы можем проверить это, осмотрев контейнер:

Здесь мы увидим большой вывод JSON, в котором нас интересует только эта часть:

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

И результат будет выглядеть примерно так:

Обратите внимание, что имена томов совпадают с именами из отпечатка docker inspect. Эти тома будут доступны, даже если связанный контейнер остановится. Поэтому любые сохраненные здесь данные будут в безопасности. Давайте проверим это, добавив запись в нашу базу данных mongo. Сначала выполните эту команду, чтобы получить доступ к оболочке mongo:

ПРИМЕЧАНИЕ: “mongo” – это команда, используемая для доступа к оболочке mongo. Не путать с аргументом “имя образа”, который мы используем для запуска контейнера.

Добавьте запись, просто введя эту команду mongo:

Выйдите из оболочки mongo, просто набрав “exit”, и перезапустите контейнер docker, выполнив команду docker container restart myMongo . Если вы снова войдете в оболочку mongo и выполните запрос “find”, вы должны увидеть запись, которую вы вставили несколько минут назад:

Итак, кажется, что все работает нормально, если использовать только тома по умолчанию. Так почему же нам нужно создавать пользовательские тома?

Использование томов по умолчанию имеет свои недостатки. Что произойдет, если мы удалим контейнеры, используемые этими томами? Тома останутся, но если мы запустим новые контейнеры DB, они будут использовать новые тома вместо старых. Существует способ связать первые тома с новыми контейнерами, но поскольку ранние тома маркируются с помощью длинных уникальных идентификаторов, процесс может оказаться довольно громоздким. Кроме того, у вас может быть много томов, используемых разными контейнерами. Как вы сможете определить, какой том вам нужен среди других? Сложная задача.

Что же мы тогда делаем? Мы создаем собственные тома!

Чтобы создать том, достаточно выполнить эту команду:

Как вы уже догадались, “my-mongo-volume” – это имя, которое мы дадим нашему новому пользовательскому тому. Если мы снова выведем список томов, то теперь мы увидим самый новый созданный том:

Теперь давайте создадим новый экземпляр mongo – чтобы не удалять старый – но на этот раз мы будем связывать новый созданный том:

Как вы можете видеть, на этот раз мы включаем опцию “-v”, это нечто довольно знакомое с тем, что мы делали в прошлом разделе. Единственное отличие заключается в том, что мы используем имя тома, который мы создали ранее. Часть после двоеточия представляет собой путь назначения контейнера – место, куда будет смонтирован том. В данном случае мы хотим смонтировать том для сохранения наших данных, поэтому мы используем путь /data/db.

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

Мы можем связать этот же том с другими контейнерами для тестирования различных конфигураций. Вы также можете связать тома с различными версиями одного и того же образа, если, конечно, в них нет ломающих изменений.

Осмотрите контейнер “myNewMongo”. Вы должны увидеть изменения в разделе “Mounts”:

Теперь вместо уникального идентификатора “Name” у нас есть имя созданного тома.

Сети в Docker

До сих пор мы имели дело с одним контейнером в одно время. Но все мы знаем, что реальные приложения работают не так. В настоящее время проект минимального стека состоит из API, фронтенд-приложения и базы данных – как самый простой пример. Мы также можем говорить о микросервисной архитектуре с множеством одновременно работающих артефактов. Как мы можем соединить все эти части с помощью Docker?

Если вы хотите соединить два или более контейнера, чтобы они могли общаться друг с другом, они должны использовать одну и ту же сеть. В Docker есть несколько способов добиться этого, но не все они хороши.

В общем, когда дело доходит до выбора того, как наши контейнеры будут общаться друг с другом, у нас есть хорошие, плохие и уродливые способы:

Хороший: создание определенной мостовой сети. Мы сосредоточимся на этом.

Плохой: опубликовать все необходимые порты и запустить контейнеры с опцией – net=”host”. Пожалуйста, не делайте этого!

Плохой : использование

  • Теперь давайте запустим контейнер PHP-apache и свяжем его с нашей новой созданной сетью. Для этого мы используем опцию –network:
  • Теперь пришло время для базы данных MySQL:
  • Для контейнера MySQL нам необходимо установить переменную окружения MYSQL_ROOT_PASSWORD.

На данном этапе эти два контейнера должны иметь возможность взаимодействовать друг с другом. Чтобы подтвердить это, мы можем использовать команду “ping” внутри одного из наших контейнеров. Давайте сначала получим shell-доступ к экземпляру PHP:

К сожалению, для этого контейнера команда ping недоступна. Поэтому нам нужно установить ее:

После установки инструмента ping в контейнер PHP, мы можем начать пинговать экземпляр MySQL, используя имя его контейнера. Мы должны увидеть ответы ping.

Как вы можете видеть, имя контейнера разрешится в IP-адрес контейнера из вашей пользовательской сети. Поздравляем, теперь ваши контейнеры подключены!

Это выглядит хорошо!

Благодаря тому, чему мы научились до сих пор, мы можем использовать функции сети и хранилища. Но нам все еще не хватает важной части Docker. Поэтому в следующей статье я расскажу, как писать Dockerfiles. До скорой встречи!

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

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