# Базовые термины

## Что такое контейнеры?

Виртуальные машины эмулируют аппаратное обеспечение на котором выполняется гостевая операционная система с целевым приложением. Виртуальные машины отлично подходят для изоляции приложения. Но за такую изоляцию приходится платить большими накладными расходами на создание виртуальной среды.

Контейнеры вместо эмуляции аппаратного обеспечения эмулирует операционную систему, делая контейнеры более легковесными. Ключом для этого типа эмуляции является правильное согласование таких механизмов Linux, как: контрольные группу (cgroups), пространства имён (kernel namespaces), union-capable файловых систем, netfilter. В отличие от виртуальных машин, контейнеры не создают больших накладных расходов, что позволяет использовать систему и ресурсы эффективнее.

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

Ключевое преимущество контейнеров заключается в том, что он позволяет пользователям упаковать приложение со всеми его зависимостями в стандартизированный образ, который легко распространять. Любой хост с совместимой средой выполнения может создать контейнер, используя образ в качестве шаблона. Десятки или сотни контейнеров могу работать одновременно без конфликтов.

## Что такое Docker?

Docker это самый известный инструмент, который позволяет разработчикам, системными администраторам и другим специалистам разворачивать приложения в песочнице (контейнерах).

## Основные механизмы работы Docker

Как вы уже знаете, в контейнерном механизме используется несколько средств ядра, которые необходимых для изоляции процессов приложений.

### 1. Функции ядра

#### 1.1. Пространства имён

Пространства имён изолируют контейнерные процессы с точки зрения нескольких функций операционной системы, включая монтирование файловой системы, управление процессами и сетевое взаимодействие. 

Например, пространство имён команды `mount` отображает процессы с помощью индивидуального представления иерархии файловой системы. Это аналогично системному вызову `chroot`, который необратимо устанавливает видимый процессу корневой каталог и тем самым отключает доступ к файлам и каталогам хоста, расположенным выше уровня `chroot`.

Контейнеры могут работать на разных уровнях интеграции с операционной системой хоста в зависимости от того, как эти пространства имён были настроены.

#### 1.2. Контрольные группы

Контрольные группы ограничивают использование системных ресурсов и определяют приоритетность одних процессов над другими. Контрольные группы препятствуют процессам контейнеров, выходящим из под контроля, использовать вс. память и всё доступное время процессора.

#### 1.3. Функциональные возможности

Функциональные возможности позволяют процессам выполнять определённые чувствительные операции с ядром и системные вызовы. Например, процесс может иметь возможность изменять права собственности на файл или устанавливать системное время.

#### 1.4. Режим защищённых вычислений

Режим защищённых вычислений ограничивает доступ к защищённым вызовам. Он обеспечивает более детальный контроль, чем функциональные возможности.

### 2. Сеть

Для обеспечение работы по сети используются такие технологии как: 
- встроенные в ядро программные L2 свичи `Linux Bridges`,
- механизмы сетевого экрана `netfilter` NAT (преобразование сетевых адресов) и Port Forwarding (проброс портов),
- опционально правила SELinux/AppArmor.

По умолчанию для подключения контейнеров к сети используется сетевое пространство имён и программный L2 свич внутри хоста. В этой конфигурации контейнеры имеют частные IP адреса, недоступные за пределами хоста. При этом хост играет роль маршрутизатора с NAT, используя `netfilter` правила, даёт возможность выхода контейнеров в интернет и позволяет пробрасывать порты для доступа к контейнеризованным приложениям.

Существуют другие режимы работы контейнеров с сетью:
- неограниченный доступ к сетевому стеку хоста машины,
- Open vSwitch,
- проекты сообщества Pipework, Clocker,
- официальный проект Docker команды по стандартизации сетевого взаимодействия контейнеров `libnetwork`.

### 3. Образы

Образ - это шаблон для будущих контейнеров. Образы контейнеров представляют из себя многоуровневые файловые системы. Структура каталога и расположение бинарных файлов, библиотек, конфигурационных файлов соответствуют стандартным спецификациям иерархии файловой системы Linux. Для использования в качестве основы для образов контейнеров были разработаны специализированные дистрибутивы Linux.

В Docker используется многоуровневая файловая система `UnionFS`. При старте контейнера слои образа объединяются и монтируются только на чтение, с добавлением слоя монтируемого для чтения и записи. Процессы контейнера в ходе своей работы изменяют имеет этот последний слой, оставляя содержимое слоёв образа нетронутым. Это свойство позволяет эффективно хранить контейнеры на основе одного и того же образа и сокращает их время запуска.

### 4. Реестры

Реестр - индекс образов, к которому `dockerd` может получить доступ и скачать образ запускаемого контейнера. Реестр позволяет разработчикам производить доставку своих приложений до пользователей. 

Docker Hub - это общедоступная служба реестра, поддерживаемая компанией Docker, Inc. В ней содержатся образы многих дистрибутивов, которые вы можете взять в качестве основы для своего образа, и проектов с открытым исходным кодом.

В вашей компании вы можете поднять собственный реестр на основе одного из общедоступных образов реестров. При выборе образа реестра для производственной среды нужно учесть ряд требований к хранилищу данных, к аутентификации и авторизации, и к требованиям выдвигаемым другими задача обслуживания.


## Инструменты Docker

### 1. Многоконтейнерные приложения

Docker Compose — это инструмент для запуска многоконтейнерных приложений в Docker, определенных с использованием формата файлов Compose. Файл Compose используется для определения того, как настроены один или несколько контейнеров, составляющих ваше приложение. Когда у вас есть файл Compose, вы можете создать и запустить приложение с помощью одной команды: docker compose up. В качестве типичного примера приложения можно привести веб-сайт, состоящий из контейнера фронтэнда и контейнера бэкенда.

### 2. Кластерные приложения

Docker Swarm это простой оркестратор для контейнеров, который доступен из коробки. Позволяет объединить докер демоны на разных машинах в кластер, что даёт возможность поставки распределённых приложений упакованных в контейнеры. Swarm, так же как и Compose, имеет декларативную модель описания кластерного приложения. Типичными задачами для такого типа приложений являются организация высокой доступности, балансировки нагрузки и канареечного обновления сервиса. Также вы можете добиться эластичности распределённого приложения, которое создаёт и удаляет контейнеры в зависимости от поступающей нагрузки. 


## Релевантные источники
- Nemeth E. et al. UNIX and Linux system administration handbook. Chapter 25.
- https://containerd.io/
- https://github.com/moby/moby/blob/master/libnetwork/docs/design.md
- https://github.com/containernetworking/cni