This article discusses virtual machines and docker, their architecture and distinctive capabilities.
Keywords: virtual machines, containers, docker, LXC, UnionFS
Что такое «контейнеры» и «виртуальные машины»?
Контейнеры и виртуальные машины схожи по своей цели: изолировать приложение и его зависимости в самостоятельный блок, который можно запускать где угодно.
Более того, и контейнеры и виртуальные машины избавляют от привязки к конкретному физическому оборудованию, что позволяет более эффективно использовать вычислительные ресурсы с точки зрения потребления энергии и экономической эффективности.
Основное различие между контейнерами и виртуальными машинами — в их архитектурном подходе.
Виртуальные машины
Виртуальная машина —программная и/или аппаратная система, эмулирующая аппаратное обеспечение некоторой целевой гостевой и исполняющая программы для гостевой платформы на платформе-хозяине или виртуализирующая некоторую платформу и создающая на ней среды, изолирующие друг от друга программы и даже операционные системы. Виртуальные машины запускают на физических машинах, используя «гипервизор».
Гипервизор представляет собой часть программного или аппаратного обеспечения, обеспечивающую или позволяющую одновременное, параллельное выполнение нескольких операционных систем на одном и том же физическом компьютере, называемом «хост-компьютером» или «хостом». Хост предоставляет виртуальным машинам вычислительные ресурсы, легко распределяемые между ними. Так что, если одна виртуальная машина выполняет запуск более ресурсоемких приложений, вы можете выделить ей больше вычислительных возможностей, чем другим машинам, работающим на том же хосте.
Рис. 1. Архитектура виртуальной машины
Виртуальную машину, запускаемую на хосте, также часто называют «гостевой машиной». Гостевая машина содержат как приложение, так и все, что нужно для его запуска (например, системные исполняемые файлы и библиотеки). Она также несет в себе весь аппаратный стек, включая виртуальные сетевые адаптеры, файловое хранилище и центральный процессор, и свою собственную полноценную гостевую операционную систему. С внутренней стороны, гостевая машина ведет себя как свой собственный блок со своими собственными выделенными ресурсами. С внешней стороны, мы знаем, что это виртуальная машина, использующая общие ресурсы, предоставленные хостом.
Контейнеры
В отличие от виртуальной машины, обеспечивающей аппаратную виртуализацию, контейнер обеспечивает виртуализацию на уровне операционной системы с помощью абстрагирования «пользовательского пространства».
В целом, контейнеры выглядят как виртуальные машины. Например, у них есть изолированное пространство для запуска приложений, они позволяют выполнять команды с правами суперпользователя (root), имеют частный сетевой интерфейс и IP-адрес, пользовательские маршруты и правила межсетевого экрана и т. д.
Одна большая разница между контейнерами и виртуальными машинами в том, что контейнеры разделяют ядро хоста с другими контейнерами.
Рис. 2. Архитектура контейнера
На рисунке 2 видно, что контейнеры упаковывают только пользовательское пространство, а не ядро или виртуальную аппаратуру, как это делают виртуальные машины. Каждый контейнер получает свое собственное изолированное пользовательское пространство для обеспечения возможности запуска нескольких контейнеров на одном хосте. Архитектура уровня операционной системы разделяется между контейнерами, именно поэтому контейнеры настолько легковесны.
Docker
Docker — программное обеспечение для автоматизации развёртывания и управления приложениями в среде виртуализации на уровне операционной системы, например LXC. Позволяет «упаковать» приложение со всем его окружением и зависимостями в контейнер, который может быть перенесён на любую Linux-систему с поддержкой cgroups в ядре, а также предоставляет среду по управлению контейнерами.
Основные преимущества Docker
- Простота использования. Основанная на контейнерах docker платформа позволят легко портировать полезную нагрузку. Docker контейнеры могут работать как на реальной локальной машине или машине в датацентре, так и на виртуальной машине в облаке. Портируемость и легковесная природа docker позволяет легко динамически управлять нагрузкой. Можно использовать docker, чтобы развернуть или погасить ваше приложение или сервисы. Скорость docker позволяет делать это почти в режиме реального времени.
- Скорость работы. Docker-контейнеры легковесны и быстры. Можно создать и запустить Docker-контейнер за секунды, в отличии от виртуальных машин, каждый раз запускающих полноценную виртуальную ОС.
- Модульность имасштабируемость. Docker позволяет легко разделять функциональность приложения в отдельные контейнеры. Например, можно запускать базу данных Postgres в одном контейнере, хранилище Redis в другом, в то время как приложение Node.js находится в третьем. Это позволит легко масштабировать и обновлять компоненты приложения независимо друг от друга.
Архитектура Docker
Docker использует архитектуру клиент-сервер. Docker-клиент общается с демоном Docker, который берет на себя тяжесть создания, запуска, распределения контейнеров. И клиент и сервер могут работать на одной системе, можно подключить клиент к удаленному демону docker. Клиент и сервер общаются через сокет или через RESTful API.
Docker-демон
Как показано на рисунке 3, демон запускается на хосте. Пользователь не взаимодействует с сервером напрямую, а использует для этого Docker-клиент.
Docker-клиент
Docker-клиент, программа docker — главный интерфейс к Docker. Она получает команды от пользователя и взаимодействует с docker-демоном.
Рис. 3. Архитектура Docker
Чтобы понимать из чего состоит docker нужно знать о трех его компонентах:
‒ образы (images);
‒ реестр (registries);
‒ контейнеры.
Образы
Docker-образ — это read-only шаблон. Например, образ может содержать операционную систему Ubuntu c веб-сервером Nginx и приложением на ней. Образы используются для создания контейнеров. Docker позволяет легко создавать новые образы и обновлять существующие.
Каждый образ состоит из набора уровней. Docker использует UnionFile System для сочетания этих уровней в один образ. Union File System позволяет файлам и директориями из разных файловых систем (разным ветвям) прозрачно накладываться, создавая когерентную файловую систему.
Одна из причин, по которой docker легковесен — это использование таких уровней. При изменении образа (например, при обновлении приложения) создается новый уровень. Так, без замены всего образа или его пересборки (как это пришлось бы сделать с виртуальной машиной) происходит лишь добавление или удаление нужных уровней. Это также позволяет распространять образы проще и быстрее.
В основе каждого образа находится базовый образ. Например, ubuntu, базовый образ Ubuntu, или debian, базовый образ дистрибутива Debian.
Docker образы могут создаться из базовых образов, шаги описания для создания этих образов называются «инструкциями». Каждая инструкция создает новый образ или уровень. Инструкциями будут следующие действия:
‒ запуск команды;
‒ добавление файла или директории;
‒ создание переменной окружения;
‒ указания что запускать, когда запускается контейнер этого образа.
Эти инструкции хранятся в файле Dockerfile. Docker считывает Dockerfile при сборке образа, выполняет эти инструкции и возвращает конечный образ.
Реестр
Docker-реестр хранит образы. Есть публичные и приватные реестры, из которых можно скачать либо загрузить образы. Существует публичный Docker-реестр с огромной коллекцией контейнеров — Docker Hub.
Контейнеры
Контейнеры похожи на директории. В контейнерах содержится все, что нужно для работы приложения. Каждый контейнер создается из образа. Контейнеры могут быть созданы, запущены, остановлены, перенесены или удалены. Каждый контейнер изолирован и является безопасной платформой для приложения.
Используемые технологии
Докер написан на языке Go и использует некоторые возможности ядра Linux, чтобы реализовать приведенный выше функционал.
Пространства имен
Docker использует технологию «namespaces» для организации изолированных рабочих пространств, которые называются контейнерами. При запуске контейнера docker создает набор пространств имен для данного контейнера. Это создает изолированный уровень, каждый аспект контейнера запущен в своем пространстве имен и не имеет доступ к внешней системе.
Существует несколько типов пространств имен, которые использует docker:
‒ pid: для изоляции процесса;
‒ net: для управления сетевыми интерфейсами;
‒ ipc: для управления IPC ресурсами;
‒ mnt: для управления точками монтирования;
‒ utc: для изолирования ядра и контроля генерации версий.
Контрольные группы
Docker также использует технологию «cgroups» или контрольные группы. Ключ к работе приложения в изоляции — предоставление приложению только тех ресурсов, которые ему нужны для правильного функционирования. Это гарантирует, что контейнеры будут хорошими соседями. Контрольные группы позволяют разделять доступные ресурсы железа и если необходимо, устанавливать пределы и ограничения. Например, ограничить возможное количество памяти контейнеру.
Файловая система UnionFS
Union File System или UnionFS — вспомогательная файловая система для Linux и FreeBSD, производящая каскадно-объединённое монтирование других файловых систем. Это позволяет файлам и каталогам изолированных файловых систем, известных как ветви, прозрачно перекрываться, формируя единую связанную файловую систему. Каталоги, которые имеют тот же путь в объединённых ветвях, будет совместно отображать содержимое в объединённом каталоге новой виртуальной файловой системы. Docker использует UnionFS для создания блоков, из которых строится контейнер. Docker может использовать несколько реализаций UnionFS, включая: AUFS, btrfs, vfs и DeviceMapper.
Литература:
- Wikipedia. «Virtual Machine». URI: https://wikipedia.org/wiki/Virtual_machine (дата обращения: 18.09.2016)
- Wikipedia. «Hypervisor». URI: https://wikipedia.org/wiki/Hypervisor (дата обращения: 18.09.2016)
- Mendel Rosenblum, Standford University and VMWare. «The Reincarnation of Virtual Machines». URI: http://queue.acm.org/detail.cfm?id=1017000 (дата обращения: 18.09.2016)
- LXC documentation. URI: https://linuxcontainers.org/lxc/documentation/ (датаобращения: 18.09.2016)
- Chenxi Wan. «Containers 101: Linux containers and Docker explained». URI: http://www.infoworld.com/article/3072929/linux/containers-101-linux-containers-and-docker-explained.html (дата обращения: 18.09.2016)
- Docker documentation. «Docker Overview». URI: https://docs.docker.com/engine/understanding-docker/ (дата обращения: 18.09.2016)
- Docker documentation. «Docker run reference». URI: https://docs.docker.com/engine/reference/run/ (дата обращения: 18.09.2016)
- Unionfs documentation. «Unionfs: A Stackable Unification File System». URI: https://www.filesystems.org/project-unionfs.html (дата обращения: 18.09.2016)