Паттерны Kubernetes: Шаблоны разработки собственных облачных приложений
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабын онлайн тегін оқу  Паттерны Kubernetes: Шаблоны разработки собственных облачных приложений

 

Билджин Ибрам, Роланд Хасс
Паттерны Kubernetes: Шаблоны разработки собственных облачных приложений
2020

Научный редактор М. Малявин

Переводчик А. Макарова

Литературный редактор А. Руденко

Художники В. Мостипан, А. Шляго (Шантурова)

Корректоры С. Беляева, Н. Викторова

Верстка Л. Егорова

 

Билджин Ибрам, Роланд Хасс

Паттерны Kubernetes: Шаблоны разработки собственных облачных приложений. — СПб.: Питер, 2020.

 

ISBN 978-5-4461-1443-6

© ООО Издательство "Питер", 2020

 

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

 

Предисловие

Начиная работу над фреймворком Kubernetes почти пять лет назад, мы — Крейг, Джо и я  — понимали, что он способен изменить мир разработки и доставки программного обеспечения. Но мы не думали, что это изменение произойдет так быстро. В настоящее время Kubernetes служит основой для создания переносимых и надежных систем для основных общедоступных и частных облаков, а также невиртуализированных окружений. Несмотря на широкую распространенность фреймворка Kubernetes, благодаря которой кластер в облаке можно развернуть менее чем за пять минут, многие недостаточно четко представляют, что делать дальше, после создания этого кластера. Мы добились значительных успехов в практической реализации самого Kubernetes, но это только часть решения. Это фундамент, на котором создаются приложения. Он предлагает обширную библиотеку инструментов для их создания, но почти не дает советов и рекомендаций архитекторам или разработчикам приложений, как можно объединить различные части этого фундамента, чтобы получить законченную надежную систему, соответствующую целям и потребностям.

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

Вот почему книга Билджина и Роланда имеет особую ценность. «Паттерны Kubernetes» знакомят вас с опытом, который мы вложили в API и инструменты, составляющие Kubernetes. Фреймворк Kubernetes является воплощением опыта, накопленного сообществом разработчиков, занимающихся созданием высоконадежных распределенных систем в разных окружениях. Каждый объект и каждая возможность, добавленные в Kubernetes, — это основополагающий инструмент, разработанный и созданный специально для удовлетворения конкретной потребности. В этой книге рассказывается, как использовать идеи, заложенные в Kubernetes, для решения практических задач и построения своей системы.

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

Брендан Бернс (Brendan Burns), разработчик Kubernetes

Вступление

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

Kubernetes

Kubernetes — это платформа для управления контейнерами. Зарождение Kubernetes произошло где-то в центрах обработки данных компании Google, где появилась внутренняя платформа управления контейнерами Borg (https://research.google.com/pubs/pub43438.html). Платформа Borg много лет использовалась в Google для запуска приложений. В 2014 году  Google решил передать свой опыт работы с Borg новому проекту с открытым исходным кодом под названием Kubernetes (в переводе с греческого «кормчий», «рулевой»), а в 2015 году он стал первым проектом, переданным в дар недавно основанному фонду Cloud Native Computing Foundation (CNCF).

С самого начала проект Kubernetes приобрел целое сообщество пользователей, и число участников росло невероятно быстрыми темпами. В настоящее время Kubernetes считается одним из самых активных проектов на GitHub. Можно даже утверждать, что на момент написания этой книги Kubernetes был наиболее часто используемой и многофункциональной платформой управления контейнерами. Kubernetes также формирует основу других платформ, построенных поверх него. Наиболее известной из таких систем вида «платформа как услуга» (Platform-as-a-Service) является Red Hat OpenShift, которая добавляет в Kubernetes различные дополнительные возможности, в том числе способы создания приложений на этой платформе. Это только часть причин, по которым мы выбрали Kubernetes в качестве эталонной платформы для описания паттернов использования облачных систем в этой книге.

Эта книга предполагает наличие у читателя некоторых базовых знаний о Kubernetes. В главе 1 мы перечислим основные понятия Kubernetes и заложим основу для обсуждения паттернов в следующих главах.

Паттерны проектирования

Понятие паттернов, или шаблонов, проектирования появилось в 1970-х годах в области архитектуры. Кристофер Александер (Christo­pher Alexander), архитектор и системный теоретик, и его команда опубликовали в 1977 году новаторский труд «A Pattern Language»1 (Oxford University Press), в котором описываются архитектурные шаблоны создания городов, зданий и других строительных проектов. Некоторое время спустя эта идея была принята недавно сформировавшейся индустрией программного обеспечения. Самая известная книга в этой области — «Приемы объектно-ориентированного проектирования. Паттерны проектирования» Эриха Гаммы, Ричарда Хелма, Ральфа Джонсона и Джона Влиссидеса — «Банды четырех» (Addison-Wesley). Когда мы говорим об известных паттернах «Одиночка» (Singleton), «Фабрика» (Factories) или «Делегирование» (Delegation), то используем названия, данные в этой книге. С тех пор было написано много других замечательных книг о паттернах для различных областей с разной степенью подробностей, таких как «Enterprise Integration Patterns»2 Грегора Хопа (Gregor Hohpe) и Бобби Вульфа (Bobby Woolf) или «Patterns of Enterprise Application Architecture»3 Мартина Фаулера (Martin Fowler).

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

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

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

Другая особенность паттернов заключается в том, что они следуют жесткому формату. Однако каждый автор определяет свой формат, и, к сожалению, нет единого стандарта, который определял бы, как должны излагаться паттерны. Мартин Фаулер дает превосходный обзор форматов, используемых для языков паттернов, в своей статье «Writing Software Patterns» (http://bit.ly/2HIuUdJ).

Структура книги

Мы выбрали простой паттерн структуры книги. Мы не придерживаемся какого-либо конкретного языка и для описания каждого паттерна используем следующую структуру:

Название

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

Задача

В этом разделе дается широкий контекст и подробное описание пространства паттерна.

Решение

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

Пояснение

Обзор достоинств и недостатков решения в данном контексте.

Дополнительная информация

Этот заключительный раздел содержит источники дополнительной информации, касающейся паттерна.

Мы организовали паттерны в этой книге следующим образом:

• Часть I Основные паттерны охватывает основные понятия Kubernetes и перечисляет основополагающие принципы и практики создания облачных приложений на основе контейнеров.

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

• Часть III Структурные паттерны содержит паттерны, имеющие отношение к организации контейнеров в поды (pod) — элементарные единицы платформы Kubernetes.

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

• Часть V Дополнительные паттерны знакомит с дополнительными понятиями, например, как можно расширить саму платформу или как создавать образы контейнеров непосредственно внутри кластера.

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

Кому адресована эта книга

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

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

Что вы узнаете

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

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

Прежде чем начать погружение, кратко перечислим, чем не является эта книга:

• Эта книга не является руководством по настройке самого кластера Kubernetes. Каждый паттерн и каждый пример предполагает, что вы уже настроили и запустили Kubernetes. Опробовать примеры можно несколькими способами. Желающим узнать, как настроить кластер Kubernetes, рекомендуем книгу «Managing Kubernetes» Брендана Бернса (Brendan Burns) и Крейга Трейси (Craig Tracey), изданную в O’Reilly (https://oreil.ly/2HoadnU). Кроме того, книга «Kubernetes Cookbook» Майкла Хаузенбласа (Michael Hausenblas) и Себастьяна Гоасгена (S

bastien Goasguen), изданная в O’Reilly (http://bit.ly/2FTgJzk), содержит рецепты создания кластера Kubernetes с нуля.

• Эта книга не является ни введением в Kubernetes, ни справочным руководством. Мы затрагиваем многие особенности Kubernetes и объясняем их до определенной степени, но основное внимание уделяется идеям, лежащим в основе этих особенностей. В главе 1 «Введение» предлагается краткий обзор основ Kubernetes. Если вы ищете исчерпывающую книгу об использовании Kubernetes, мы настоятельно рекомендуем книгу «Kubernetes in Action»5 Марко Лукши (Marko Luk

a), изданную в Manning Publications.

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

Типографские соглашения

Как уже упоминалось, паттерны образуют простой, взаимосвязанный язык. Чтобы подчеркнуть эту взаимосвязь, названия паттернов записываются курсивом (например, Sidecar (Прицеп)). Когда паттерн получает название по базовому понятию Kubernetes (например, Init Container (Инициализирующий контейнер) или Controller (Контроллер)), мы используем такой способ оформления только для прямых ссылок на сам паттерн. Там, где это имеет смысл, мы также даем ссылки на главы с описаниями паттернов для упрощения навигации.

Мы также используем следующие соглашения:

• Все, что вводится в командной оболочке или в редакторе, будет оформляться моноширинным шрифтом.

• Имена ресурсов Kubernetes всегда записываются с заглавной буквы (например, Pod). Если ресурс имеет комбинированное имя, такое как ConfigMap, мы используем его вместо более естественного обозначения «config map» (конфигурационная карта), чтобы подчеркнуть, что имеется в виду понятие Kubernetes.

• Имена некоторых ресурсов Kubernetes совпадают с общими понятиями, такими как «служба» или «узел». В этих случаях мы используем оформление, характерное для имен ресурсов, только для ссылок на ресурсы.

Использование примеров кода

Описание каждого паттерна сопровождается примерами, которые вы можете найти на веб-странице книги (https://k8spatterns.io/). Также ссылки на примеры для каждого паттерна приводятся в разделе «Дополнительная информация» в каждой главе.

В разделе «Дополнительная информация» также приводятся ссылки на дополнительную информацию, имеющую отношение к паттерну. Мы постоянно обновляем эти списки в репозитории примеров. Изменения в коллекциях ссылок также будут публиковаться в Twitter (https://twitter.com/k8spatterns).

Исходный код всех примеров в этой книге доступен в GitHub (https://github.com/k8spatterns). Репозиторий и веб-сайт также содержат указания и инструкции о том, как создать кластер Kubernetes для опробования примеров. Просматривая примеры, также загляните в предоставляемые файлы ресурсов. В них вы найдете много полезных комментариев, помогающих понять код примера.

Во многих примерах используется REST-служба random-generator, которая возвращает случайные числа. Она специально создавалась для опробования примеров из этой книги. Исходный код этой службы тоже можно найти в GitHub (https://github.com/k8spatterns/random-generator), а ее образ для развертывания в контейнере k8spatterns/random-generator добавлен в каталог Docker Hub.

Для описания полей ресурсов мы используем обозначение путей в формате JSON. Например, .spec.replicas — это ссылка на поле replicas в разделе spec ресурса.

Если вы найдете ошибку в коде примера или в документации или если у вас появится вопрос, смело создавайте заявку в трекере проблем GitHub (https://github.com/k8spatterns/examples/issues). Мы следим за появлением заявок и с радостью отвечаем на любые вопросы.

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

Благодарности

Создание этой книги было долгим путешествием, продолжавшимся два года, и мы хотим поблагодарить всех наших рецензентов, помогавшим нам не сбиться с пути. Особую благодарность хотим выразить Паоло Антинори (Paolo Antinori) и Андреа Тарокки (Andrea Tarocchi), помогавшим нам в этом путешествии. Большое спасибо также Марко Лукше (Marko Luk

a), Брендону Филипсу (Brandon Philips), Майклу Хуттерманну (Michael H
ttermann), Брайану Грейсли (Brian Gracely), Эндрю Блоку (Andrew Block), Иржи Кремсеру (Jiri Kremser), Тобиасу Шнеку (Tobias Schneck) и Рику Вагнеру (Rick Wagner), которые поддержали нас своим опытом и советами. Наконец, но не в последнюю очередь, большое спасибо нашим редакторам Вирджинии Уилсон (Virginia Wilson), Джону Девинсу (John Devins), Кэтрин Тозер (Katherine Tozer), Кристине Эдвардс (Christina Edwards) и всем замечательным сотрудникам O’Reilly за то, что помогли довести эту книгу до финала.

От издательства

Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).

Мы будем рады узнать ваше мнение!

На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.

Кристофер Александер, Сара Исикава, Мюррей Силверстайн. Язык шаблонов. Города. Здания. Строительство. Издательство Студии Артемия Лебедева, 2014. — Примеч. пер.

Хоп Грегор, Вульф Бобби. Паттерны интеграции корпоративных приложений. М.: Вильямс, 2016. — Примеч. пер.

Мартин Фаулер, Дейвид Райс, Мэттью Фоммел, Эдвард Хайет, Роберт Ми, Рэнди Стаффорд. Паттерны корпоративных приложений. М.: Вильямс, 2016. — Примеч. пер.

Кристофер Александер и его команда определили первоначальное значение слова «паттерн» в контексте архитектуры следующим образом: «Каждый паттерн дает описание той или иной проблемы, регулярно возникающей в окружающем нас пространстве, вслед за которым представлена суть решения данной проблемы, сформулированная таким образом, чтобы вы могли многократно использовать это решение, но никогда не копировать его» (Кристофер Александер, Сара Исикава, Мюррей Силверстайн. Язык шаблонов. Города. Здания. Строительство. С. 20). Мы считаем, что это определение прекрасно подходит также для паттернов, которые описываются в этой книге, с той лишь разницей, что у нас, пожалуй, не так много свободы в реализации решений.

Лукша Марко. Kubernetes в действии. М.: ДМК Пресс, 2018. — Примеч. пер.

Кристофер Александер и его команда определили первоначальное значение слова «паттерн» в контексте архитектуры следующим образом: «Каждый паттерн дает описание той или иной проблемы, регулярно возникающей в окружающем нас пространстве, вслед за которым представлена суть решения данной проблемы, сформулированная таким образом, чтобы вы могли многократно использовать это решение, но никогда не копировать его» (Кристофер Александер, Сара Исикава, Мюррей Силверстайн. Язык шаблонов. Города. Здания. Строительство. С. 20). Мы считаем, что это определение прекрасно подходит также для паттернов, которые описываются в этой книге, с той лишь разницей, что у нас, пожалуй, не так много свободы в реализации решений.

Мартин Фаулер, Дейвид Райс, Мэттью Фоммел, Эдвард Хайет, Роберт Ми, Рэнди Стаффорд. Паттерны корпоративных приложений. М.: Вильямс, 2016. — Примеч. пер.

Лукша Марко. Kubernetes в действии. М.: ДМК Пресс, 2018. — Примеч. пер.

Хоп Грегор, Вульф Бобби. Паттерны интеграции корпоративных приложений. М.: Вильямс, 2016. — Примеч. пер.

Кристофер Александер, Сара Исикава, Мюррей Силверстайн. Язык шаблонов. Города. Здания. Строительство. Издательство Студии Артемия Лебедева, 2014. — Примеч. пер.

Глава 1. Введение

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

Эта глава не является обязательным условием для понимания паттернов, описываемых далее. Читатели, знакомые с понятиями Kubernetes, могут пропустить ее и сразу перейти к интересующей их категории.

Путь в облачное окружение

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

Существует большое количество теоретических и практических методов создания микросервисов с нуля или деления монолитных приложений на микросервисы. Большинство из этих методов основаны на приемах, описанных в книге Эрика Эванса (Eric Evans) «Domain-Driven Design»6 (Addison-Wesley), и понятиях ограниченного контекста и агрегатов. Ограниченные контексты непосредственно связаны с большими моделями и делят их на разные компоненты, и агрегаты помогают группировать ограниченные контексты в модули с определенными границами транзакций. Однако кроме этих понятий, характерных для каждой предметной области, для каждой распределенной системы, независимо от того, основана она на микросервисах или нет, существует множество технических проблем, связанных с их организацией, структурой и поведением во время выполнения.

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

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

 

Рис. 1.1. Путь в облачное окружение

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

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

• Предметно-ориентированное проектирование (Domain-Driven De­sign, DDD) — это подход к проектированию программного обеспечения с позиции бизнеса с целью получить архитектуру, как можно более близкую к реальному миру. Он лучше всего соответствует объектно-ориентированным языкам программирования, но есть и другие хорошие подходы к моделированию и проектированию программного обеспечения для решения практических задач. Модель с правильно выбранными границами, простыми в использовании интерфейсами и многофункциональным API является основой для успешной контейнеризации и автоматизации в дальнейшем.

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

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

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

Распределенные примитивы

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

Язык Java и виртуальная машина Java (Java Virtual Machine, JVM) предоставляют локальные, внутрипроцессные строительные блоки для создания приложений. Kubernetes добавляет в эту привычную картину совершенно новое измерение, предлагая новый набор распределенных примитивов и среды выполнения для создания распределенных систем, разбросанных по нескольким узлам и процессам. Используя Kubernetes для реализации всего поведения приложения, мы больше не полагаемся только на локальные примитивы.

Таблица 1.1. Локальные и распределенные примитивы7

Понятие

Локальный примитив

Распределенный примитив

Инкапсуляция поведения

Класс

Образ контейнера

Экземпляр поведения

Объект

Контейнер

Единица повторного использования

.jar

Образ контейнера

Композиция

Класс A содержит класс B

Шаблон Sidecar (Прицеп)

Наследование

Класс A расширяет класс B

Контейнер A создается из родительского образа

Единица развертывания

.jar/.war/.ear

Под (Pod)

Изоляция времени сборки/выполнения

Модуль, Пакет, Класс

Пространство имен, под, контейнер

Начальная инициализация

Конструктор

Инициализирующие контейнеры, или Init-контейнеры

Операции, следующие сразу за начальной инициализацией

Метод Init

postStart

Операции, непосредственно предшествующие уничтожению экземпляра

Метод Destroy

preStop

Процедура освобождения ресурсов

finalize(), обработчик события завершения

Деинициализированный контейнер1

Асинхронное и параллельное выполнение

ThreadPoolExecutor, ForkJoinPool

Задание

Периодическое выполнение

Timer, ScheduledExecutorService

Планировщик заданий

Фоновое выполнение

Фоновые потоки выполнения

Контроллер набора демонов (DaemonSet)

Управление конфигурацией

System.getenv(), Properties

Карта конфигураций (ConfigMap), секрет (Secret)

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

Внутрипроцессные и распределенные примитивы имеют общие черты, но их нельзя сравнивать непосредственно и они не являются взаимозаменяемыми. Они работают на разных уровнях абстракции и имеют разные предпосылки и гарантии. Некоторые примитивы должны использоваться вместе. Например, мы должны использовать классы для создания объектов и помещать их в образы контейнеров. Однако некоторые другие примитивы могут служить полноценной заменой поведения в Java, например, CronJob в Kubernetes может полностью заменить ExecutorService в Java.

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

Контейнеры

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

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

Init-контейнеры можно сравнить с конструкторами объектов; контроллеры DaemonSet похожи на потоки выполнения, действующие в фоновом режиме (как, например, сборщик мусора в Java). Поды можно считать аналогами контекста инверсии управления (Inversion of Control, IoC), используемого, например, в Spring Framework, где несколько объектов имеют общий управляемый жизненный цикл и могут напрямую обращаться друг к другу.

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

• Образ контейнера — это функциональная единица, решающая одну определенную задачу.

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

• Образ контейнера является самодостаточным — он определяет и несет в себе зависимости времени выполнения.

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

• Образ контейнера имеет определенные зависимости времени выполнения и требования к ресурсам.

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

• Контейнер обычно выполняется как один процесс Unix.

• Контейнер позволяет безопасно масштабировать его вверх и вниз в любой момент.

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

Поды

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

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

Как показано на рис. 1.2, на этапах разработки и сборки микросервис соответствует образу контейнера, который разрабатывается и выпускается одной группой. Но во время выполнения аналогом микросервиса является под, представляющий единицу развертывания, размещения и масштабирования. Единственный способ запустить контейнер — в ходе масштабирования или миграции — использовать абстракцию пода. Иногда под содержит несколько контейнеров, например, когда контейнер с микросервисом использует вспомогательный контейнер во время выполнения, как показано в главе 15 «Шаблон Sidecar».

 

Рис. 1.2. Под как един

...