Виртуальные машины эмулируют аппаратное обеспечение на котором выполняется гостевая операционная система с целевым приложением. Виртуальные машины отлично подходят для изоляции приложения. Но за такую изоляцию приходится платить большими накладными расходами на создание виртуальной среды.
Контейнеры вместо эмуляции аппаратного обеспечения эмулирует операционную систему, делая контейнеры более легковесными. Ключом для этого типа эмуляции является правильное согласование таких механизмов Linux, как: контрольные группу (cgroups), пространства имён (kernel namespaces), union-capable файловых систем, netfilter. В отличие от виртуальных машин, контейнеры не создают больших накладных расходов, что позволяет использовать систему и ресурсы эффективнее.
Контейнер представляет собой изолированную группу процессов, которые ограничены частной корневой файловой системой и пространством имён процессов. Содержащиеся процессы совместно используют ядро и другие службы хост-системы, но по умолчанию они не могут получить доступ к файлам или системным ресурсам за пределами своего контейнера.
Ключевое преимущество контейнеров заключается в том, что он позволяет пользователям упаковать приложение со всеми его зависимостями в стандартизированный образ, который легко распространять. Любой хост с совместимой средой выполнения может создать контейнер, используя образ в качестве шаблона. Десятки или сотни контейнеров могу работать одновременно без конфликтов.
## Что такое Docker?
Docker это самый известный инструмент, который позволяет разработчикам, системными администраторам и другим специалистам разворачивать приложения в песочнице (контейнерах).
Namespaces - технология ядра Linux, разработанная в достаточно далёком 2002 году. Docker использует namespaces, такие как PID (Process ID), Network и Mount, для создания изолированных пространств имён. Пространства имён изолируют контейнерные процессы с точки зрения нескольких функций операционной системы, включая монтирование файловой системы, управление процессами и сетевое взаимодействие.
Например, с использованием PID namespaces каждый контейнер видит только свои процессы, что обеспечивает изоляцию процессов между контейнерами. Пространство имён команды `mount` отображает процессы с помощью индивидуального представления иерархии файловой системы. Это аналогично системному вызову `chroot`, который необратимо устанавливает видимый процессу корневой каталог и тем самым отключает доступ к файлам и каталогам хоста, расположенным выше уровня `chroot`.
Cgroups (Control Groups) - технология, разработанная внутри компании Google еще в 2006 году. Контрольные группы ограничивают использование системных ресурсов и определяют приоритетность одних процессов над другими. Контрольные группы препятствуют процессам контейнеров, выходящим из под контроля, использовать всю память и всё доступное время процессора. Это позволяет предотвратить «голодание» ресурсов и обеспечить справедливое распределение мощностей между контейнерами.
Docker использует «слоистые» файловые системы, такие как AUFS, OverlayFS и Overlay2, чтобы создавать легковесные и эффективные образы контейнеров. Это возможно благодаря тому, что они разделяют общие файлы между собой, экономя дисковое пространство.
#### 1.4. Функциональные возможности (Capabilities)
Функциональные возможности позволяют процессам выполнять определённые чувствительные операции с ядром и системные вызовы. Например, процесс может иметь возможность изменять права собственности на файл или устанавливать системное время.
Ядро Linux предоставляет разные возможности (capabilities) для выполнения привилегированных действий. Docker позволяет настраивать набор возможностей, доступных контейнеру, для более тонкой настройки безопасности.
#### 1.5. Режим защищённых вычислений (Seccomp)
Для повышения безопасности Docker может использовать Seccomp. Он ограничивает доступ контейнера к системным вызовам, что позволяет уменьшить поверхность атаки и предотвратить выполнение опасных операций. Он обеспечивает более детальный контроль, чем функциональные возможности.
- встроенные в ядро программные L2 свичи `Linux Bridges`,
- механизмы сетевого экрана `netfilter` NAT (преобразование сетевых адресов) и Port Forwarding (проброс портов),
- опционально правила SELinux/AppArmor.
По умолчанию для подключения контейнеров к сети используется сетевое пространство имён и программный L2 свич внутри хоста. В этой конфигурации контейнеры имеют частные IP адреса, недоступные за пределами хоста. При этом хост играет роль маршрутизатора с NAT, используя `netfilter` правила, даёт возможность выхода контейнеров в интернет и позволяет пробрасывать порты для доступа к контейнеризованным приложениям.
Существуют другие режимы работы контейнеров с сетью:
- неограниченный доступ к сетевому стеку хоста машины,
- Open vSwitch,
- проекты сообщества Pipework, Clocker,
- официальный проект Docker команды по стандартизации сетевого взаимодействия контейнеров `libnetwork`.
Образ - это шаблон для будущих контейнеров. Образы контейнеров представляют из себя многоуровневые файловые системы. Структура каталога и расположение бинарных файлов, библиотек, конфигурационных файлов соответствуют стандартным спецификациям иерархии файловой системы Linux. Для использования в качестве основы для образов контейнеров были разработаны специализированные дистрибутивы Linux.
В Docker используется многоуровневая файловая система `UnionFS`. При старте контейнера слои образа объединяются и монтируются только на чтение, с добавлением слоя монтируемого для чтения и записи. Процессы контейнера в ходе своей работы изменяют имеет этот последний слой, оставляя содержимое слоёв образа нетронутым. Это свойство позволяет эффективно хранить контейнеры на основе одного и того же образа и сокращает их время запуска.
Реестр - индекс образов, к которому `dockerd` может получить доступ и скачать образ запускаемого контейнера. Реестр позволяет разработчикам производить доставку своих приложений до пользователей.
Docker Hub - это общедоступная служба реестра, поддерживаемая компанией Docker, Inc. В ней содержатся образы многих дистрибутивов, которые вы можете взять в качестве основы для своего образа, и проектов с открытым исходным кодом.
В вашей компании вы можете поднять собственный реестр на основе одной из общедоступных реализаций реестров, в том числе поставляемых в виде докер образа. При выборе образа реестра для производственной среды нужно учесть ряд требований к хранилищу данных, к аутентификации и авторизации, и к требованиям выдвигаемым другими задачам обслуживания.
Все эти возможности, кроме обеспечения персистентности при хранении данных, также обеспечивают более высокую производительность при записи в файловую систему контейнера, по сравнению с верхним слоем `UnionFS`, доступным на запись и чтение.