Docker контейнер что это

Docker контейнер что это

Рассказывает Сергей Бродин. Текст подготовили вместе с NetApp

Цитируя разработчиков Docker, «контейнер — это стандартная единица программного обеспечения, в которую упаковано приложение со всеми необходимыми для его работы зависимостями — кодом приложения, средой запуска, системными инструментами, библиотеками и настройками».

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

На рынке существует немало решений, представляющих среды запуска контейнеров и оркестрации, таких как CoreOS rkt, LXC, OpenVZ, containerd, Apache Mesos и Docker Swarm. Однако более 4/5 контейнеров запускается в среде Docker, а для оркестрации более половины пользователей выбрали Kubernetes. Об этих системах мы и поговорим.

Чем полезны контейнеры

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

Техническим же специалистам контейнеры прежде всего полюбились за возможность упаковать приложение вместе с его средой запуска, решая тем самым проблему зависимостей в разных окружениях. Например, различие версий языковых библиотек на ноутбуке разработчика и в последующих окружениях рано или поздно приведёт к сбоям, и нужно будет как минимум потратить время на их анализ, а как максимум — решать проблему проникших в продакшен багов. Использование контейнеров устраняет проблему «А на моей машине все работало! ¯\_(ツ)_/¯».

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

Чем контейнеры отличаются от виртуальных машин

Наиболее частым вопросом при выборе среды запуска приложения является вопрос о различии между контейнерами и виртуальными машинами — двумя самыми популярными опциями на текущий момент. Между ними есть принципиальная разница. Контейнер, в сущности, является ограниченным внутри ОС пространством, использующим для доступа к аппаратным ресурсам ядро host-системы. ВМ представляет собой машину целиком со всеми необходимыми для её работы устройствами. Из этого образуются отличия, имеющие практическое значение:

  • Контейнеры требуют значительно меньше ресурсов для своей работы, что положительно сказывается на производительности и бюджете.
  • Контейнеры можно запускать только в той же операционной системе, что стоит на host-системе — то есть запустить Windows-контейнер на host-системе с Linux не получится (на персональных устройствах это ограничение обходится с помощью технологии виртуализации). Однако это не относится к разным дистрибутивам одной и той же ОС, например Ubuntu и Alpine Linux.
  • Контейнеры предоставляют меньшую степень изоляции, поскольку используют ядро host-системы, что потенциально создаёт бóльшие риски в эксплуатации при небрежном отношении к безопасности.

Основные принципы контейнеризации приложений

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

1 контейнер — 1 сервис

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

Неизменность образа

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

Утилизируемость контейнеров

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

Отчётность

Контейнер должен иметь точки проверки состояния его готовности (readiness probe) и жизнеспособности (liveness probe), предоставлять логи для отслеживания состояния запущенного в нём приложения.

Управляемость

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

Самодостаточность

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

Лимитирование ресурсов

К лучшим практикам эксплуатации контейнеров относится настройка ресурсных лимитов (CPU и RAM): следование этой практике позволяет сохранять внимательное отношение к экономии ресурсов и вовремя реагировать на их избыточное потребление.

Docker

Когда мы говорим о контейнерах в современных IT-системах, прежде всего мы подразумеваем Docker — open-source-технологию, благодаря своей популярности ставшую в IT синонимом слова «контейнер».

Основные сущности Docker

Dockerfile

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

Image

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

Instance

Запущенный экземпляр образа, минимальная единица деплоя в Docker.

Volume

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

Registry

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

Процесс разработки в среде Docker

Типичный процесс разработки в среде Docker выглядит следующим образом: разработчики устанавливают на свои машины Docker, загружают собранный заранее образ с установленной средой сборки и выполнения приложения, а затем запускают контейнер командой, которая также пробросит в него директорию с исходниками. Для установки Docker не требуется особого железа — он может быть установлен на вполне заурядной машине. Однако у него имеются ограничения по версиям ОС — Windows 7 64bit или выше для ПК с поддержкой Hyper-V, macOS Sierra 10.12 для устройств от Apple и версией ядра 3.10 для систем с Linux. Контейнеры Docker являются родной технологией для ОС Linux и запускаются на других с помощью виртуальных машин под её управлением.

Инструкции по установке Docker на разных платформах: Windows, Mac, Linux Ubuntu.

Чтобы запустить ваш первый контейнер на Docker, после его установки введите в командной строке docker run hello-world — эта команда загрузит образ hello-world с Docker hub’а (публично доступный Docker registry), создаст контейнер, используя этот образ, и выдаст приветственную фразу:

Hello from Docker!
This message shows that your installation appears to be working correctly.
.

Оркестрирование контейнеров: Kubernetes

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

NetApp Kubernetes Service позволит создать cloud-agnostic кластер с уже реализованными механизмами деплоя и управления жизненным циклом приложения, автоматическим масштабированием инфраструктуры, интеграцией с сервисами хранилищ данных и многим другим, снизив затраты на конфигурацию и поддержку сложной инфраструктуры.

Основные сущности, которыми оперирует Kubernetes

Node (master и slave)

Узлы, из которых состоит кластер Kubernetes. Master-нода осуществляет контроль над кластером через планировщик и менеджер контроллеров, обеспечивает интерфейс взаимодействия с пользователями посредством API-сервера и содержит хранилище etcd, где находится конфигурация кластера, статусы его объектов и метаданные. Slave-нода предназначена исключительно для запуска контейнеров, для этого на ней установлены два сервиса Kubernetes — сетевой маршрутизатор и агент планировщика.

Namespace

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

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

ReplicaSet

Объект, описывающий и контролирующий соответствие запущенного на кластере количества реплик Pod’ов. Установка количества реплик больше одной требуется для повышения отказоустойчивости и масштабирования приложения. Общепринято создавать ReplicaSet с помощью Deployment.

Deployment

Объект, декларативно описывающий Pod’ы, количество реплик и стратегию их замены при обновлении параметров.

StatefulSet

Действует по тому же принципу, что и ReplicaSet, однако дополнительно позволяет описывать и сохранять при перезапуске уникальный сетевой адрес Pod’ов или их дисковое хранилище.

Читайте также:  Asus компания какой страны

DaemonSet

Объект, обеспечивающий контроль за тем, что на каждой ноде (или нескольких выбранных) будет запущено по экземпляру указанного Pod’а.

Job и CronJob

Объекты, запускающие соответственно однократно и регулярно по расписанию указанный Pod и отслеживающие результат завершения его работы.

Label и Selector

Метки, позволяющие маркировать ресурсы и тем самым упрощать групповые манипуляции, связанные с ними.

Service

Инструмент для публикации приложения в качестве сетевого сервиса, в том числе реализующий балансировку нагрузки между Pod’ами приложения.

Если сравнить объекты Docker и Kubernetes, то станет понятна разница в задачах, решаемых этими инструментами: можно сказать, что Docker управляет контейнерами, в то время как Kubernetes управляет самим Docker.

Управление конфигурацией (Configuration/Complexity Management)

Развитие IT-систем ведёт ко всё большему их усложнению, и это порождает проблемы управления — даже на небольшом количестве серверов или контейнеров ручное управление приложением превращает практически любое изменение конфигурации в трудовой подвиг, а на десятках или сотнях делает его абсолютно невозможным. К счастью, новые проблемы ведут и к новым решениям — в этом разделе мы расскажем о некоторых инструментах управления конфигурацией (configuration management) или, как ещё принято говорить, управления сложностью (complexity management). Они используются для установки, управления и обновления приложений Kubernetes: например, с их помощью можно описать приложение, состоящее из фронтенда, бэкенда и всех необходимых для их работы сервисов, таких как объекты Kubernetes, контейнеры с веб-серверами, базами данных, серверами очередей и т. д.

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

Kustomize

Благодаря популярности у пользователей и своей простоте, начиная с версии Kubernetes 1.14, Kustomize является встроенным инструментом управления конфигурацией. Для описания приложений использует чистый язык разметки YAML без возможности шаблонизации и использования параметров, что является одновременно его сильной и слабой сторонами, упрощая процесс настройки и вместе с тем сильно его ограничивая.

Ansible

Многофункциональный инструмент, для которого конфигурация Kubernetes-приложений — лишь одно из великого множества применений, реализованная с помощью специального модуля интеграции. Например, Ansible может быть использован для настройки виртуальных машин, развертывания облачной инфраструктуры, выполнения бэкапов и т.д. Его универсальность позволяет решать разнообразные задачи, связанные с IT-проектами, одним инструментом – но ценой меньшей функциональности в отношении управления конфигурацией приложений Kubernetes. Для описания использует YAML и язык шаблонов Jinja2.

Управляйте хранилищами данных в автоматизированном режиме с помощью модулей интеграции Ansible NetApp.

Jsonnet

Также как и Ansible, Jsonnet не является чем-то специфичным для Kubernetes, однако многие знакомы с ним именно благодаря K8s. Jsonnet описывает объекты с помощью расширенного JSON, включающего комментарии, текстовые блоки, параметры, переменные, условные включения и функции. Очень мощный и гибкий инструмент.

Пакетный менеджер приложений Kubernetes. Этот инструмент описывает приложения в виде декларативных диаграмм (charts), создающихся с помощью языка разметки YAML и шаблонов Golang. Helm обладает широкой базой готовых диаграмм, даёт возможность версионировать конфигурации и переключаться между версиями релизов, т. е. откатывать конфигурацию. Из всех приведенных здесь инструментов является наиболее функциональным в отношении управления приложениями Kubernetes и одновременно обладает наиболее сложным способом описания конфигурации из-за шаблонов Golang, весьма требователен к пользовательским навыкам.

В этой статье перечислены лишь те инструменты, что наиболее заслуживают внимания по нашему мнению. Помимо них существует ещё с добрый десяток решений для задач управления конфигурацией в Kubernetes: такие как Kapitan, Ksonnet, Replicated Ship и т. д. При выборе менеджера управления конфигурацией мы рекомендуем определиться с требованиями, предъявляемыми к нему, и руководствоваться принципом разумной достаточности, не используя без нужды излишне сложный инструмент – хорошим путем будет начать с чего-то простого, дополнительно задействуя более мощный инструмент, когда возникнет необходимость.

Платформы для хостинга контейнеров

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

Своё железо (bare metal)

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

Облачные решения (SaaS)

Крупные облачные провайдеры предоставляют своим клиентам сервисы для запуска контейнеров — готовые среды, обёрнутые удобным интерфейсом управления. Построенные по такому принципу решения называются Software as a Service (SaaS). Они не требуют никаких капитальных затрат, поскольку вся инфраструктура арендуется, а конфигурация создаётся в минимальном объёме, относящемуся исключительно к запускаемому приложению. Сами же кластеры настраиваются провайдером по указанному пользователем небольшому объему параметров. SaaS-решения — оптимальный вариант для стартап-компаний, небольших и развивающихся проектов. Самым большим минусом этого решения можно назвать повышенную в сравнении с bare metal стоимость при условии многолетнего использования.

Тремя наиболее популярными облачными платформами на сегодня являются Amazon Web Services, Microsoft Azure и Google Cloud. Все три провайдера имеют доступный в виде сервиса Kubernetes, и все три из них предлагают пробный период пользования сервисами, выдавая депозит на сумму 200–300 $. Чтобы оценить удобство и качество облачных решений и сравнить друг с другом их поставщиков, вам даже не придется тратить свои деньги.

Хотите обеспечить максимальную сохранность данных, создаваемых и используемых в контейнерах? NetApp Trident позволит легко интегрировать в вашу контейнерную инфраструктуру надежное и функциональное хранилище данных enterprise-уровня.

Заключение

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

Docker
Тип Виртуализация на уровне операционной системы
Автор
Разработчик Docker, Inc.[d]
Написана на Go[1]
Операционная система Linux[2] , Microsoft Windows[3] и macOS[4]
Первый выпуск 13 марта2013[5]
Аппаратная платформа x86-64
Последняя версия
  • 19.03.5 ( 14 ноября2019 ) [6]
Состояние Активная разработка
Лицензия Apache License 2.0[7][8] и проприетарная лицензия[d]
Сайт docker.com​ (англ.)
Медиафайлы на Викискладе

Docker — программное обеспечение для автоматизации развёртывания и управления приложениями в средах с поддержкой контейнеризации. Позволяет «упаковать» приложение со всем его окружением и зависимостями в контейнер, который может быть перенесён на любую Linux-систему с поддержкой cgroups в ядре, а также предоставляет среду по управлению контейнерами. Изначально использовал возможности LXC, с 2015 года применял собственную библиотеку, абстрагирующую виртуализационные возможности ядра Linux — libcontainer. С появлением ​Open Container Initiative начался переход от монолитной к модульной архитектуре.

Разрабатывается и поддерживается одноимённой компанией-стартапом, распространяется в двух редакциях — общественной ( Community Edition ) по лицензии Apache 2.0 и для организаций ( Enterprise Edition ) по проприетарной лицензии [9] . Написан на языке Go.

Содержание

История [ править | править код ]

Проект начат как внутренняя собственническая разработка компании dotCloud, основанной Соломоном Хайксом (Solomon Hykes) в 2008 году с целью построения публичной PaaS-платформы с поддержкой различных языков программирования. Наряду с Хайксом в первоначальной разработке значительное участие приняли инженеры dotCloud Андреа Лудзарди (Andrea Luzzardi) и Франсуа-Ксавье Бурле (François-Xavier Bourlet).

В марте 2013 года код Docker был опубликован под лицензией Apache 2.0 [10] . В июне 2013 года генеральным директором в dotCloud приглашён Бен Голуб (англ. Ben Golub ), ранее руководивший фирмой Gluster [en] (разрабатывавшей технологию распределённого хранения GlusterFS и поглощённой за $136 млн Red Hat в 2011 году) [11] . В октябре 2013 года, подчёркивая смещение фокуса к новой ключевой технологии, dotCloud переименована в Docker (при этом PaaS-платформа сохранена под прежним названием — dotCloud).

В октябре 2013 года выпущен релиз Havana тиражируемой IaaS-платформы OpenStack, в котором реализована поддержка Docker (как драйвер для OpenStack Nova). С ноября 2013 года частичная поддержка Docker включена в дистрибутив Red Hat Enterprise Linux версии 6.5 [12] и полная — в 20-ю версию дистрибутива Fedora, ранее было достигнуто соглашение с Red Hat о включении с 2014 года Docker в тиражируемую PaaS-платформу OpenShift [en] [13] . В декабре 2013 года объявлено о поддержке развёртывания Docker-контейнеров в среде Google Compute Engine [en] [14] .

С 2014 года ведутся работы по включению поддержки Docker в среду управления фреймворка распределённых приложений Hadoop; по результатам тестирования вариантов платформы виртуализации для Hadoop, проведённом в мае 2014 года, Docker показал на основных операциях (по массовому созданию, перезапуску и уничтожению виртуальных узлов) существенно более высокую производительность, нежели KVM, в частности, на тесте массового создания виртуальных вычислительных узлов прирост потребления процессорных ресурсов в Docker зафиксирован в 26 раз ниже, чем в KVM, а прирост потребления ресурсов оперативной памяти — втрое ниже [15] .

Читайте также:  Asus eah5770 series драйвер

С 2017 года вдобавок к свободно распространяемой под лицензией Apache 2.0 редакции продукта выпускается редакция для организаций, продаваемая по ценам от $750 до $2 тыс. в год на узел в зависимости от доступных функций [9] .

Применение [ править | править код ]

Программное обеспечение функционирует в среде Linux с ядром, поддерживающим cgroups и изоляцию пространств имён (namespaces); существуют сборки только для платформ x86-64 и ARM [17] . Начиная с версии 1.6 возможно использование в ОС Windows [18] .

Для экономии дискового пространства проект использует файловую систему Aufs с поддержкой технологии каскадно-объединённого монтирования: контейнеры используют образ базовой операционной системы, а изменения записываются в отдельную область. Также поддерживается размещение контейнеров в файловой системе Btrfs с включённым режимом копирования при записи.

В состав программных средств входит демон — сервер контейнеров (запускается командой docker -d), клиентские средства, позволяющие из интерфейса командной строки управлять образами и контейнерами, а также API, позволяющий в стиле REST управлять контейнерами программно.

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

Набор клиентских средств позволяет запускать процессы в новых контейнерах (docker run), останавливать и запускать контейнеры (docker stop и docker start), приостанавливать и возобновлять процессы в контейнерах (docker pause и docker unpause). Серия команд позволяет осуществлять мониторинг запущенных процессов (docker ps по аналогии с ps в Unix-системах, docker top по аналогии с top и другие). Новые образы возможно создавать из специального сценарного файла (docker build, файл сценария носит название Dockerfile), возможно записать все изменения, сделанные в контейнере, в новый образ (docker commit). Все команды могут работать как с docker-демоном локальной системы, так и с любым сервером Docker, доступным по сети. Кроме того, в интерфейсе командной строки встроены возможности по взаимодействию с публичным репозиторием Docker Hub, в котором размещены предварительно собранные образы контейнеров, например, команда docker search позволяет осуществить поиск образов среди размещённых в нём [19] , образы можно скачивать в локальную систему (docker pull), возможно также отправить локально собранные образы в Docker Hub (docker push).

Также Docker имеет пакетный менеджер Docker Compose, позволяющий описывать и запускать многоконтейнерные приложения. Конфигурационные файлы Compose описываются на языке YAML [20] .

Если вы являетесь программистом или техником, то вы наверняка хотя бы слышали о Docker — полезном инструменте для упаковки, отправки и запуска приложений в «контейнерах». Трудно не знать об этой вещи, ведь в последнее время она получает много внимания от всех, начиная от разработчиков и заканчивая сисадминами. Даже такие крупные шишки, как Google, VMware и Amazon создают сервисы, поддерживающие Docker.

Независимо от того, использовали ли вы уже Docker или нет, я думаю, важно понять некоторые фундаментальные концепции того, что такое «контейнер», и сопоставить его с виртуальной машиной (VM). В то время как Интернет полон отличных руководств по использованию Docker, я не смог найти понятных для начинающих руководств о концепции, особенно о том, из чего состоит контейнер. Итак, надеюсь, этот пост решит эту проблему!

Давайте начнем с понимания того, что такое виртуальные машины и контейнеры.

Что такое «контейнеры» и «VM»?

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

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

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

Виртуальные машины

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

Давайте разберемся с жаргоном:

Гипервизор — это часть ПО, прошивки или аппаратного обеспечения, на которой работают виртуальные машины. Гипервизоры запускаются на физических компьютерах, называемых «хост-машинами». Хост-машина обеспечивает виртуальные машины ресурсами, включая оперативную память и процессор. Эти ресурсы делятся между виртуальными машинами и могут быть распределены по вашему усмотрению. Если на одной виртуальной машине работает более ресурсоемкое приложение, вы можете выделить больше ресурсов для нее, чем для других виртуальных машин, запущенных на одном и том же хосте.

Виртуальная машина, работающая на хосте (опять же, с использованием гипервизора), также часто называется «гостевой машиной». Этот гостевой компьютер содержит как приложение, так и все, что ему нужно для его запуска (например, системные двоичные файлы и библиотеки). Он также включает в себя весь собственный виртуализированный аппаратный стек (в него входят виртуализированные сетевые адаптеры, хранилище и процессор). Это означает, что у него также есть своя полноценная гостевая операционная система. Изнутри гостевая машина ведет себя как отдельное устройство с собственными ресурсами. С точки зрения извне, мы знаем, что это VM-ресурсы совместного доступа, предоставляемые хост-машиной.

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

Во-первых, хостовый гипервизор виртуализации работает на операционной системе хост-машины. Например, компьютер с OSX может иметь виртуальную машину (например, VirtualBox или VMware Workstation 8), установленную «поверх» этой ОС. У VM нет прямого доступа к аппаратным средствам, поэтому она должна проходить через операционную систему хоста (в нашем случае — Mac OSX).

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

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

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

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

Как вы можете видеть на диаграмме, каждая виртуальная машина содержит виртуальное оборудование, ядро (т. е. ОС) и пользовательское пространство.

Контейнеры

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

С точки зрения всех целей и задач контейнеры ничем не отличаются от виртуальных машин. Например, они могут иметь личное пространство для обработки, выполнять команды, такие как root, иметь частный сетевой интерфейс и IP-адрес, разрешать кастомные маршруты и правила iptable, монтировать файловые системы и т. д.

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

На этой диаграмме показано, что контейнеры содержат только пользовательское пространство, а не ядро или виртуальное оборудование, как в случае с VM. Каждый контейнер Docker получает свое изолированное пользовательское пространство, позволяющее нескольким контейнерам запускаться на одном хосте. Мы видим, что вся архитектура ОС делится между контейнерами. С нуля создаются только файлы bin, lib. Именно поэтому контейнеры такие легкие.

Когда же в дело вступает Docker?

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

Контейнеры — это не новое изобретение. Google использует собственные технологии контейнеров уже многие годы. Другие технологии контейнеров на Linux включают в себя Solaris Zones, BSD jails и LXC, которые существуют уже много лет.

Так почему же Docker внезапно набирает обороты?

  1. Простота использования: Docker упростил для всех (разработчиков, системных администраторов, архитекторов и других) использование контейнеров для быстрой сборки и тестирования портативных приложений. Это позволяет кому угодно передавать приложение на свой ноутбук. Такое приложение, в свою очередь, может работать без изменений в любом общедоступном облаке, в частном облаке или даже на чистом сервере. Девиз таков: «Создайте один раз, запускайте откуда угодно»;
  2. Скорость: Контейнеры в Docker очень легкие и быстрые. Поскольку контейнеры — это помещенные в «песочницу» среды, работающие на ядре, они потребляют меньше ресурсов. На создание и запуск Docker контейнеров тратятся мгновения по сравнению с VM. Работа с ними может занять больше времени, потому что каждый раз они должны загружать полную виртуальную ОС;
  3. Docker Hub: Пользователи Docker также получают выгоду от все больше богатеющей экосистемы Docker Hub, которую вы можете назвать «магазином приложений для образов Docker». Docker Hub содержит десятки тысяч общедоступных образов, созданных сообществом. Они легко доступны для использования. Теперь невероятно легко найти образы, которые отвечают вашим потребностям. Их уже можно взять и использовать практически без изменений;
  4. Модульность и масштабируемость: Docker позволяет легко разбить функциональность вашего приложения на отдельные контейнеры. Например, ваша база данных Postgres может работать в одном контейнере, а сервер Redis — в другом, приложение Node.js — в третьем. С Docker стало проще связать эти контейнеры вместе для создания приложения. В будущем это упростит масштабирование или обновление компонентов независимо друг от друга.
Читайте также:  Bus gov не заходит в личный кабинет

И наконец: кто же не любит кита Docker?

Фундаментальные Docker концепции

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

Docker Engine

Docker Engine — это слой, на котором работает Docker. Это легкая среда и набор инструментов, которые позволяют осуществлять управление контейнерами, образами, версиями и многим другим. По умолчанию эта часть работает на системах Linux и состоит из:

  • Docker Daemon (работает на хосте);
  • Docker Client (связывается с Docker Daemon, чтобы осуществлять команды);
  • REST API (для удаленного взаимодействия с Docker Daemon).

Docker Client

Клиент Docker — то, с чем вы, конечный пользователь Docker, взаимодействуете. Вы можете представить его как интерфейс Docker. Например, когда вы задаете:

Вы связываетесь с клиентом Docker, который впоследствии передает ваши инструкции Docker Daemon.

Docker Daemon

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

Dockerfile

Dockerfile — то, где вы пишете инструкции для создания образов Docker. Эти инструкции могут быть таковы:

  • Для установки пакета ПО: RUN apt-get y install some-package;
  • Для раскрытия порта: EXPOSE 8000;
  • Для передачи переменной среды: ENV ANT_HOME /usr/local/apache-ant.

Бывают и другие инструкции. Как только вы запустите Dockerfile, то сможете использовать команду docker build для создания образа. Вот пример Dockerfile:

Docker Image

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

Образы Docker создаются с помощью Dockerfile. Каждая инструкция в Dockerfile добавляет к образу новый «слой». Слои представляют собой часть файловой системы, которая либо дополняет слой под собой, либо заменяет его. Слои — ключ к легкой, но мощной структуре Docker. Для этого Docker применяет Union FS.

Union File System

Docker применяет Union FS для создания образов. Думайте о Union FS как о составной файловой системе. Это значит, что файлы и директории отдельных систем (их называют ветками) могут без перекодировки сформировать единую систему.

Содержимое директорий, которые имеют одинаковые пути в ветках, представляется в виде объединенного директория. Из-за этого не требуется создавать копии каждого слоя. Вместо этого они получат указатели к одному и тому же ресурсу. Когда вам понадобится изменить определенные слои, будет создана копия. Изменения будут происходить на копии, а оригинал останется нетронутым. Поэтому вам может казаться, что файловые системы можно переписать, хотя на самом деле они этого не позволяют. (Другими словами, это система «копирование при записи».)

Многоуровневые системы имеют 2 главных преимущества:

  • Свободное копирование: слои помогают избежать необходимости дублировать полный набора файлов каждый раз, когда вы используете образ для создания и запуска нового контейнера. Это делает создание контейнеров в Docker очень быстрым и «дешевым»;
  • Разделение слоев: внесение изменений происходит намного быстрее — при изменении образа Docker распространяет обновления только на слой, который был изменен.

Volume

Volume — это часть контейнера, ответственная за данные. Ее инициализация происходит при создании контейнера. Volume позволяют хранить и передавать данные контейнера. Volume отделены от обычной Union FS. Они существуют в виде обычных директорий и файлов в хостовой системе файлов. Даже если вы разрушите, обновите или рекомпилируете контейнер Docker, данные Volume останутся нетронутыми. Если вы хотите обновить Volume, нужно изменять его напрямую. (Дополнительное преимущество: данные в Volume можно распределять и использовать в нескольких контейнерах, что достаточно удобно.)

Контейнеры Docker

Контейнер Docker, как говорилось выше, упаковывает ПО приложения в невидимую «коробку», в которой есть все, что необходимо для запуска приложения. Туда входят ОС, код приложения, среда, инструменты, библиотеки и т. д. Контейнеры Docker создаются из образов. Так как образы доступны только для чтения, для создания контейнера Docker добавляет файловую систему «чтение/запись» поверх системы «read-only».

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

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

Применение двойного клика к контейнерам

Фух! Как много подвижных частей. Меня всегда интересовало: а как контейнеры вообще создаются? Вокруг них ведь нет какой-то абстрактной инфраструктуры. Я много читал, и теперь все стало ясно. Я попытаюсь объяснить это вам!

Термин «контейнер» на самом деле является просто абстрактным понятием, описывающим, как несколько различных функций работают вместе для визуализации «контейнера». Давайте очень быстро пробежимся по ним:

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

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

В ядре используется несколько различных типов пространств имен, например:

a. NET: Предоставляет контейнер с собственным представлением сетевого стека системы (например, собственные сетевые устройства, IP-адреса, таблицы IP-маршрутизации, каталог /proc/net, номера портов и т. д.);

b. P >ps aux в командной строке, чтобы проверить, какие процессы запущены в вашей системе, вы видели столбец с названием «PID». Пространство имен PID дает контейнерам свое собственное видение процессов, которые они могут просматривать и с которыми способны взаимодействовать, включая независимый init (PID 1), который является «предком всех процессов»;

c. MNT: дает контейнеру собственное представление о «монтировании» в системе. Таким образом, процессы в разных пространствах имеют разные представления об иерархии файловой системы;

d. UTS: UTS обозначает UNIX Timesharing System. Это позволяет процессу идентифицировать системные идентификаторы (т. е. имя хоста, имя домена и т. д.). UTS позволяет контейнерам иметь свое собственное имя хоста и имя домена NIS, которое не зависит от других контейнеров и хост-системы;

e. IPC: IPC расшифровывается как InterProcess Communication. Пространство имен IPC отвечает за изоляцию ресурсов IPC между процессами, выполняющимися внутри каждого контейнера;

f. USER: это пространство имен используется для изоляции пользователей в каждом контейнере. Он функционирует, позволяя контейнерам иметь другое представление диапазонов uid (идентификатор пользователя) и gid (идентификатор группы) по сравнению с хост-системой. В результате uid и gid процесса могут различаться внутри и снаружи пространства имен пользователя. Это позволяет процессу иметь непривилегированного пользователя вне контейнера, не жертвуя привилегиями root внутри него.

Docker использует эти пространства имен вместе, чтобы изолировать и начать создание контейнера. Следующий элемент — контрольные группы.

2) Контрольные группы

Контрольные группы (также называются cgroups) — это функция ядра Linux, которая изолирует, расставляет приоритеты и учитывает использование ресурсов (ЦП, память, дисковый ввод-вывод, сеть и т. д.) для набора процессов. Cgroup гарантирует, что контейнеры Docker используют только те ресурсы, которые им необходимы, и при необходимости устанавливает ограничения на то, какие ресурсы контейнер может использовать. Cgroups также гарантирует, что единственный контейнер не исчерпает один из этих ресурсов и не разрушит всю систему.

Наконец, Docker также использует Union FS.

3) Изолированная Union FS

Описана выше в разделе «Docker Image».

Вот и все, что существует в контейнере Docker. Конечно, все трудности начинаются в деталях осуществления: например, как управлять взаимодействиями между различными компонентами?

Будущее Docker: сосуществование Docker и VM

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

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

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

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

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

Заключение

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

Ссылка на основную публикацию
Adblock detector