
Изд. № 29
.pdf
время как другие являются приватными, доступными только для определенных людей или машин;
контейнеры. Контейнер на основе Docker – это обычный контейнер Linux, созданный из образа контейнера на основе Docker. Выполняемый контейнер – это процесс, запущенный на хосте, на котором работает Docker, но он полностью изолирован как от хоста, так и от всех других процессов, запущенных на нём. Процесс также ограничен ресурсами, имея в виду, что он может получать доступ и использовать только тот объём ресурсов (ЦП, ОЗУ и т.д.), который ему выделен.
Создание, распространение и запуск образа Docker
На рисунке 6 показаны все три понятия и их взаимосвязь. Разработчик сначала создает образ, а затем помещает его в хранилище. Таким образом, образ доступен всем, кто имеет доступ к хранилищу. Затем он может закачать образ на любую другую машину, на которой выполняется Docker, и запустить образ. Docker создает изолированный контейнер на основе образа и выполняет двоичный исполняемый файл, указанный в рамках образа.
Рисунок 6 - Образы, реестры и контейнеры Docker
20

На рисунке 7 представлены компоненты платформы Docker.
Рисунок 7 - Компоненты платформы Docker
Docker host (докер-хост). Это компьютер, на котором работает докер. Это может быть обычный персональный компьютер, сервер или виртуальная машина в облаке.
Docker daemon (докер-демон). Фоновая служба на хосте, которая работает постоянно и отвечает за создание, запуск и уничтожение контейнеров. Все операции по управлению контейнерами отправляются именно в демон.
Client докер-(клиент). Утилита командной строки в Docker для управления демоном. Чрез клиента пользователи взаимодействуют с демоном и отправляют ему команды. Это может быть консоль, API или графический интерфейс. Любое взаимодействие с контейнером проходит через Daemon.
•Docker pull - команда скачивает образ из docker registry и помещает его в локальное хранилище на хосте;
•Docker build - команда читает докер-файл и собирает образ;
•Docker run - команда создает из образа контейнер и запускает его.
Image (докер-образ). Это неизменяемый образ, из которого разворачивается контейнер. Его можно рассматривать как набор файлов, необходимых для запуска и работы приложения на другом хосте.
Container (докер-контейнер). Запущенное приложение, которое развернули из образа.
21

Registry (реестр, репозиторий). Служба в Docker, выполняющая функции репозитория (хранилища). Позволяет следить за версиями образов, создавать приватные репозитории. Есть публичные репозитории, например Docker Hub, используемый по умолчанию в Docker. Можно создать свой репозиторий для использования внутри компании или команды.
Dockerfile (докер-файл). Текстовый файл с последовательно расположенными инструкциями для создания образа Docker. Файл создаётся по принципу «одна строка — одна команда».
Сравнение виртуальных машин и контейнеров Docker
Как уже говорилось выше, контейнеры Linux в общем похожи на виртуальные машины, но гораздо облегчённее. Рассмотрим, чем конкретно контейнеры Docker отличаются от виртуальных машин (и чем образы Docker отличаются от образов виртуальных машин). На рисунке 8 снова показаны те же шесть приложений, работающих как в виртуальных машинах, так и в контейнерах Docker.
Рисунок 8 - Выполнение шести приложений на трех виртуальных машинах по сравнению с их выполнением в контейнерах Docker
Приложения A и B имеют доступ к одним и тем же двоичным файлам и библиотекам как при работе в виртуальной машине, так и при работе в виде двух отдельных контейнеров. В виртуальной машине это очевидно, поскольку оба приложения видят одну и ту же файловую систему (виртуальную машину). Но каждый контейнер имеет свои собственные, изолированные системы. Каким образом Приложение A и Приложение B могут совместно использовать одни и те же файлы?
22

Слои образа
Как уже отмечалось ранее, образы Docker состоят из слоев. Разные образы могут содержать одни и те же слои, поскольку каждый слой Docker надстроен поверх другого образа, а два разных образа могут использовать один и тот же родительский образ в качестве основы. Это ускоряет распределение образов по сети, так как слои, которые уже были перенесены как часть первого образа, не нужно передавать снова при передаче другого образа.
Но слои не только делают распределение более эффективным, они также помогают уменьшить объём хранения образов. Каждый слой хранится только один раз. Таким образом, два контейнера, созданные из двух образов, основанных на одних и тех же базовых слоях, могут читать одни и те же файлы, но если один из них записывает эти файлы, другой не видит этих изменений. Таким образом, даже если они совместно используют файлы, они по-прежнему изолированы друг от друга (рисунок 9). Это работает, поскольку слои образов контейнеров доступны только для чтения.
Рисунок 9 - Слои образа и контейнера
При запуске контейнера поверх слоев образа создается новый слой, доступный для записи. Когда процесс в контейнере записывает в файл, расположенный в одном из низлежащих слоев, копия всего файла создается в верхнем слое, и процесс записывает в копию (рисунок 10).
23

Рисунок 10 - Создание контейнеров
Ограничения переносимости образов контейнеров
Теоретически образ контейнера может быть выполнен на любой машине Linux, в которой работает Docker, но существует одно небольшое предостережение, связанное с тем, что все контейнеры, работающие на хосте, используют Linux’овское ядро хоста. Если контейнеризированное приложение требует конкретной версии ядра, оно может работать не на каждой машине. Если на машине работает другая версия ядра Linux или на ней нет доступных модулей ядра, приложение не сможет на нем работать.
Контейнеры – гораздо облегчённее, по сравнению с виртуальными машинами, вместе с тем они накладывают определенные ограничения на приложения, работающие внутри них. Виртуальные машины не имеют таких ограничений, так как каждая виртуальная машина выполняет свое собственное ядро.
И дело не только в ядре. Также должно быть ясно, что контейнеризированное приложение, созданное для определенной аппаратной архитектуры, может выполняться на других машинах только с такой же архитектурой. Вы не можете контейнеризировать приложение, созданное для архитектуры x86, и ожидать, что оно будет работать на машине на базе ARM, поскольку оно также запускает Docker. Для этого по-прежнему будет нужна виртуальная машина.
24
В таблице 1 приведено сравнение Docker-контейнеров и виртуальных машин.
Таблица 1 - Сравнение Docker-контейнеров и виртуальных машин
Характеристика |
Docker-контейнеры |
Виртуальные машины |
|
|
|
Уровень изоляции |
Операционная система |
Аппаратное обеспечение |
|
|
|
Ресурсоёмкость |
Меньше |
Больше |
|
|
|
Запуск и остановка |
Быстрее |
Медленнее |
|
|
|
Размер |
Меньше |
Больше |
|
|
|
Изоляция |
Менее глубокая |
Глубокая |
|
|
|
Нагрузка на хост-систему |
Меньше |
Больше |
|
|
|
Совместимость |
Ограниченная |
Высокая |
|
|
|
Виртуализация ОС |
Да |
Да |
|
|
|
Гипервизор |
Не требуется |
Требуется |
|
|
|
Контрольные вопросы к разделу 2
1.Что такое контейнеры?
2.Где выполняется процесс, запущенный в контейнере?
3.Чем отличается виртуальная машина от контейнера?
4.Чем отличаются два типа гипервизоров?
5.Какое преимущество в виртуальных машинах?
6.Чем отличается образ(image) от контейнера?
7.Что такое Docker?
8.Из чего состоят образы в Docker?
9.Компоненты платформы Docker?
25
3. Kubernetes
По мере роста количества разворачиваемых компонентов приложений
всистеме становится все труднее управлять ими всеми. Google, вероятно, была первой компанией, которая поняла, что ей нужен гораздо более оптимальный способ развертывания и управления их программными компонентами и их инфраструктурой, с тем чтобы обеспечить масштабируемость в глобальном масштабе. Это одна из немногих компаний
вмире, которая управляет сотнями тысяч серверов и имеет дело с управлением развертываниями в таком массовом масштабе. Что вынудило их разрабатывать решения, позволяющие сделать разработку и развертывание тысяч программных компонентов управляемым и экономичным.
На протяжении многих лет разработанная в Google внутренняя система под названием Borg (а позже новая система под названием Omega) помогала как разработчикам приложений, так и системным администраторам управлять тысячами приложений и служб. В дополнение к упрощению процесса разработки и управления она также помогала им достигать гораздо более высокой степени задействованности их инфраструктуры, что важно, когда организация настолько большая. Это позволило сэкономить миллионы долларов.
Продержав целое десятилетие системы Borg и Omega в секрете, в 2014 году Google анонсировала Kubernetes, систему с открытым исходным кодом, основанную на опыте, приобретенном благодаря Borg, Omega и другим внутренним системам Google.
3.1. Общее представление о Kubernetes
Kubernetes – это программная система, которая позволяет легко развёртывать контейнеризированные приложения и управлять ими. Она использует возможности контейнеров Linux для запуска разнородных приложений без необходимости знать какие-либо внутренние детали этих приложений и без необходимости вручную развёртывать эти приложения на каждом хосте. Поскольку данные приложения работают в контейнерах, они не влияют на другие приложения, работающие на том же сервере, что имеет решающее значение при запуске приложений для совершенно разных организаций на одном и том же оборудовании. Это имеет первостепенное значение для облачных провайдеров, поскольку они стремятся к максимально возможной задействованности своего оборудования, сохраняя при этом полную изоляцию размещённых приложений.
26

Kubernetes позволяет выполнять программные приложения на тысячах компьютерных узлов, как если бы все эти узлы были одним огромным компьютером. Она абстрагируется от базовой инфраструктуры и тем самым упрощает разработку, развёртывание и управление как для разработчиков, так и для системных администраторов.
Процедура развёртывания приложений через Kubernetes всегда одинаковая, независимо от того, содержит ли кластер всего несколько узлов или тысячи. Размер кластера не имеет никакого значения. Дополнительные узлы кластера просто представляют собой дополнительный объём ресурсов, доступных для развернутых приложений.
Рисунок 11 показывает простейший вид системы Kubernetes. Система состоит из ведущего узла (мастера) и любого количества рабочих узлов. Когда разработчик отправляет список приложений ведущему узлу, Kubernetes развёртывает их в кластере рабочих узлов. То, на какой узел приземляется компонент, не имеет (и не должно иметь) значения ни для разработчика, ни для системного администратора.
Рисунок 11 - Kubernetes обеспечивает доступ ко всему центру обработки данных как единой платформе развёртывания
Разработчик может указать, что определённые приложения должны выполняться вместе, и Kubernetes развернёт их на одном рабочем узле. Другие будут разбросаны по всему кластеру, но они могут обмениваться между собой одинаково, независимо от того, где они развернуты.
Для разработчиков
Kubernetes можно рассматривать как операционную систему для кластера. Она избавляет разработчиков приложений от необходимости внедрять в свои приложения определённые службы, связанные с
27

инфраструктурой; вместо этого в вопросе предоставления этих служб они опираются на Kubernetes. Это включает в себя такие аспекты, как обнаружение службы, масштабирование, балансировка нагрузки, самовосстановление и даже выбор лидера. Поэтому разработчики приложений могут сосредоточиться на реализации реального функционала приложений и не тратить время на то, чтобы разбираться в том, как интегрировать их с инфраструктурой.
Для системных администраторов
Kubernetes будет выполнять контейнеризованное приложение гденибудь в кластере, предоставит информацию его компонентам о том, как отыскать друг друга, и будет поддерживать их в работающем состоянии. Поскольку приложению все равно, на каком узле оно работает, Kubernetes может перемещать приложение в любое время и путем смешивания и отождествления приложений добиваться гораздо лучшей задействованности ресурсов, чем это возможно при ручном планировании.
3.2. Архитектура кластера Kubernetes
Рассмотрим более подробно архитектуру кластера Kubernetes. На аппаратном уровне кластер Kubernetes состоит из множества узлов, которые можно разделить на два типа:
ведущий узел (мастер, master node), на котором размещена плоскость управления (Control Plane) Kubernetes, контролирующая и управляющая всей системой Kubernetes;
рабочие узлы (worker node), на которых выполняются развертываемые приложения.
На рисунке 12 показаны компоненты, работающие на этих двух
наборах узлов.
Рисунок 12 - Компоненты, составляющие кластер Kubernetes
28
Плоскость управления
Плоскость управления – это то, что управляет кластером и заставляет его функционировать. Она состоит из нескольких компонентов, которые могут работать на одном ведущем узле либо быть распределены по нескольким узлам и реплицированы для обеспечения высокой доступности:
сервер Kubernetes API, с которым взаимодействуют пользователь и другие компоненты плоскости управления;
планировщик, который распределяет приложения (назначает рабочий узел каждому развёртываемому компоненту приложения);
менеджер контроллёров, выполняющий функции кластерного уровня, такие как репликация компонентов, отслеживание рабочих узлов, обработка аварийных сбоев узлов и т.д.;
etcd, надёжное распределённое хранилище данных, которое непрерывно сохраняет конфигурацию кластера.
Компоненты плоскости управления содержат и управляют состоянием
кластера, но не выполняют приложения. Это делается (рабочими) узлами.
Узлы
Рабочие узлы – это машины, на которых выполняются контейнеризированные приложения. Задача выполнения, мониторинга и предоставления служб приложениям выполняется следующими компонентами:
Docker или другая среда выполнения контейнеров, в которой выполняются контейнеры;
Kubelet, агент, который обменивается с сервером API и управляет контейнерами на своём узле;
служебный прокси Kubernetes (kube-proxy), который балансирует нагрузку сетевого трафика между компонентами приложения.
Модуль (pod)
Модуль (pod) – это группа, состоящая из одного или нескольких тесно связанных контейнеров, которые всегда будут выполняться вместе на одном рабочем узле и в одном пространстве имен Linux. Каждый модуль подобен отдельной логической машине с собственным IP-адресом, сетевым именем, процессами и т.д., выполняющей одно приложение. Приложение может быть одним процессом, выполняемым в одном контейнере, или же главным
29