4. Упаковка приложений со всем необходимым для их работы, передача и запуск таких «контейнеров» другим, запуск нескольких контейнеров вместе
Как мы уже выяснили, DevOps — это процесс упаковки, тестирования и доставки приложений пользователям. В связи с этим нам крайне важно иметь возможность запускать, обновлять и собирать наши приложения в любом месте. Однако для работы приложений требуются библиотеки, конфигурационные файлы, сами запускаемые файлы приложений и т.д.
Контейнеризация
Docker — это инструмент для упаковки программ так, чтобы их можно было легко запускать на разных компьютерах без необходимости заново настраивать окружение. Представь себе, что у тебя есть программа, которая работает на твоем компьютере, но когда ты пытаешься запустить её на другом компьютере, она почему-то не работает. Это может произойти потому, что на втором компьютере нет нужных библиотек, версий программного обеспечения или других настроек, необходимых для работы программы.
Docker решает эту проблему, упаковывая программу вместе со всеми необходимыми зависимостями и настройками в специальный контейнер. Этот контейнер можно запустить на любом компьютере, где установлен Docker, и он будет работать точно так же, как на твоём компьютере. Таким образом, Docker помогает избежать проблем совместимости и упрощает процесс развертывания приложений.
Чтобы эффективно работать с контейнерами, важно иметь четкое представление о ключевых терминах, используемых в этой технологии. Вот основные из них:
- Docker — это приложение которое работает как сервис systemd (то есть запущенно постоянно), предназначенное для создания, запуска и управления контейнерами.
- Контейнер (Container) — это изолированная среда, которая содержит все необходимое для запуска приложения: код, зависимости, библиотеки, конфигурационные файлы и так далее. Контейнеры используют общие ресурсы хоста, но при этом остаются независимыми друг от друга.
- Образ (Image) — это шаблон из слоев, на основе которого создаются контейнеры. Можно представить, что образ как рецепт слоёного пирога, а контейнер — это уже готовый слоёный пирог. Образ включает в себя все необходимые компоненты для запуска приложения, такие как операционная система, библиотеки и настройки.
- Репозиторий (Repository) — это хранилище образов Docker. Репозитории могут быть как общедоступными, например, Docker Hub, так и частными — созданными на вашем компьютере и доступными только для ограниченного круга лиц, например, для ваших друзей. Они предоставляют возможность хранить и обмениваться образами между разработчиками и командами.
- Тег (Tag) — это метка, которая присваивается образу для идентификации конкретной версии или состояния. Например, тег “latest” обычно указывает на последнюю версию образа. Примеры образов:
- nginx:1.27.3 - базовый образ Nginx с тегом
1.27.3
, на основании которого вы можете
- ubuntu:24.04 - Базовый образ Ubuntu с тегом
24.04
, который вы можете использовать для запуска своего приложения в изолированной среде Ubuntu, добавляя собственные слои cсодержащие ваше приложение, команду для его запуска, библиотеки и т.д.
- Dockerfile — это файл, содержащий инструкции для сборки образа Docker. Он описывает шаги, которые необходимо выполнить для создания образа, начиная с базового (например как выше Ubuntu) и заканчивая установкой всех необходимых компонентов.
- Командная строка Docker (CLI) — это интерфейс для взаимодействия с сервисом Docker через команды. С помощью CLI можно выполнять различные операции, такие как создание, запуск, остановка и удаление контейнеров, сборка образов и многое другое.
- Volume (Том) — это механизм для сохранения данных вне контейнера. Том позволяет сохранять данные даже после удаления контейнера, что особенно полезно для хранения важных файлов или базы данных.
- Network (Сеть) — это способ подключения контейнеров друг к другу и внешнему миру. Docker поддерживает различные типы сетей, что позволяет настраивать взаимодействие между контейнерами.
Преимущества контейнеризации
- Простота и скорость развертывания - Контейнеры создаются и удаляются очень быстро, поскольку для их создания не требуется установка полной операционной системы.
- Переносимость - Контейнеры могут работать практически на любой платформе, где установлен соответствующий движок контейнеризации, например, Docker.
- Экономия ресурсов - Поскольку контейнеры используют одно и то же ядро операционной системы, они занимают меньше места и потребляют меньше ресурсов по сравнению с виртуальными машинами.
- Упрощение разработки и тестирования - Разработчики могут создавать контейнеры, содержащие все необходимые зависимости, что значительно облегчает процесс тестирования и развертывания кода.
Недостатки контейнеризации
- Ограниченная изоляция - Поскольку контейнеры используют общее ядро хоста, они обладают меньшей степенью изоляции по сравнению с виртуальными машинами. Это может представлять угрозу безопасности в случае сбоя одного из контейнеров.
- Совместимость с операционными системами - Контейнеры имеют ограниченную совместимость с различными операционными системами, поскольку они работают на одном общем ядре.
Виртуализация
Виртуализация — это процесс создания виртуальных машин (VM), то есть на одном физическом компьютере можно запустить несколько виртуальных, каждая из которых имеет свою собственную копию операционной системы. Эти виртуальные машины функционируют на основе гипервизора — программы, отвечающей за создание и управление виртуальными машинами. Гипервизор распределяет ресурсы физической машины между различными виртуальными машинами.
Вот несколько примеров технологий виртуализации:
- VMware ESXi: Одна из самых популярных платформ для виртуализации серверов в больших компаниях.
- VirtualBox: Бесплатный инструмент для создания и запуска виртуальных машин на локальном компьютере.
Преимущества виртуализации
- Полная изоляция - Каждая виртуальная машина функционирует под управлением собственной копии операционной системы, что обеспечивает надежную защиту приложений и данных.
- Безопасность - Благодаря полной изоляции, сбой или атака на одну виртуальную машину не затронет остальные.
- Поддержка различных операционных систем - Виртуальные машины дают возможность одновременно запускать различные операционные системы на одном физическом оборудовании, что открывает новые горизонты для использования и управления.
- Управление ресурсами - Гипервизоры обеспечивают гибкое управление ресурсами, позволяя динамически распределять процессорное время, память и дисковое пространство между виртуальными машинами, что дает возможность максимально эффективно использовать ресурсы.
Недостатки виртуализации
- Высокая нагрузка на ресурсы - Каждая виртуальная машина требует значительного объёма памяти и процессорных мощностей, поскольку содержит полную копию операционной системы.
- Медленное развёртывание - Процесс создания новой виртуальной машины занимает больше времени по сравнению с контейнерами.
- Сложное масштабирование - Масштабирование виртуальных машин связано с дополнительными затратами ресурсов и времени, особенно когда требуется создать несколько копий одной и той же виртуальной машины.
Запуск нескольких контейнеров вместе
Compose — это инструмент, который позволяет легко создавать и запускать многоконтейнерные приложения. Он работает на основе файла compose.yml
, в котором описывается, какие контейнеры будут запущены, а также их переменные среды, сети и тома.
Compose упрощает запуск и тестирование нескольких контейнеров одновременно. Например, если мы создаем проект интернет-магазина, нам понадобятся два контейнера, которые будут взаимодействовать друг с другом. Удобнее всего управлять ими и запускать их вместе с помощью Compose.
- Первый контейнер — это веб-сайт (приложение которое принимает и отвечает на HTTP запросы), который должен иметь возможность обращаться к базе данных для отображения информации из нее в виде HTML-страниц.
- Второй контейнер — это база данных (приложение которое записывает данные на диск особенным образом) товаров и учетных записей пользователей.
Теоретические вопросы
- В чем ключевые различия между виртуализацией и контейнеризацией?
- Как Docker обеспечивает изоляцию контейнеров?
- Сохраняются ли данные, которые хранились в контейнере, после его остановки?
- Зачем нужны тома (volumes) в docker?
- Где располагаются тома (volumes), создаваемые Docker?
- Что такое логи и где хранятся логи для dokcer приложений?
- Каким образом формируется образ для контейнера?
- Как происходит создание контейнера?
- В чем заключается разница между образом и контейнером?
- Приведите пример простого Dockerfile.
- Объясните, как создаются слои в Dockerfile?
- Какие основные инструкции есть для создания слоев в Dockerfile?
- При создании нового слоя, что происходит?
- В чем разница между
ENTRYPOINT
и CMD
?
- Возможно ли использовать
ENTRYPOINT
и CMD
одновременно?
- Почему не рекомендуется всегда использовать только
latest
версию образа?
- Как остановить запущенный контейнер, но не уничтожить его?
- Допустимо ли запускать несколько контейнеров на одной виртуальной машине?
- Какой командой можно просмотреть все образы Docker, скачанные на вашу машину?
- Какой командой выгрузить ваш образ в registry?
- Какие основные типы сетей поддерживает docker?
- Чем лучше сборка через kaniko чем через docker?
- Чем отличается базовый образ alpine от ubuntu?
- В чем отличия между
COPY
и ADD
?
- Можно ли в docker compose ограничить использование RAM и CPU для отдельных контейнеров?
- Как настроить контейнер так чтобы он перезапускался сам если приложение внутри сломается?
- Как сделать также в docker compose?
Первое задание
- Проверьте, установлен ли у вас Docker или Docker Desktop.
- Скачайте образ
nginx
локально.
- Определите тег (версию) скачанного вами образа nginx.
- Как скачать версию образа, отличную от
latest
?
- Запустите Nginx, используя образ с тегом, отличным от
latest
.
- Какой порт занимает nginx внутри запущенного контейнера?
- Как запустить контейнер таким образом, чтобы порт был доступен не только в изолированной среде?
- Запустите контейнер nginx с прокинутым портом и откройте в браузере адрес localhost:80
- Вы должны увидеть приветствие от Nginx.
- Как выглядит файл
compose.yml
?
- Какие основные поля в
compose.yml
?
Второе задание
- Создайте свой Dockerfile, используя в качестве основы образ nginx.
- Добавьте свою HTML-страницу вместо стандартного приветствия.
- Найдите в контейнере расположение базовой страницы.
- На основе базовой страницы создайте свою собственную (в той же директории, где и Dockerfile).
- В Dockerfile добавьте инструкцию, которая заменит базовую страницу на нашу.
- Соберите образ (image), выдав ему название
devops
с тегом 1.0
- Запустите контейнер с нашим новым образом.
- Убедитесь, что главная страница была изменена на вашу.
Третье задание
- Используя образ, созданный во втором задании, создайте файл
compose.yml
.
- Найдите и добавьте в compose еще один контейнер, который будет отправлять HTTP GET запросы к вашему nginx.
- Запустите ваш docker compose.
- Просмотрите логи compose и обратите внимание на вывод nginx.
- Завершите работу docker compose.