Часть 1. Предпосылки и основы

Глава 1. Что и почему контейнеров

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

Контейнеры являются инкапсуляцией приложений вместе с их зависимостями. На первый взгляд они возникли для простой формы виртуальных машин (ВМ) - как и ВМ, контейнеры содержат изолированные экземпляры операционной системы (ОС), которые могут применяться для выполнения приложений.

Однако контейнеры имеют определённые преимущества, которые делают возможными варианты применения, которые сложны или даже невозможны для ВМ:

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

  • Переносимсоть контейнеров имеет потенциал исключить целый класс дефектов программ, вызываемых хитроумными изменениями в среде выполнения - они могут даже положить конец разработчиками старой закалки постоянно повторяющих "но это работает на моей машине!"

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

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

Что ещё более важно, фундаментальные цели ВМ и контейнеров являются различными - цель ВИ состоит в в полной эмуляции внешней среды, в то время как цель контейнера состоит в создании переносимого приложения и самодостаточности.

 Контейнеры против виртуальных машин

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

Рисунок 1-1 показывает три приложения, работающие в различных ВМ на хосте. Для создания ВМ и их работы, управления доступом к лежащем в основе ОС и оборудованию, а также для интерпретации по мере необходимости системных вызовов требуется гипервизор (Рисунок изображает гипервизор 2 типа, например Virtualbox или VMWare Workstation, которые работают поверх ОС хоста; гипервизор 1 типа, например Xen также возможен, в этом случае гипервизор работает поверх голого железа). Каждой ВМ требуется полная копия ОС, запускаемое приложение и все библиотеки поддержки.

 

Рисунок 1.1. Три ВМ, работающие на одном хосте



 

Рисунок 1.2. Три контейнера, работающих на одном хосте



В противовес этому Рисунок 1-2 показывает как те же самые три приложения могут быть запущены в системе с контейнерами. В отличие от ВМ, ядро хоста (ядро является сердцевиной ОС и отвечает за поддержку приложений основными системными функциями относящимися к оперативной памяти, процессору и доступу к устройствам; вся ОС состоит из ядра плюс различных системных программ, таких как инициализация систем, компиляторы и оконные менеджеры) совместно используется работающими контейнерами. Это означает, что контейнеры всегда ограничены выполнением одного и того же ядра в качестве хоста. Приложения Y и Z используют те же самые библиотеки и могут совместно использовать эти данные или даже иметь избыточные копии. Движок контейнера отвечает за запуск и остановку контейнеров аналогично гипервизору в случае ВМ. Однако, выполняемые внутри контейнеров процессы эквивалентны обычным процессам в хосте и не несут дополнительных накладных расходов связанных с выполнением гипервизора.

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

 Docker и контейнеры

Контейнеры являются старой концепцией. На протяжении десятилетий системы UNIX имели команду chroot, которая предоставляла простейшую форму изоляции файловой системы. Начиная с 1998 года FreeBSD обзавелась утилитой jail, которая расширила песочницу chroot до процессов. Solaris Zone предложили относительно завершенную технологию котейеризации примерно в 2001, однако были ограничены ОС Solaris. Также в 2001, Paralls Inc (позже SWsoft) реализовали коммерческую контейнерную технологию Virtuozzo для Linux, а позже технологию ядра с открытым исходным кодом под названием OpenVZ в 2005 (OpenVZ так и не нашла массового принятия, возможно из-за требования выполнения ядра с доработками). Затем Google запустил разработку CGroup для ядра Linux и начал перемещать свою инфраструктуру на контейнеры. Проект контейнеров Linux (LXC, Linux Container) стартовал в 2008 и свёл воедино CGroup, пространства имён ядра, а также технологию chroot (помимо всего прочего) для обеспечения полностью конейеризованного решения. Наконец, в 2013, Docker внесла последний штрих в паззл контейеризации и эта технология начала входить в мейнстрим.

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

Docker Engine предоставляет быстрый и удобный интерфейс выполнения контейнеров. Раньше выполнение контейнеров использовало технологии подобные LXC, требующие значительных специальных знаний и ручной работы. Docker Hub предоставляет значительное число общедоступных образов контейнеров для загрузки, позволяя пользователям быстро получать запуск и избегать дублирования уже выполненной другими работы. Другие разработанные Docker инструменты включают в себя систему управления кластером Swarm; графический интерфейс для работы с контейнерами Kitematic; и утилиту командной строки сопровождения хостов Docker Machine.

Открыв исходный код Docker Engine, Docker смог увеличить большое сообщество вокруг Docker и получить преимущества общественной помощи с окружениями и фиксацией ошибок. Быстрый рост Docker означает, что он практически становится стандартом де факто, который побуждает индустрию оказывать давление на продвижение разработки независимых формальных стандартов для исполнения контейнеров и их формата. В 2015г это нашло свою кульминацию в учреждении открытой инициативы контейнеров (Open Container Initiative), "управляющей структуры" спонсируемой Docker, Microsoft, CoreOS и многими прочими важными организациями, чья миссия состоит в разработке подобного стандарта. В основе их усилий лежат формат контейнера Docker и его формы исполнения.

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

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

[Замечание]Перевозочная метафора

Философия Docker часто объясняется в терминах метафоры транспортного контейнера, которая по-видимому объясняет имя Docker. История обычно рассказывается как-то так:

При транспортировке товаров они должны пройти через различные средства, возможно включающие грузовики, автопогрузчики, краны, поезда и корабли. Эти средства должны быть в состоянии обрабатывать большое разнообразие грузов различных размеров и с различными требованиями (напимер, мешки кофе, бочки с опасными химическими веществами, ящики с электронными товарами, парки высококлассных автомашин, стойки с охлажденной бараниной) Исторически это было обременительным и дорогостоящим процессом, требующим ручной работы, например, работников доков, для погрузки и выгрузки элементов в каждой точке транзита Рисунок 1-3.

 

Рисунок 1.3. Докеры, работающие в Бристоле, Англия (фотография фотоотдела Министерства инфрмации)



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

Цель Docker состоит в переносе преимуществ стандартизации контейнеров в информационные технологии. В последние годы системы программного обеспечения переживают взрыв в в терминах разнообразия. Прошли те времена когда стек LAMP (изначально обозначало Linux, Apache, MySQL и PHP - общеупотребимые компоненты веб- приложений) работал на отдельной машине. Типичная современная система может содержать инфраструктуру Javascript, базы данных NoSQL, очереди сообщений, REST API, а также сервера, написанные на различных языках программирования. Такой стек должен работать частично или полностью поверх разнообразных аппаратных средств - от ноутбуков разработчиков и домашних тестовых кластеров вплоть до промышленных поставщиков облачных решений. Каждая из таких сред является существенно отличной, работает с разными операционными системами, с различными версиями библиотек на различных аппаратных средствах. Короче говоря, мы имеем аналогичную проблему, которая наблюдалась в транспортной отрасли - мы должны постоянно вносить существенный ручной труд для перемещения кода между окружениями. Подобно тому как многофункциональные контейнеры упростили транспортировку товаров, контейнеры Docker упрощают транспортировку программных приложений. Разработчики могут сосредоточиться на разработке приложений и отправлять его сквозь тестирование и производств не заботясь о разнице в средах и зависимостях. Персонал сопровождения может сосредоточиться на ключевых вопросах работающих контейнеров, таких как распределение ресурсов запуск и останов контейнеров, а также их переносе между серверами.

 Docker: история

В 2008г Соломон Хайкс основал dotCloud для построения независимого от языков высокого уровня предложения платформы-как-службы (PaaS, Plaftform-as-a-Service). Независимый от языков высокого уровня подход был уникальной посевной точкой для dotCloud - существовавшие PaaS привязывались к определенному набору языков (например, Heroku поддерживал Ruby, а Google App Engine поддерживал Java и Python). В 2010 dotCloud принял участие в программе ускорителя Y Combinator, в которой он был представлен новым партнерам и начал получать серъёзные инвестиции. Главной поворотной точкой стал март 2013, когда dotCloud открыл исходные коды Docker, основной блок построения dotCloud. Хотя некоторые компании были напуганы что dotCloud раздавал свои волшебные бобы, dotCloud осознал, что Docker получит значительную выгоду от того, что станет проектом движимым сообществом.

Ранние версии Docker были чем-то чуть большим чем обёртка вокруг LXC спаренной с UnionFS, однако освоение и скорость разработки были шокирующе быстрыми. За шесть месяцев он получил 6700зезд на GitHub и 175 свободных сотрудников. Это привело к тому, что dotCloud изменил своё имя на Docker, Inc. и поменял свою бизнес модель. Docker 1.0 был анонсирован в июне 2014, всего через 15 месяцев после выпуска 0.1. Docker 1.0 представил значительный прыжок в стабильности и гибкости - он был теперь объявлен как "годный к промышленному применению", хотя он уже был замечен в промышленном применении в различных компаниях, включая Spotify и Baidu. В то же время Docker запустил перемещение по направлению к тому чтобы быть завершенной платформой, а не просто движком контейнеров, с запуском Docker Hub, общедоступного репозитория для контейнеров.

Другиекомпании быстро увидели потенциал Docker. Red Hat стал ведущим партнером в сентябре 2013 и начал применять Docker для усиления своего облачного предложения OpenShift. Google, Amazon и DigitalOcean быстро предложили поддержку Docker в своих облаках, а различные стартапы начали специализироваться на хостинге Docker, например, StackDock. В октябре 2014 Microsoft анонсировал, что последующие версии Windows Server будут поддерживать Docker, отображая колоссальный сдвиг в позиционировании для компании, традиционно связываемой с обрюзгшим корпоративным программным обеспечением.

В декабре 2014 DockerConEU увидел анонс Docker Swarm, менеджер кластера для Docker и Docker Machine, инструментарий командной строки для предоставления хостов Docker. Это был ясный сигнал намерения Docker предоставить полное и интегрированное решение для работы контейнеров и не позволять себе ограничиваться исключительной поддержкой движка Docker.

Также в декабре CoreOS анонсировал разработку rkt, своего собственного средства поддержки контейнеров, и разработку спецификации контейнера appc. В июне 2015 на протяжении DockerCon в Сан Франциско, Соломон Хейкс из Docker и Алекс Полви из CoreOS анонсировали инициативы открытого контейнера (затем названную Open Container Project) для разработки общего стандарта для форматов контейнеров и их исполнения.

Также в июне 2015 проект FreeBSD анонсировал, что Docker теперь поддерживается FreeBSD с применением ZFS и уровня совместимости с Linux. В августе 2015 Docker и Microsoft выпустили "технический предпоказ" Docker Engine для Windows Server.

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

 Плагины и сантехника

Будучи компанией, Docker Inc. неизменно быстро осознавала, что во многом обязана своим успехом экосистеме. В то время как Docker Inc. сосредотачивается на выпуске стабильной, готовой к промышленной эксплуатации версии движка контейнеров, другие компании, такие как CoreOS, WeaveWorks и ClusterHQ работали в смежных областях, например, оркестровка и сетевые контейнеры. Однако быстро стало понятно, что Docker Inc. планировала производить завершённую коробочную платформу, содержащую сетевую среду, хранилище и возможности оркестровки. С целью поощрения дальнейшего роста экосистемы и гарантирования пользователям наличия доступа к решениям для широкого диапазона вариантов применения, Docker Inc. объявила о своём намерении создать модульную расширяемую инфраструктуру для Docker, в которой имеющиеся в наличии компоненты могут выгружаться для сторонних эквивалентов или расширяться сторонней функциональностью. Docker Inc. назвал эту стратегию "батарейки в комплекте, но заменяемы" (Batteries Included, But Replaceable), что означает, что полные решения будут предоставлены, но детали могут переставляться (конкретно мне никогда не нравилась данная фраза, все батарейки предоставляют во многом схожую функциональность, и могут заменяться только батареями того же размера и напряжения; я предполагаю, что эта фраза имеет происхождение из Python-овской философии "батарейки вложены" (Batteries Included), которая используется для объяснения громадной стандартной библиотеки, поставляемой с Python).

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

Docker также следует тому, что они называют "манифестом сантехнической инфраструктуры" (Infrastructure Plumbing Manifesto), который подчеркивает свою приверженность повторному использованию и совершенствованию существующих компонентов инфраструктуры там, где это возможно и способствует повторному использованию компонентов обратно в сообществе, когда требуются новые инструменты. Это привело к вывинчиванию кода низкого уровня для выполнения контейнеров в проект runC, который контролируется OCI и может повторно применяться как основа для других платформ контейнера.

 Linux 64-бита

На момент написания единственная стабильная, готовая к промышленной эксплуатации платформа для Docker была 64- битный Linux. Это означает, что ваш компьютер должен выполнять 64- битный дистрибутив Linux и все контейнеры также будут 64- битные Linux. Если вы являетесь пользователем Windows или Mac OS, вы можете выполнять Docker внутри виртуальной машины.

Поддержка для других обычных контейнеров на других платформах, включающих BSD, Solaris и Windows Server находятся в различных стадиях разработки. Хотя Docker не делал изначально никакой виртуализации, контейнеры всегда должны соответствовать ядру хоста - Windows Server контейнер может выполняться только на Windows Server хосте, а 64- битный Linux контейнер может работать только на 64- битном Linux хосте.

[Замечание]Микрослужбы и монолиты

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

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

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

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

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

Для получения дополнительных сведений по микрослужбам ознакомьтесь с Building Microservices Сэма Ньюмана (O`Reilly) и Microservice Resource Guide Мартина Фоулера.