Перейти к содержимому

На чем написан docker

  • автор:

Docker Engine overview

Docker Engine is an open source containerization technology for building and containerizing your applications. Docker Engine acts as a client-server application with:

  • A server with a long-running daemon process dockerd .
  • APIs which specify interfaces that programs can use to talk to and instruct the Docker daemon.
  • A command line interface (CLI) client docker .

The CLI uses Docker APIs to control or interact with the Docker daemon through scripting or direct CLI commands. Many other Docker applications use the underlying API and CLI. The daemon creates and manage Docker objects, such as images, containers, networks, and volumes.

Install Docker Engine

Learn how to install the open source Docker Engine for your distribution.

Эволюция Docker. Часть 1

The future of Linux Containers

The future of Linux Containers

20 марта 2013 года на конференции PyCon 2013, Соломон Хайкс (CEO компании dotCloud) выступил с пятиминутной презентацией The future of Linux Containers. В ней широкой общественности впервые была представлена внутренняя разработка компании dotCloud под названием Docker, а спустя несколько дней ее исходный код был выложен в открытый доступ. Хотя технологии LXC и Aufs, на которых была основана первая версия Docker существовали и активно использовались уже порядка пяти лет, но именно появление Docker послужило началом стремительного роста и эволюции систем контейнеризации, что кардинально преобразило многие процессы разработки и деплоймента программного обеспечения.

Этой статьей я собираюсь начать небольшой цикл посвященный изучению развития исходного кода Docker на протяжении нескольких лет. В первой части мы посмотрим на то, что представлял собой код на момент создания git репозитория датированного январем 2013 года. Тогда исходный код Docker (за исключением тестов) состоял всего из шести файлов общим объемом

600 строк кода, написанных на языке Go. Это больше походило на библиотеку/api, функционал которой состоял лишь в создании, удалении, запуске и остановке контейнеров. Мы разберем принцип работы и даже сможем запустить с ее помощью подготовленный контейнер.

Во второй части мы перенесемся на несколько месяцев вперед — в март 2013, когда докер был представлен на конференции PyCon. На тот момент он уже обладал практически всеми знакомыми нам функциями. А в третьей части я постараюсь рассмотреть переход Docker с LXC на собственную разработку, произошедший годом позже.

Исходный код

Для запуска я буду использовать Windows 10 c Vagrant и Ubuntu 20.04. Сразу хочу предупредить, что WSL2 не подойдет, так как используемое ядро не поддерживает aufs, требуемую в ранних версиях.

В первую очередь нам нужно скачать исходный код https://github.com/docker/engine.git или https://github.com/moby/moby.git. Склонируем репозиторий и вернемся к началу истории (хеш первого коммита можно получить при помощи git log —reverse).

На момент создания репозитория (18 января 2013 года), код Docker состоял всего из 6 файлов общим объемом в 624 строки и как мы увидим далее, представлял собой лишь обертку и удобное api для утилит lxc и mount.

Итак, приступим к изучению самого кода, отправной точкой будет служить файл docker.go, в котором объявлены функции New и NewFromDirectory:

New является фасадом, который просто вызывает NewFromDirectory с дефолтным путем /var/lib/docker. Функция NewFromDirectory производит инициализацию структуры Docker, создает директорию для контейнеров (если она не существует) и возвращает структуру Docker (перед чем вызывается метод restore):

В методе restore происходит попытка загрузки и инициализации существующих контейнеров из папки containers вызовом функции loadContainer. При первом запуске данная папка будет пуста, так что ничего не произойдет. Мы рассмотрим данный функционал немного позже, когда перейдем к файлу container.go.

Следующие интересующие нас методы из файла docker.go это Create и Destroy:

Здесь все предельно просто — метод Create проверяет существование контейнера по переданному имени, делегирует создание методу createContainer (находится в файле container.go) и сохраняет созданный контейнер в список.

Аналогично ему метод Destroy останавливает контейнер, удаляет корневую директорию контейнера, а затем удаляет его из списка containers.

Остальное содержимое файла docker.go составляют лишь несколько хелпер методов:

Get — возвращает контейнер по имени

List — возвращает список контейнеров

getContainerElement — возвращает элемент списка контейнеров

Exists — проверяет существование контейнера в списке по имени

Следующей точкой будет файл container.go и метод createContainer, который собственно и занимается реальным созданием контейнеров:

В начале метода происходит инициализация структуры Container, создание директории и сохранение в ней экспортированного файла конфигурации контейнера, а также конфигурационного файла для утилиты lxc-start. В функции newFilesystem из файла filesystem.go просто инициализируется и возвращается структура Filesystem. Чуть позже мы рассмотрим filesystem.go подробнее.

Функция newState находится в state.go и инициализирует структуру содержащую pid, exitcode, а так же мьютекс для коммуникации.

Функция newWriteBroadcaster() из utils.go возвращают структуру writeBroadcaster (broadcast pattern) использующуюся для работы с потоками stdout и stderr.

Метод save экспортирует структуру Container в json формат и сохраняет в файл, по которому в дальнейшем происходит загрузка контейнеров в методе restore и loadContainer, о чем было указано ранее.

Перейдем к последнему методу вызываемому в функции createContainer — generateLXCConfig:

Как видим, в нем используется переменная LxcTemplateCompiled. Чтобы разобраться с ней, нам нужно взглянуть на файл lxc_template.go, в котором находится шаблон для конфигурационного файла lxc:

Он компилируется на этапе инициализации модуля, а в методе generateLXCConfig после подстановки значений сохраняется на диск в файле config.lxc.

Подведем итог: в методе createContainer выполняется инициализация структуры Container и вспомогательных структур Filesystem, State и writeBroadcaster. Далее в папке containers создается директория с именем контейнера, в которую сохраняется структура Container после экспорта в json. На последнем этапе на основе параметров контейнера генерируется и сохраняется конфигурационный файл для lxc-start.

Далее перейдем к запуску контейнера, который происходит в методе Start из файла container.go

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

Как видим, это всего лишь обертка над утилитой mount. Метод createMountPoints создает две директории:

Rootfs — будет точкой монтирования файловой системы контейнера.

RWPath — директория с возможностью записи, в которой будут сохраняться все изменения файловой системы происходящие во время работы контейнера.

Метод Mount формирует строку параметров и вызывает утилиту mount с типом aufs. Метод Umount соответственно размонтирует файловую систему.

Все слои образа (Layers) представляют собой пути к директориям, которые монтируются с правами read only в объединенную файловую систему в точке RootFS, а все изменения происходят в директории RWPath и сохраняются даже после размонтирования. Файловая система Aufs имеет механизм copy-on-write, это означает, что когда происходит попытка изменения файла находящегося в read-only слое, он будет автоматически скопирован в RWPath.

Теперь вернемся к функции Start из container.go. После монтирования файловой системы она подготавливает параметры и запускает утилиту lxc-start, перед этим перенаправляя потоки stdout и stderr. В качестве параметров ей передается имя запускаемого контейнера и путь к конфигурационному файлу config.lxc, который был сгенерирован ранее на этапе создания контейнера. После запуска процесса его pid сохраняется в структуре State:

Далее запускается горутина monitor, которая ждет завершения процесса, закрывает потоки stdout и stderr и сохраняет exitcode контейнера через метод setStopped:

Осталось разобрать метод Stop, который предназначен для остановки контейнеров:

Здесь тоже все предельно просто — если контейнер еще работает, то пытаемся остановить его с помощью вызова утилиты lxc-stop, после чего размонтируем файловую систему.

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

Запуск контейнеров

Теперь мы можем попробовать запустить контейнер. Как я указывал в начале, все операции выполняются на чистой виртуалке с Ubuntu 20.04.

Перед продолжением нужно установить golang и lxc, а так же скачать rootfs для образа (я буду использовать alpine linux).

Проверим что rootfs на месте:

Теперь нужно сделать небольшие изменения, так как некоторые опции lxc поменялись в новой версии, а так же поправим метод restore в docker.go. Ниже приведен патч:

Далее выполним go mod init docker и остается лишь написать простую cli программу для управления контейнерами. Создадим папку cli c файлом docker.go и подобным контентом:

Теперь скомпилируем программу и запустим контейнер:

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

Запустим еще один контейнер и создадим в нем файл:

Запустим /bin/sh в созданном контейнере:

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

Теперь попробуем удалить контейнер:

Как видим, все файлы контейнера test2 были успешно удалены.

Заключение

Вот приблизительно так выглядел весь функционал Docker на момент его зарождения.

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

Что такое докер?

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

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

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

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

Для чего я могу использовать docker?

Быстрое выкладывание ваших приложений

Docker прекрасно подходит для организации цикла разработки. Docker позволяет разработчикам использовать локальные контейнеры с приложениями и сервисами. Что в последствии позволяет интегрироваться с процессом постоянной интеграции и выкладывания (continuous integration and deployment workflow).

Например, ваши разработчики пишут код локально и делятся своим стеком разработки (набором docker образов) с коллегами. Когда они готовы, отравляют код и контейнеры на тестовую площадку и запускают любые необходимые тесты. С тестовой площадки они могут оправить код и образы на продакшен.

Более простое выкладывание и разворачивание

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

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

Высокие нагрузки и больше полезных нагрузок

Docker легковесен и быстр. Он предоставляет устойчивую, рентабельную альтернативу виртуальным машинам на основе гипервизора. Он особенно полезен в условиях высоких нагрузок, например, при создания собственного облака или платформа-как-сервис (platform-as-service). Но он так же полезен для маленьких и средних приложений, когда вам хочется получать больше из имеющихся ресурсов.

Главные компоненты Docker

Docker состоит из двух главных компонент:

  • Docker: платформа виртуализации с открытым кодом;
  • Docker Hub: наша платформа-как-сервис для распространения и управления docker контейнерами.

Примечание! Docker распространяется по Apache 2.0 лицензии.

Архитектура Docker

Docker использует архитектуру клиент-сервер. Docker клиент общается с демоном Docker, который берет на себя тяжесть создания, запуска, распределения ваших контейнеров. Оба, клиент и сервер могут работать на одной системе, вы можете подключить клиент к удаленному демону docker. Клиент и сервер общаются через сокет или через RESTful API.

Docker-демон

Как показано на диаграмме, демон за пускается на хост-машине. Пользователь не взаимодействует с сервером на прямую, а использует для этого клиент.

Docker-клиент

Docker-клиент, программа docker — главный интерфейс к Docker. Она получает команды от пользователя и взаимодействует с docker-демоном.

Внутри docker-а

Чтобы понимать, из чего состоит docker, вам нужно знать о трех компонентах:

  • образы (images)
  • реестр (registries)
  • контейнеры

Образы

Docker-образ — это read-only шаблон. Например, образ может содержать операционку Ubuntu c Apache и приложением на ней. Образы используются для создания контейнеров. Docker позволяет легко создавать новые образы, обновлять существующие, или вы можете скачать образы созданные другими людьми. Образы — это компонента сборки docker-а.

Реестр

Docker-реестр хранит образы. Есть публичные и приватные реестры, из которых можно скачать либо загрузить образы. Публичный Docker-реестр — это Docker Hub. Там хранится огромная коллекция образов. Как вы знаете, образы могут быть созданы вами или вы можете использовать образы созданные другими. Реестры — это компонента распространения.

Контейнеры

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

Так как же работает Docker?

Пока мы знаем, что:

  • можем создавать образы, в которых находятся наши приложения;
  • можем создавать контейнеры из образов, для запуска приложений;
  • можем распространять образы через Docker Hub или другой реестр образов.

Давайте посмотрим, как эти компоненты сочетаются.

Как работает образ?

Мы уже знаем, что образ — это read-only шаблон, из которого создается контейнер. Каждый образ состоит из набора уровней. Docker использует union file system для сочетания этих уровней в один образ. Union file system позволяет файлам и директориями из разных файловых систем (разным ветвям) прозрачно накладываться, создавая когерентную файловую систему.

Одна из причин, по которой docker легковесен — это использование таких уровней. Когда вы изменяете образ, например, обновляете приложение, создается новый уровень. Так, без замены всего образа или его пересборки, как вам возможно придётся сделать с виртуальной машиной, только уровень добавляется или обновляется. И вам не нужно раздавать весь новый образ, раздается только обновление, что позволяет распространять образы проще и быстрее.

В основе каждого образа находится базовый образ. Например, ubuntu, базовый образ Ubuntu, или fedora, базовый образ дистрибутива Fedora. Так же вы можете использовать образы как базу для создания новых образов. Например, если у вас есть образ apache, вы можете использовать его как базовый образ для ваших веб-приложений.

Примечание! Docker обычно берет образы из реестра Docker Hub.

Docker образы могут создаться из этих базовых образов, шаги описания для создания этих образов мы называем инструкциями. Каждая инструкция создает новый образ или уровень. Инструкциями будут следующие действия:

  • запуск команды
  • добавление файла или директории
  • создание переменной окружения
  • указания что запускать когда запускается контейнер этого образа

Эти инструкции хранятся в файле Dockerfile . Docker считывает это Dockerfile , когда вы собираете образ, выполняет эти инструкции, и возвращает конечный образ.

Как работает docker реестр?

Реестр — это хранилище docker образов. После создания образа вы можете опубликовать его на публичном реестре Docker Hub или на вашем личном реестре.

С помощью docker клиента вы можете искать уже опубликованные образы и скачивать их на вашу машину с docker для создания контейнеров.

Docker Hub предоставляет публичные и приватные хранилища образов. Поиск и скачивание образов из публичных хранилищ доступно для всех. Содержимое приватных хранилищ не попадает в результат поиска. И только вы и ваши пользователи могут получать эти образы и создавать из них контейнеры.

Как работает контейнер?

Контейнер состоит из операционной системы, пользовательских файлов и метаданных. Как мы знаем, каждый контейнер создается из образа. Этот образ говорит docker-у, что находится в контейнере, какой процесс запустить, когда запускается контейнер и другие конфигурационные данные. Docker образ доступен только для чтения. Когда docker запускает контейнер, он создает уровень для чтения/записи сверху образа (используя union file system, как было указано раньше), в котором может быть запущено приложение.

Что происходит, когда запускается контейнер?

Или с помощью программы docker , или с помощью RESTful API, docker клиент говорит docker демону запустить контейнер.

Давайте разберемся с этой командой. Клиент запускается с помощью команды docker , с опцией run , которая говорит, что будет запущен новый контейнер. Минимальными требованиями для запуска контейнера являются следующие атрибуты:

  • какой образ использовать для создания контейнера. В нашем случае ubuntu
  • команду которую вы хотите запустить когда контейнер будет запущен. В нашем случае /bin/bash

Что же происходит под капотом, когда мы запускаем эту команду?

Docker, по порядку, делает следующее:

  • скачивает образ ubuntu: docker проверяет наличие образа ubuntu на локальной машине, и если его нет — то скачивает его с Docker Hub. Если же образ есть, то использует его для создания контейнера;
  • создает контейнер: когда образ получен, docker использует его для создания контейнера;
  • инициализирует файловую систему и монтирует read-only уровень: контейнер создан в файловой системе и read-only уровень добавлен образ;
  • инициализирует сеть/мост: создает сетевой интерфейс, который позволяет docker-у общаться хост машиной;
  • Установка IP адреса: находит и задает адрес;
  • Запускает указанный процесс: запускает ваше приложение;
  • Обрабатывает и выдает вывод вашего приложения: подключается и логирует стандартный вход, вывод и поток ошибок вашего приложения, что бы вы могли отслеживать как работает ваше приложение.

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

Используемые технологии

Докер написан на Go и использует некоторые возможности ядра Linux, чтобы реализовать приведенный выше функционал.

Пространство имен(namespaces)

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

Это создает изолированный уровень, каждый аспект контейнера запущен в своем простанстве имен, и не имеет доступ к внешней системе.

Список некоторых пространств имен, которые использует docker:

  • pid: для изоляции процесса;
  • net: для управления сетевыми интерфейсами;
  • ipc: для управления IPC ресурсами. (ICP: InterProccess Communication);
  • mnt: для управления точками монтирования;
  • utc: для изолирования ядра и контроля генерации версий(UTC: Unix timesharing system).

Control groups (контрольные группы)

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

Union File System

Union File Sysem или UnionFS — это файловая система, которая работает создавая уровни, делая ее очень легковесной и быстрой. Docker использует UnionFS для создания блоков, из которых строится контейнер. Docker может использовать несколько вариантов UnionFS включая: AUFS, btrfs, vfs и DeviceMapper.

Форматы контейнеров

Docker сочетает эти компоненты в обертку, которую мы называем форматом контейнера. Формат, используемый по умолчанию, называется libcontainer . Так же docker поддерживает традиционный формат контейнеров в Linux c помощью LXC. В будущем Docker возможно будет поддерживать другие форматы контейнеров. Например, интегрируясь с BSD Jails или Solaris Zones.

Docker: введение

Docker: введение

Docker – это открытая платформа, предназначенная для разработки, доставки и организации работы приложений.

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

Что такое платформа Docker?

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

Docker предоставляет утилиты и платформу для управления жизненным циклом ваших контейнеров:

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

Что такое Docker Engine?

  • Сервер, по сути являющийся долго работающим приложением, называемым демоном
  • REST API, определяющее интерфейсы для взаимодействия, которые могут использовать другие программы.
  • Консольный (CLI) клиент

engine-components-flow.png

Консольный клиент использует Docker REST API для управления или взаимодействия с демоном Docker при помощи скриптов или непосредственных консольных команд.

Демон создает и управляет объектами Docker, такими как образы (images), контейнеры, сети и тома данных (data volumes)

На заметку: Docker распространяется под открытой Apache 2.0 лицензией.

Для чего я могу использовать Docker?

Быстрая, последовательная доставка ваших приложений

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

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

Адаптивная доставка и масштабируемость

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

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

Обслуживание больших нагрузок на том же самом железе

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

Архитектура Docker

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

docker-architecture.png

Демон Docker

Демон Docker работает на хостовом сервере. Пользователь использует клиент Docker для взаимодействия с демоном.

Клиент Docker

Клиент Docker в формате исполняемого файла docker — это основной пользовательский интерфейс для Docker. Он принимает команды и конфигурационные флаги от пользователя и взаимодействует с демоном Docker. Один клиент может взаимодействовать с множеством несвязанных демонов.

Внутри Docker

Для понимания внутренностей Docker вам необходимо знать про образы (images), реестры (registries) и контейнеры (containers).

Образы Docker

Образ Docker — это шаблон в формате «только для чтения» с инструкциями для создания контейнера Docker. Например, образ может содержать в себе ОС Ubuntu с web-сервером Apache и вашим установленным внутрь web-приложением. Вы можете собрать или обновить образ с нуля, или загрузить и использовать образы, созданные другими людьми. Образ может быть основан или расширять один или более других образов. Образ Docker описан в текстовом файле Dockerfile, который имеет простой и вполне определенный синтаксис. Для получения большей информации о образах, смотрите «Как работают образы Docker?».

Образы Docker — это основной строительный компонент Docker.

Контейнеры Docker

Контейнер Docker — это запускаемый экземпляр Docker образа. Вы можете запустить, остановить, переместить или удалить контейнер, используя Docker API или консольный клиент. Когда вы запускаете контейнер, вы можете предоставить конфигурационные метаданные такие как сетевая информация или переменные окружения. Каждый контейнер — это изолированная и безопасная платформа для приложений, однако, ему может быть предоставлен доступ к ресурсам, работающим на другом хосте или контейнере, таким как постоянный сторадж (persistent storage) или база данных. Для получения большей информации о контейнерах, смотрите «Как работает контейнер?»

Контейнеры Docker — это рабочий компонент Docker.

Реестры Docker

Реестр Docker — это библиотека образов. Реестр может быть публичным, приватным, а также может быть установлен на том же сервере, что и демон или клиент Docker или же на совсем частном сервере. Для получения большей информации о реестре, смотрите Как работает реестр Docker?

Реестры Docker — это компонент распространения Docker.

Сервис Docker

Сервис Docker позволяет целому рою (swarm) Docker узлов работать одновременно, обслуживая определенное количество экземпляров реплицированной задачи (replica task), представляющей собой образ Docker. Вы можете определить количество одновременных запускаемых реплицированных задач и кластерный менеджер убедится, что нагрузка распределена You can specify the number of concurrent replica tasks to run, and the swarm manager ensures that the load is spread равномерно по рабочим узлам. Для конечного потребителя сервис Docker представляется как одно приложение. Docker Engine поддерживает режим работы swarm mode с Docker 1.12 и выше.

Сервисы Docker — это компоненты масштабирования Docker.

Как работают образы Docker?

Образы Docker — это шаблоны в формате «только чтение» из которых запускаются Docker контейнеры. Каждый образ состоит из последовательности слоев. Docker использует union file systems для объединения этих слоев в единый образ. Union FS позволяет файлам и директориям отдельных файловых систем известным как ветки (branches) быть прозрачно наложенными друг на друга, чтобы образовать единую связную файловую систему.

Эти слои одна из причин, почему Docker настолько легковесный. Когда вы изменяете образ Docker, например, в процессе обновления приложения на новую версию, собирается только новый слой, заменяет только тот слой, который обновляется. Остальные слои остаются нетронутыми. Для распространения обновления все, что вам нужно, это передать обновленный слой. Механизм работы со слоями увеличивает скорость распространения образов Docker. Docker сам определяет, какой слой должен быть обновлен в рантайме.

Образ определяется в Dockerfile. Каждый образ начинается с основного образа (base image), такого как ubuntu (основного образа ОС Ubuntu) или fedora (основного образа ОС Fedora). Вы можете также самостоятельно использовать доступные образы в качестве основы для новых, например, вам доступен базовый образ web-сервера Apache, и вы можете использовать его для всех образов ваших web-приложений. Базовый образ определяется при помощи ключевого слова FROM в Dockerfile.

Заметка: Docker Store — это публичный реестр и хранилище образов Docker

Образ Docker собирается на основе базового образа при помощи простого

The docker image is built from the base image using a simple, наглядного набора шагов, которые называются инструкциями, которые последовательно записаны в

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

  • Определить базовый образ
  • Определить ответственного за поддержку
  • Выполнить команду
  • Добавить файл или директорию
  • Создать переменную окружения
  • Какой процесс запустить, когда будет запускаться контейнер из этого образа

Как работает реестр Docker?

Реестр Docker хранит Docker образы. После того как вы собрали Docker образ, вы можете отправить (push) его в публичный реестр, такой как Docker Store или приватный реестр, закрытый вашим межсетевым экраном. Вы можете также искать уже существующие образы и скачивать (pull) их из реестра на хост.

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

Как работает контейнер?

В процессе своей работы контейнер использует Linux ядро хостовой машины, состоит из какого-то количества дополнительных файлов, которые были добавлены к нему в процессе его создания, а также метаданных, связываемых с контейнером в процессе его создания или когда контейнер уже запущен. Каждый контейнер собирается из образа. Образ определяет содержимое контейнера, какой процесс запустить, когда контейнер начинает работать, а также другие всевозможные подробности конфигурации. Образ Docker не изменяем. Когда Docker запускает контейнер из образа, он добавляет дополнительный слой поверх этого образа, который доступен для записи (при помощи UnionFS, как мы видели ранее).

Что происходит, когда вы запускаете контейнер?

Когда вы используете

консольную команду или эквивалентный API-вызов, клиент Docker Engine отдает задачу Docker демону на запуск контейнера. В этом примере клиент сообщает Docker демону инструкцию по запуску контейнера из образа Docker, используется, чтобы оставаться войти в контейнер в интерактивном режиме и запустить команду

Когда вы запускаете эту команду, Docker Engine выполняет следующие действия:

  1. Скачивает (pull) образ Docker Engine проверяет наличие образа в кеше на хосте, на котором работает Docker Engine. Если образ уже существует локально, Docker Engine использует его для запуска нового контейнера. В противном случае Docker Engine скачивает этот образ с Docker Store.
  2. Создает новый контейнер: Docker использует указанный образ для создания контейнера.
  3. Выделяет место на файловой системе хоста и монтирует слой доступный для записи: Контейнер создан на файловой системе и доступный для записи слой добавлен к его образу.
  4. Выделяет сетевой / bridge интерфейс: Создает сетевой интерфейс, который позволяет Docker контейнеру взаимодействовать с локальным хостом, на котором установлен Docker Engine.
  5. Назначает IP адрес: Находит и присоединяет доступный IP-адрес из пула.
  6. Выполняет процесс, который вы определили: Выполняет команду
  7. Захватывате и предоставляет вывод приложения: Подключается и логирует стандартный поток ввода, вывода и ошибок, чтобы показать вам, как исполняется ваше приложение, т.к. вы работаете в интерактивном режиме.

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

Базовые технологии

Docker написан на Go и использует несколько возможностей Linux ядра для реализации собственной функциональности.

Пространства имен (namespaces)

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

Эти пространства имен организуют слой изоляции. Каждый аспект контейнера запускается в отдельном пространстве имен и его доступ ограничен этим пространством имен.

Docker Engine использует следующие пространства имен в Linux:

  • Пространство имен Изоляция процесса (PID: ID процесса).
  • Пространство имен Управление сетевыми интерфейсами (NET: Сеть).
  • Пространство имен Управление доступом к IPC ресурсам (IPC: Межпроцессное взаимодействие).
  • Пространство имен Управление точками монтирования файловой системы (MNT: Монтирование).
  • Пространство имен Изолирование идентификаторов ядра и версий. (UTS: Unix система разделения времени).

Группы управления (control groups)

Docker Engine в Linux также основывается на другой технологии, называемой группами управления

Каждая cgroup лимитирует приложение в доступе к определенному набору ресурсов. Группы управления позволяют Docker Engine разделять доступные аппаратные ресурсы между контейнерами и при необходимости применять лимиты и ограничения. Например, вы можете ограничить определенному контейнеру доступную оперативную память.

Файловая система Union или UnionFS — это файловая система, которая работает путем создания слоев, делая их оучень легковесными и быстрыми. Docker Engine использует UnionFS как «строительные блоки» для контейнеров. Docker Engine может использовать множество различных реализаций UnionFS, т.к. AUFS, btrfs, vfs, а также DeviceMapper.

Формат контейнеров

Docker Engine объединяет пространства имен, группы управления и UnionFS в обертку (wrapper), называемую контейнерным форматом. Основной формат контейнеров — это

В будущем Docker возможно будет поддерживать другие форматы контейнеров, интегрируясь с такими технологиями как BSD Jails или Solaris Zones.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *