Контейнерная среда разработки многокомпонентных веб-приложений пришла на смену платформам, построенным на основе виртуальных машин. Её применение позволяет избежать многих проблем, связанных с совместным использованием машинных ресурсов и их экономией. Одной из наиболее распространённых платформ такого типа является система Docker, обеспечивающая наличие полноценной контейнерной среды, пригодной для разработки и тестирования многокомпонентных распределённых приложений. Рассмотрим вопросы, связанные с установкой программы на сервере Ubuntu, и продемонстрируем некоторые из её возможностей на практике.
Способы построения программной среды для работы веб-приложений
Для работы почтовых и веб-серверов, сайтов и любых других интернет-ресурсов требуется наличие подготовленной программной среды, имеющей определённые характеристики. Со временем выделились три основных направления построения такой среды:
- Традиционная среда, основанная на непосредственном использовании физических ресурсов компьютера;
- Виртуальные машины;
- Контейнерные среды.
Основным недостатком использования традиционной среды является её большая ресурсоёмкость и, соответственно, затратность, ограничивающая возможности её широкого применения в связи с постоянно растущими ресурсными требованиями программного обеспечения.
Виртуализация программной среды позволила на какое-то время снять проблему нехватки ресурсов, что, например, отразилось в появлении множества типов виртуальных серверов на хостинг-площадках. VPS-сервера во многом способны конкурировать с физическими серверами при минимальном уровне используемых ресурсов.
Контейнерные среды появились как ответ на постоянно растущие запросы касательно эффективности использования физических ресурсов компьютера при разработке многокомпонентных распределённых веб-приложений. В отличие от виртуальных машин, виртуализация среды здесь реализуется на уровне операционной системы (ОС), а не физических ресурсов компьютера. Причём контейнеры являются более «легковесными» и «гибкими» в контексте использования общих ресурсов операционной системы. В результате стало возможным получить в пределах одной физической машины или VPS-сервера большее количество «независимых» сред функционирования и / или разработки многокомпонентных веб-приложений.
На Рисунке 1. представлены рассматриваемые нами варианты организации программной среды: традиционная (Traditional Deployment), виртуальная (Virtualized Deployment) и контейнерная (Container Deployment).
Рисунок 1. Виды программных сред исполнения веб-приложений.
Программный инструмент Docker
На рынке программного обеспечения присутствует множество средств создания контейнерных сред исполнения приложений, однако далеко не все из них отвечают требованиям Международного стандарта OCI (Open Container Initiative). Он определяет формальные правила реализации виртуальной среды на уровне операционной системы, которые описаны в двух спецификациях. Одна из спецификаций формализует правила создания и использования общей контейнерной среды Container Runtime (см. Рисунок 1), а другая определяет правила работы с образами (image) – создание, обработка и т. д.
Контейнеры заменяют собой виртуальные машины, имея свою собственную среду исполнения, ресурсы и возможности настройки параметров конфигурации. Их активация в Docker происходит сразу же после запуска специального шаблона или образа, который предварительно должен быть загружен из репозитория или создан локально с помощью специальной команды.
Платформа Docker отвечает всем требованиям стандарта OCI и может быть использована для работы в среде большинства известных OC – Windows, MacOS, Linux и др. Программа выпускается в двух исполнениях – для коммерческого использования (Enterprise) и «свободная» версия (CE), которая стала довольно популярной на платформах хостинг-провайдеров. Мы здесь будем использовать именно эту версию программы как наиболее доступную.
Практическое использование CE Docker
Процесс ознакомления с программой разобьём на несколько этапов, что позволит сконцентрироваться на каждом из направлений. Это такие этапы:
- Подготовка программной среды Ubuntu для установки Docker;
- Установка и развёртывание;
- Ознакомление со встроенной системой поддержки пользователя;
- Работа с контейнерами.
Осуществим последовательное выполнение каждого из этапов.
Подготовка программной среды Ubuntu для установки Docker
Для начала обновим индекс пакетов нашей системы из репозитория Ubuntu. Для этого введём следующую команду в командной строке терминала:
$ sudo apt update
Как видим, может быть обновлён 51 пакет. Инициируем эту процедуру с помощью следующей команды:
$ apt list –upgradable
Обновление пакетов прошло успешно.
Теперь установим программные пакеты, необходимые для обеспечения беспрепятственной работы протокола, управляющего загрузками по сети. Для этого введём в терминале:
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
Пакеты успешно установлены.
Загрузим программный ключ из Docker-репозитория:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –
В результате ключ был загружен на наш сервер, о чём говорит выход команды (OK).
Для возможности осуществлять загрузки из Docker-репозитория необходимо добавить его в список допустимых источников данных для нашего apt-протокола. Это можно сделать с помощью следующей команды:
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
Список сформирован. Теперь можно приступать к установке программы.
Установка и развёртывание
Инициируем процесс развёртывания Docker CE с помощью следующей команды:
sudo apt install docker-ce
Подтверждаем своё согласие на продолжение установки с помощью символа Y (Yes).
Итоговое окно результатов выполнения команды представлено ниже.
Можно убедиться, что программа была успешно установлена в системе.
Проверим её статус. Для этого введём в терминале:
$ sudo systemctl status docker
Выход команды:
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2024-02-02 17:44:37 UTC; 1 week 6 days ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 779607 (dockerd)
Tasks: 16
Memory: 33.3M
CPU: 4min 13.066s
CGroup: /system.slice/docker.service
└─779607 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Результаты говорят о том, что Docker-машина (контейнерная среда) создана; даемон сервиса запущен (active); PID процесса: 779607.
Теперь контейнерная среда готова к работе.
Ознакомление со встроенной системой поддержки пользователя
Как и любая другая программная система, Docker предоставляет ряд встроенных средств, необходимых для его освоения. Воспользуемся ими.
Для начала выведем список всех доступных пользователю команд управления контейнерной средой и Docker-образами. Для этого введём в командной строке терминала:
$ docker
Опишем наиболее важные из общих Docker-команд:
run – Создание и запуск контейнера из имеющегося образа;
exec – Запуск на выполнение команд в активном контейнере;
ps – Вывод списка активных контейнеров;
build – Создание образа из Docker-файла;
pull – Загрузка образа из репозитория;
images – Вывод списка имеющихся в системе образов.
Каждая из указанных команд имеет свои параметры, использующиеся для её запуска. Просмотрим, например, параметры общей команды build. Это можно сделать с помощью следующей управляющей конструкции:
$ docker build --help
Как видим, команда имеет множество опций для использования в том или ином случае.
Для получения полного набора данных по созданной программной среде можно воспользоваться следующей командой:
$ docker info
Вывод команды:
Client: Docker Engine - Community
Version: 25.0.2
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.12.1
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.24.5
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 25.0.2
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Как видим, информация о программной среде разделена на две части – клиентскую и серверную. В клиентской части указана версия Docker-машины, режим работы, список установленных плагинов, их версии и размещение.
В серверной части, в частности, содержатся данные о контейнерах, образах, типе файловой системы и установленных для неё драйверов.
Всё это даёт полную картину конфигурации программной среды.
Работа с контейнерами в Docker-среде
Для возможности активации контейнера необходимо наличие его образа, который может быть загружен из общедоступного репозитория или создан с помощью специальной команды. Рассмотрим первый способ.
Предположим, нам необходим контейнер, содержащий интерпретатор языка Python для работы с Python-приложениями. Для начала просмотрим имеющиеся образы Python в общедоступном репозитории:
$ docker search python
Можно убедиться, что в репозитории имеется множество образов, связанных с этим языком. Три из них являются официальными: python, pypy и hylang. Для нас наиболее подходит образ с именем python. Загрузим его на наш сервер. Это можно сделать с помощью следующей команды:
$ docker pull python
Теперь этот образ находится на нашем сервере. Проверим это, а заодно узнаем о наличии других образов.
Введём в терминале:
$ docker images
Вывод команды:
DESCRIPTION | TAG | IMAGE ID | CREATED | SIZE |
python | latest | a3aef63c6c10 | 9 days ago | 1.02GB |
gcr.io/k8s-minikube/kicbase | v0.0.42 | dbc648475405 | 3 months ago | 1.2GB |
Как видим, на нашем сервере имеется два образа, один из которых мы только что загрузили. Команда вывела их атрибуты: название, тег, идентификатор, время создания и размер. Идентификатор позволит нам в дальнейшем управлять контейнером.
Активируем контейнер на базе python-образа. Это можно сделать с помощью следующей управляющей конструкции:
$ docker run -it python
Параметр –it позволяет включить интерактивный режим работы с создаваемым контейнером.
В результате мы получили доступ к интерпретатору языка Python, где мы можем беспрепятственно вводить нужные команды.
Например, введём в командной строке команду для перехода в интерактивную справку Python:
>>> help ()
Нажимаем комбинацию клавиш ctrl+C и возвращаемся в режим интерпретатора, как показано ниже:
Вернемся в командную строку терминала:
>>> exit()
В процессе работы в контейнерной среде может накапливаться множество разных контейнеров. Существует соответствующая команда, чтобы узнать их статус на данный момент времени. Воспользуемся ею для определения статуса нашего контейнера:
$ docker ps -a
Мы видим, что в списке присутствует наш контейнер со статусом Exited (0). Это означает, что он неактивен. Обращаем внимание на наличие двух идентификаторов – цифрового (9b91b4cb047e) и символьного (eager_morse), с помощью которых мы сможем впоследствии управлять нашим ресурсом.
Для вывода только активных контейнеров существует следующая управляющая конструкция:
$ docker ps
Результат очевиден – список пуст.
Однако, зная идентификаторы, мы можем вновь запустить контейнер. Введём в терминале:
$ docker start 9b91b4cb047e
Опять проверим список активных ресурсов:
$ docker ps
Можно убедиться, что список уже не пуст и наш ресурс имеет активный статус.
Остановим его, воспользовавшись для идентификации символьным именем:
$ docker stop eager_morse
Опять проверим активные ресурсы:
$ docker ps
Мы видим, что список опять пуст, что означает, что тип используемого в команде идентификатора не имеет значения.
Теперь создадим новый образ на основе условно модифицированного нами контейнера python.
Для этого введём в терминале:
$ docker commit -m "Modify Python " -a "Admin" 9b91b4cb047e new_python
Здесь new_python – произвольное имя создаваемого образа, Admin – имя пользователя.
Просмотрим список образов, зарегистрированных в системе:
$ docker images
Как видно, в списке появился новый шаблон, которого не было ранее. Его имя new_python, как и следовало ожидать.
Рассмотренные нами возможности Docker-среды являются более, чем скромными. На самом деле эти возможности гораздо шире и позволяют проводить сколь угодно сложные манипуляции с объектами виртуальной среды, но их рассмотрение выходит за рамки этой статьи.