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

Главное и принципиальное отличие контейнера от ВМ в том, что он использует ресурсы и ядро хостовой ОС. Несколько контейнеров, размещённых на одном сервере, используют ресурсы сервера совместно, тем самым экономя их.

Так же, как и ВМ, контейнер изолирован от других контейнеров и хостовой ОС. Он может содержать различные приложения и запускаться на различных платформах.

Хорошей практикой считается принцип «один контейнер — один сервис». Так проще обновлять приложения и создавать резервные копии. Например, если вы написали для веб-сервера NGINX веб-приложение на Python, поместите сервер и приложение в отдельные контейнеры.

Слоистая архитектура контейнеров

Говоря о контейнерах, часто употребляют термин слой. Любое изменение окружения — установка программы, создание директории — создаёт новый слой. Эти слои накладываются друг на друга.

Если на одном сервере оказываются несколько контейнеров с общими слоями (например, библиотеками), то слои не дублируются: они устанавливаются один раз и затем используются совместно.

Преимущества контейнеров

С контейнерами разработка стала эффективнее и проще. Чем же они хороши?

  • Экономия ресурсов. Во-первых, контейнеры занимают меньший объём, чем ВМ: они не содержат отдельных копий ОС и дополнительных программ и утилит. Во-вторых, благодаря общим слоям контейнеры оптимизируют использование ресурсов хоста.
  • Независимость. Контейнер самодостаточен. Всё, что нужно для работы (библиотеки, настройки, среда запуска), находится внутри.
  • Переносимость. Контейнер независим. Платформа, на которой его запускают, неважна: он везде будет работать одинаково. Можно спокойно переносить контейнер с одной платформы на другую.
  • Скорость разворачивания контейнеров и работы в них. Это преимущество следует из предыдущих. Сервер не тратит время на эмуляцию гостевой ОС, а высвободившиеся ресурсы можно направить на увеличение производительности приложений и сервисов.
  • Тиражирование и масштабирование. Собрали контейнер однажды — копируйте его сколько угодно раз. Запускайте одновременно нужное количество копий контейнера. Всё будет работать одинаково.
  • Оркестрация. Дирижёр одновременно управляет множеством музыкантов, играющих на разных инструментах. Вы можете создавать похожие системы из контейнеров, каждый из которых выполняет узкую задачу. Оркестрация — это управление такими системами, т. е. координация работы множества контейнеров.

Docker

Как и виртуальные машины, контейнеры создаются из образов. На сегодняшний день самая популярная и удобная платформа для создания и запуска образов — Docker.

Docker работает так. Предположим, вы с коллегами разработали приложение. Вы упаковываете его со всеми зависимостями — библиотеками, интерпретаторами, файлами и т. д. — в Docker-образ и отправляете в репозиторий (т. е. в хранилище). Чтобы развернуть приложение, нужно скачать из репозитория образ и создать из него контейнер на рабочем сервере.

Хранилища Docker-образов бывают публичные и приватные. Самое известное публичное хранилище — это Docker Hub. Однако если вы работаете с Yandex Cloud, лучше использовать собственное хранилище облака — Yandex Container Registry. О нём и его плюсах мы поговорим на следующем уроке.

Как создаются образы

Docker-образы создаются с помощью инструкций, таких как запуск команды, добавление файла или директории, создание переменной окружения. Инструкции хранятся в Dockerfile — это обычный текстовый файл, который можно редактировать в любом текстовом редакторе (что соответствует принципам Infrastructure as Code).

Вот простой пример Dockerfile для образа, в котором есть только ОС Ubuntu и веб-сервер NGINX:

FROM ubuntu:latest
RUN apt-get update -y
RUN apt-get install -y nginx
ENTRYPOINT ["nginx", "-g", "daemon off;"]

Каждая инструкция создаёт новый слой образа, и эти слои накладываются друг на друга. В конце вы задаёте команду — исполняемый файл, который будет запущен при старте Docker-контейнера.

В примере выше первая строка определяет исходный образ (публичный образ с последней версией Ubuntu), на основе которого мы строим свой.

Вторая и третья строки устанавливают веб-сервер NGINX.

Последняя строка задаёт точку входа — запускает NGINX.

Процесс создания образа — это считывание и выполнение инструкций из Dockerfile. Чтобы создать образ из Dockerfile, используется команда build. Если файл со спецификацией называется стандартно (Dockerfile), не указывайте название. Если иначе — напишите название после ключа -f. После ключа -t указывается имя образа, который будет создан:

docker image build -f my-dockerfile -t my-image .

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

Как создаются контейнеры из образов

Для работы с хранилищем используются традиционные команды push и pull. Так мы помещаем образ в хранилище:

docker push my-image

Чтобы создать контейнер, загрузите из хранилища образ и запустите его:

docker pull my-image
docker run my-image

При создании контейнера из образа можно использовать параметры (флаги). Например, чтобы ограничить ресурсы памяти и процессора, загрузить свежую версию образа, передать значения переменных. Смотрите доступные флаги с помощью традиционного ключа --help.


📂 YandexCloud | Последнее изменение: 15.08.2024 11:54