Киф Моррис Санкт-Петербург «БХВ-Петербург» 2024
УДК 004.451 ББК 32.973.26-018.2 М80 Моррис К. М80 Программирование инфраструктуры. — 2-е изд.: Пер. с англ. — СПб.: БХВ-Петербург, 2024. — 416 с.: ил. ISBN 978-5-9775-1901-4 Впервые на русском языке книга об управлении облачной IT-инфраструктурой. Показаны методы контроля и развития версий инфраструктуры, аналогичные применяемым при работе с исходным кодом. Рассказано об управлении облачными серверами, их стеками и кластерами через Terraform-подобный инфраструктурный код. Описано, как получать, поддерживать и масштабировать облачные ресурсы, как управлять облачными серверами, их стеками и кластерами, как организовать непрерывное развертывание и масштабирование облачных инфраструктур. Для системных администраторов, инженеров по облачным сервисам, программистов, DevOps-специалистов УДК 004.451 ББК 32.973.26-018.2 Группа подготовки издания: Руководитель проекта Олег Сивченко Зав. редакцией Людмила Гауль Перевод с английского Олега Сивченко Компьютерная верстка Ольги Сергиенко Оформление обложки Зои Канторович © 2024 BHV Authorized Russian translation of the English edition of Infrastructure as Code 2E ISBN 9781098114671 © 2021 Kief Morris. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the same. Авторизованный перевод с английского языка на русский издания Infrastructure as Code 2E ISBN 9781098114671 © 2021 Kief Morris. Перевод опубликован и продается с разрешения компании-правообладателя O’Reilly Media, Inc. "БХВ-Петербург", 191036, Санкт-Петербург, Гончарная ул., 20 ISBN 978-1-098-11467-1 (англ.) ISBN 978-5-9775-1901-4 (рус.) © Kief Morris, 2021 © Перевод на русский язык, оформление. ООО "БХВ-Петербург", ООО "БХВ", 2024
Оглавление Предисловие ................................................................................................................... 18 Зачем я написал эту книгу ............................................................................................................ 19 Что нового и особенного во втором издании .............................................................................. 19 Что дальше ..................................................................................................................................... 21 Чего ожидать и чего не стоит ожидать от этой книги ................................................................ 21 Исторический контекст программирования инфраструктуры .................................................. 22 Для кого эта книга ......................................................................................................................... 22 Принципы, практики, паттерны ................................................................................................... 23 Примеры с ShopSpinner ................................................................................................................. 24 Соглашения, используемые в книге ............................................................................................. 24 Благодарности ................................................................................................................................ 25 ЧАСТЬ I. ОСНОВЫ ...................................................................................................... 27 Глава 1. Что такое программирование инфраструктуры ..................................... 29 Из железного века в облачный ..................................................................................................... 30 Программирование инфраструктуры ........................................................................................... 31 Достоинства программирования инфраструктуры ..................................................................... 32 Программирование инфраструктуры как оптимизация в расчете на изменения ..................... 32 Возражение: «мы не так часто вносим изменения, поэтому их автоматизация не столь нужна» .................................................................................................................. 33 Возражение: «сначала систему нужно построить, а уже потом автоматизировать» ...... 34 Возражение: «приходится выбирать между скоростью и качеством» .......................... 35 Четыре ключевые метрики ........................................................................................................... 37 Три ключевые практики для программирования инфраструктуры .......................................... 37 Ключевая практика: все определяется как код ................................................................ 38 Ключевая практика: вся текущая работа непрерывно тестируется и сдается .............. 38 Ключевая практика: создаются небольшие простые фрагменты, которые поддаются изменениям независимо друг от друга .......................................................... 39 Заключение..................................................................................................................................... 39 Глава 2. Инфраструктурные принципы для облачного века ............................... 40 Принцип: исходим из того, что системы ненадежны ................................................................. 40 Принцип: все нужно делать воспроизводимым .......................................................................... 41 Западня: системы-снежинки ......................................................................................................... 42 Принцип: создавайте такие компоненты, которые легко пустить в расход ............................. 43 Принцип: минимизируем вариативность .................................................................................... 44 Конфигурационная энтропия ............................................................................................ 45 Принцип: убедитесь, что любой процесс сможете повторить................................................... 47 Заключение..................................................................................................................................... 48
6 | Оглавление Глава 3. Инфраструктурные платформы ................................................................. 49 Из каких частей состоит инфраструктурная система ................................................................. 49 Инфраструктурные платформы .................................................................................................... 51 Инфраструктурные ресурсы ......................................................................................................... 53 Вычислительные ресурсы .................................................................................................. 54 Ресурсы для хранения данных .......................................................................................... 55 Сетевые ресурсы ................................................................................................................. 56 Заключение..................................................................................................................................... 59 Глава 4. Ключевая практика: все определяется как код ...................................... 60 Зачем следует определять инфраструктуру так, чтобы ее можно было программировать ....... 60 Что можно определить как код .................................................................................................... 61 Выбирайте инструменты, конфигурация которых вынесена наружу............................ 61 Управление вашим кодом в системе контроля версий ................................................... 62 Языки для программирования инфраструктуры......................................................................... 63 Скрипты для обслуживания инфраструктуры ................................................................. 64 Декларативные инфраструктурные языки ....................................................................... 66 Программируемые императивные инфраструктурные языки ........................................ 68 Сравнение декларативных и императивных языков в контексте инфраструктуры ........ 69 Предметно-ориентированные инфраструктурные языки ................................................. 69 Языки общего назначения в сравнении с инфраструктурными DSL ............................ 71 Принципы реализации при определении инфраструктуры, которую планируется программировать ........................................................................................................................... 71 Разделяем декларативный и императивный код ............................................................. 72 Обращайтесь с инфраструктурным кодом точно как с «настоящим» ........................... 72 Заключение..................................................................................................................................... 73 ЧАСТЬ II. РАБОТА С ИНФРАСТРУКТУРНЫМИ СТЕКАМИ ......................... 75 Глава 5. Программирование инфраструктурных стеков ...................................... 77 Что такое инфраструктурный стек ............................................................................................... 77 Код стека ............................................................................................................................. 78 Инстанс стека ...................................................................................................................... 79 Конфигурирование серверов в стеке ................................................................................ 79 Низкоуровневые инфраструктурные языки ..................................................................... 80 Высокоуровневые инфраструктурные языки .................................................................. 81 Паттерны и антипаттерны структурирования стеков ................................................................. 82 Антипаттерн: монолитный стек ........................................................................................ 82 Зачем это нужно ......................................................................................................... 82 Применимость ............................................................................................................ 83 Последствия ............................................................................................................... 83 Внедрение ................................................................................................................... 84 Смежные паттерны .................................................................................................... 84 Паттерн: стек группы приложений ................................................................................... 84 Зачем это нужно ......................................................................................................... 85 Применимость ............................................................................................................ 85 Последствия ............................................................................................................... 85 Внедрение ................................................................................................................... 86 Смежные паттерны .................................................................................................... 86
Оглавление | 7 Паттерн: сервисный стек ................................................................................................... 86 Зачем это нужно ......................................................................................................... 86 Применимость ............................................................................................................ 87 Последствия ............................................................................................................... 87 Внедрение ................................................................................................................... 87 Смежные паттерны .................................................................................................... 87 Паттерн: микростек ............................................................................................................ 87 Зачем это нужно ......................................................................................................... 88 Последствия ............................................................................................................... 88 Внедрение ................................................................................................................... 88 Смежные паттерны .................................................................................................... 88 Заключение..................................................................................................................................... 88 Глава 6. Создание окружений с помощью стеков ................................................... 89 Зачем вообще нужны окружения ................................................................................................. 89 Окружения для доставки ................................................................................................... 89 Множество продакшен-окружений .................................................................................. 90 Окружения, согласованность и конфигурация ................................................................ 91 Паттерны построения окружений ................................................................................................ 92 Антипаттерн: один стек на несколько окружений .......................................................... 92 Зачем это нужно ......................................................................................................... 92 Последствия ............................................................................................................... 93 Смежные паттерны .................................................................................................... 93 Антипаттерн: копирование и вставка окружения ........................................................... 94 Зачем это нужно ......................................................................................................... 94 Применимость ............................................................................................................ 94 Последствия ............................................................................................................... 94 Внедрение ................................................................................................................... 95 Смежные паттерны .................................................................................................... 95 Паттерн: переиспользуемый стек ..................................................................................... 95 Зачем это нужно ......................................................................................................... 96 Применимость ............................................................................................................ 97 Последствия ............................................................................................................... 97 Внедрение ................................................................................................................... 97 Смежные паттерны .................................................................................................... 97 Построение окружений с использованием множества стеков................................................... 98 Заключение..................................................................................................................................... 99 Глава 7. Конфигурирование инстансов стеков ..................................................... 100 Использование параметров стека для создания уникальных идентификаторов ................... 101 Пример параметров стека ........................................................................................................... 102 Паттерны конфигурирования стеков ......................................................................................... 103 Антипаттерн: установка параметров стека вручную .................................................... 103 Зачем это нужно ....................................................................................................... 103 Последствия ............................................................................................................. 104 Внедрение ................................................................................................................. 104 Смежные паттерны .................................................................................................. 104 Паттерн: переменные окружения стека .......................................................................... 105 Зачем это нужно ....................................................................................................... 105 Применимость .......................................................................................................... 105 Последствия ............................................................................................................. 105
8 | Оглавление Внедрение ................................................................................................................. 106 Смежные паттерны .................................................................................................. 107 Паттерн: скрипты для ввода параметров ....................................................................... 107 Зачем это нужно ....................................................................................................... 107 Применимость .......................................................................................................... 107 Последствия ............................................................................................................. 108 Внедрение ................................................................................................................. 108 Смежные паттерны .................................................................................................. 110 Паттерн: конфигурационные файлы стека ..................................................................... 110 Зачем это нужно ....................................................................................................... 110 Применимость .......................................................................................................... 111 Последствия ............................................................................................................. 111 Внедрение ................................................................................................................. 111 Смежные паттерны .................................................................................................. 113 Паттерн: стек-обертка ...................................................................................................... 113 Зачем это нужно ....................................................................................................... 114 Последствия ............................................................................................................. 114 Внедрение ................................................................................................................. 115 Смежные паттерны .................................................................................................. 116 Паттерн: конвейеризация параметров стека .................................................................. 116 Зачем это нужно ....................................................................................................... 117 Применимость .......................................................................................................... 117 Последствия ............................................................................................................. 117 Внедрение ................................................................................................................. 118 Смежные паттерны .................................................................................................. 119 Паттерн: реестр параметров стека .................................................................................. 119 Зачем это нужно ....................................................................................................... 120 Применимость .......................................................................................................... 120 Последствия ............................................................................................................. 120 Внедрение ................................................................................................................. 121 Смежные паттерны .................................................................................................. 122 Конфигурационный реестр ......................................................................................................... 122 Внедрение конфигурационного реестра ........................................................................ 123 Реестры инструмента, предназначенного для автоматизации инфраструктуры ....................................................................................................... 123 Продукты, которые могут послужить конфигурационным реестром общего назначения ................................................................................................... 123 Сервисы реестра, предоставляемые на платформе ............................................... 124 Конфигурационные реестры «сделай сам» ........................................................... 124 Один или множество конфигурационных реестров ...................................................... 125 Обращение с секретами как с параметрами .............................................................................. 125 Шифрование секретов ...................................................................................................... 126 Несекретная авторизация................................................................................................. 126 Инъекция секретов во время выполнения ...................................................................... 127 Одноразовые секреты ...................................................................................................... 127 Заключение................................................................................................................................... 128 Глава 8. Ключевая практика: непрерывное тестирование и доставка ............ 129 Зачем непрерывно тестировать инфраструктурный код .......................................................... 130 Что такое непрерывное тестирование ............................................................................ 130 Что следует тестировать на уровне инфраструктуры ................................................... 132
Оглавление | 9 Сложности с тестированием инфраструктурного кода ............................................................ 134 Проблема: тесты для декларативного кода обычно не слишком ценны ..................... 135 Тестирование изменчивого декларативного кода ................................................. 136 Тестирование сочетаний декларативного кода ..................................................... 137 Проблема: тестирование инфраструктурного кода идет медленно ............................. 137 Проблема: зависимости усложняют тестовую инфраструктуру .................................. 139 Прогрессивное тестирование ...................................................................................................... 140 Тестовая пирамида ........................................................................................................... 141 Модель тестирования по принципу швейцарского сыра .............................................. 143 Конвейеры доставки для работы с инфраструктурой .............................................................. 144 Этапы работы конвейера ................................................................................................. 145 Масштаб компонентов, тестируемых на этапе .............................................................. 146 Масштаб зависимостей, используемых на этапе конвейера ........................................ 146 Платформенные элементы, требуемые на этапе конвейера ......................................... 147 Программы и сервисы для организации конвейера доставки ...................................... 148 Тестирование в продакшене ....................................................................................................... 150 Что невозможно воспроизвести вне продакшена .......................................................... 151 Управление рисками тестирования в продакшене ........................................................ 152 Заключение................................................................................................................................... 153 Глава 9. Тестирование инфраструктурных стеков............................................... 154 Пример инфраструктуры ............................................................................................................ 154 Пример стека .................................................................................................................... 155 Пример стека и конвейер для него.................................................................................. 156 Офлайновые этапы тестирования стеков .................................................................................. 156 Проверка синтаксиса ........................................................................................................ 157 Офлайновый статический анализ кода ........................................................................... 157 Статический анализ кода с применением API ............................................................... 158 Тестирование с применением имитационного API ....................................................... 158 Онлайновые этапы тестирования стеков ................................................................................... 159 Предпросмотр: проверяем, какие изменения могут быть внесены.............................. 160 Верификация: выдвижение гипотез об инфраструктурных ресурсах ......................... 161 Результаты: убеждаемся, что инфраструктура работает корректно ............................ 162 Использование тестовых контекстов для обращения с зависимостями ................................. 163 Тестовые двойники для восходящих зависимостей ...................................................... 164 Тестовые контексты для нисходящих зависимостей .................................................... 165 Проводим рефакторинг компонентов так, чтобы их легко было изолировать ........... 167 Паттерны жизненного цикла для тестовых инстансов стеков ................................................. 167 Паттерн: персистентный тестовый стек ......................................................................... 168 Зачем это нужно ....................................................................................................... 168 Применимость .......................................................................................................... 168 Последствия ............................................................................................................. 168 Внедрение ................................................................................................................. 169 Смежные паттерны .................................................................................................. 169 Паттерн: эфемерный тестовый стек ................................................................................ 169 Зачем это нужно ....................................................................................................... 170 Применимость .......................................................................................................... 170 Последствия ............................................................................................................. 170 Внедрение ................................................................................................................. 170 Смежные паттерны .................................................................................................. 170
10 | Оглавление Антипаттерн: сдвоенные этапы с персистентными и эфемерными стеками .............. 170 Зачем это нужно ....................................................................................................... 171 Применимость .......................................................................................................... 171 Последствия ............................................................................................................. 171 Внедрение ................................................................................................................. 171 Смежные паттерны .................................................................................................. 172 Паттерн: периодическая пересборка стека .................................................................... 172 Зачем это нужно ....................................................................................................... 172 Применимость .......................................................................................................... 172 Последствия ............................................................................................................. 172 Внедрение ................................................................................................................. 173 Смежные паттерны .................................................................................................. 173 Паттерн: серийный сброс стека....................................................................................... 173 Зачем это нужно ....................................................................................................... 174 Применимость .......................................................................................................... 174 Последствия ............................................................................................................. 174 Внедрение ................................................................................................................. 174 Смежные паттерны .................................................................................................. 174 Оркестрация тестов ..................................................................................................................... 175 Поддержка локального тестирования ............................................................................. 175 Избегайте плотного связывания с инструментами конвейера ..................................... 176 Инструменты оркестрации тестов .................................................................................. 176 Заключение................................................................................................................................... 177 ЧАСТЬ III. РАБОТА С СЕРВЕРАМИ И ДРУГИМИ ПЛАТФОРМАМИ ИСПОЛНЕНИЯ ПРИЛОЖЕНИЙ ........................................................................... 179 Глава 10. Среды выполнения приложений ............................................................ 181 Исходно облачная инфраструктура под потребности приложений ........................................ 182 Цели для сред исполнения приложений .................................................................................... 183 Развертываемые части приложения ................................................................................ 183 Пакеты для развертывания .............................................................................................. 184 Развертывание приложений на серверах ................................................................................... 185 Упаковка приложений в контейнерах ............................................................................ 185 Развертывание приложений в серверных кластерах ..................................................... 186 Развертывание приложений в кластерах приложений ............................................................. 187 Пакеты для развертывания приложений в кластерах ............................................................... 188 Развертывание серверного приложения по модели FaaS ......................................................... 190 Данные приложений .................................................................................................................... 190 Структуры и схемы данных ............................................................................................. 191 Исходно облачная инфраструктура для хранения приложений ................................... 192 Соединяемость приложений ....................................................................................................... 192 Обнаружение сервисов................................................................................................................ 193 Заключение................................................................................................................................... 195 Глава 11. Сборка серверов в коде ............................................................................ 196 Что на сервере .............................................................................................................................. 197 Откуда что берется ...................................................................................................................... 198 Код для конфигурации сервера .................................................................................................. 199 Модули кода для конфигурации сервера ....................................................................... 200
Оглавление | 11 Проектирование модулей для конфигурации серверного кода.................................... 201 Версионирование и продвижение серверного кода ...................................................... 202 Серверные роли ................................................................................................................ 203 Тестирование серверного кода ................................................................................................... 204 Прогрессивное тестирование серверного кода .............................................................. 204 Что тестировать в серверном коде .................................................................................. 205 Как тестировать серверный код ...................................................................................... 206 Создание нового серверного инстанса ...................................................................................... 207 Сборка нового серверного инстанса вручную ............................................................... 208 Создаем сервер с помощью скрипта ............................................................................... 209 Создание сервера с помощью инструмента управления стеком .................................. 209 Конфигурирование платформы для автоматического создания серверов .................. 210 Как собрать сервер с помощью сетевого инструмента предоставления ресурсов ........ 211 Заблаговременная сборка серверов ............................................................................................ 212 Горячее клонирование сервера ....................................................................................... 212 Использование серверного снимка ................................................................................. 213 Создание чистого серверного образа .............................................................................. 213 Конфигурирование нового серверного инстанса ...................................................................... 214 Зажаривание серверного инстанса .................................................................................. 215 Выпекание серверных образов ........................................................................................ 216 Комбинируем выпекание и зажаривание ....................................................................... 216 Применение серверной конфигурации при создании сервера ..................................... 217 Заключение................................................................................................................................... 218 Глава 12. Управление изменениями, поступающими на серверы ..................... 219 Паттерны управления изменениями: когда применять изменения ......................................... 220 Антипаттерн: применять по факту изменений .............................................................. 220 Зачем это нужно ....................................................................................................... 220 Применимость .......................................................................................................... 221 Последствия ............................................................................................................. 221 Внедрение ................................................................................................................. 221 Смежные паттерны .................................................................................................. 221 Паттерн: непрерывная синхронизация конфигурации .................................................. 222 Зачем это нужно ....................................................................................................... 222 Применимость .......................................................................................................... 223 Последствия ............................................................................................................. 223 Внедрение ................................................................................................................. 223 Смежные паттерны .................................................................................................. 223 Паттерн: неизменяемый сервер ....................................................................................... 224 Зачем это нужно ....................................................................................................... 224 Применимость .......................................................................................................... 224 Последствия ............................................................................................................. 224 Внедрение ................................................................................................................. 225 Смежные паттерны .................................................................................................. 225 Как применять код конфигурации сервера ............................................................................... 226 Паттерн: конфигурация сервера методом push .............................................................. 226 Зачем это нужно ....................................................................................................... 226 Применимость .......................................................................................................... 226 Последствия ............................................................................................................. 227 Внедрение ................................................................................................................. 227 Смежные паттерны .................................................................................................. 228
12 | Оглавление Паттерн: конфигурация сервера методом pull ............................................................... 228 Зачем это нужно ....................................................................................................... 228 Применимость .......................................................................................................... 229 Внедрение ................................................................................................................. 229 Смежные паттерны .................................................................................................. 230 Другие события серверного жизненного цикла ........................................................................ 230 Останов и перезапуск серверного инстанса ................................................................... 231 Замена серверного инстанса ............................................................................................ 232 Восстановление отказавшего сервера ............................................................................ 233 Заключение................................................................................................................................... 234 Глава 13. Образы серверов как код ......................................................................... 235 Сборка серверного образа ........................................................................................................... 235 Зачем собирать серверный образ .................................................................................... 236 Как собрать серверный образ .......................................................................................... 237 Инструменты для сборки серверных образов ................................................................ 237 Процесс онлайновой сборки образа................................................................................ 238 Инфраструктура для сборочного инстанса ............................................................ 239 Конфигурирование сборочного инстанса .............................................................. 239 Процесс офлайновой сборки образа ............................................................................... 241 Исходное содержимое для серверного образа .......................................................................... 242 Сборка на основе стандартного серверного образа ...................................................... 243 Сборка серверного образа с нуля .................................................................................... 243 Происхождение серверного образа и его содержимое ................................................. 243 Изменение серверного образа .................................................................................................... 244 Разогреть или испечь свежий? ........................................................................................ 244 Версионирование серверного образа .............................................................................. 245 Обновление серверных инстансов при изменении образа ........................................... 247 Предоставление серверного образа для совместного использования несколькими командами .................................................................................................. 248 Как работать с крупными изменениями, вносимыми в образ ...................................... 249 Использование конвейера для тестирования и доставки серверного образа ......................... 250 Стадия сборки серверного образа ................................................................................... 250 Стадия тестирования серверного образа ........................................................................ 252 Стадии доставки серверного образа ............................................................................... 253 Использование множества серверных образов ......................................................................... 253 Серверные образы для разных инфраструктурных платформ ..................................... 254 Серверные образы для разных операционных систем .................................................. 254 Серверные образы для разных аппаратных архитектур ................................................. 254 Серверные образы для разных ролей ............................................................................. 255 Многослойное расположение серверных образов ......................................................... 255 Совместное использование кода в разных серверных образах .................................... 256 Заключение................................................................................................................................... 257 Глава 14. Сборка кластеров в коде .......................................................................... 258 Решения с кластерами приложений ........................................................................................... 259 Кластер как услуга ........................................................................................................... 259 Распространение кластеров в упакованном виде .......................................................... 260 Топологии стеков для кластеров приложений .......................................................................... 261 Монолитный стек, использующий кластер как услугу ................................................. 262
Оглавление | 13 Монолитный стек для упакованного кластерного решения ......................................... 263 Конвейер для стека, в котором реализован монолитный кластер приложений ......... 264 Пример: множество стеков в одном кластере ................................................................ 267 Стратегии совместного использования кластеров приложений ............................................. 269 Один большой кластер на все случаи жизни ................................................................. 270 Отдельные кластеры для стадий доставки ..................................................................... 271 Кластеры для управления ................................................................................................ 272 Кластеры для команд ....................................................................................................... 273 Сервисная сеть .................................................................................................................. 273 Инфраструктура для бессерверных FaaS-сервисов .................................................................. 275 Заключение................................................................................................................................... 277 ЧАСТЬ IV. ПРОЕКТИРОВАНИЕ ИНФРАСТРУКТУРЫ .................................. 279 Глава 15. Ключевая практика: небольшие простые фрагменты ...................... 281 Модульное проектирование ....................................................................................................... 281 Характеристики хорошо спроектированных компонентов .......................................... 282 Правила проектирования компонентов .......................................................................... 283 Избегайте дублирования ......................................................................................... 283 Правило композиции ............................................................................................... 284 Принцип единственной ответственности .............................................................. 284 Проектируйте компоненты на основе концепций предметной области, а не на основе технических концепций ................................................................. 284 Закон Деметры ......................................................................................................... 285 Никаких циклических зависимостей ...................................................................... 285 Используйте тестирование для принятия проектных решений ................................... 286 Модульная инфраструктура ....................................................................................................... 286 Компоненты стека по сравнению со стеками в качестве компонентов ....................... 286 Использование сервера в стеке ....................................................................................... 288 Проведение границ между компонентами ................................................................................ 291 Устанавливайте границы по паттернам естественных изменений .............................. 292 Устанавливайте границы по жизненным циклам компонентов ................................... 292 Устанавливайте границы по организационным структурам ........................................ 294 Создавайте границы, поддерживающие устойчивость ................................................. 295 Создавайте границы, поддерживающие масштабирование ......................................... 295 Устанавливайте границы по проблемам безопасности и управления ......................... 298 Заключение................................................................................................................................... 299 Глава 16. Построение стеков из компонентов ....................................................... 300 Языки инфраструктуры для компонентов стека ....................................................................... 301 Повторное использование декларативного кода с модулями ...................................... 301 Динамическое создание элементов стека с применением библиотек ......................... 302 Паттерны для компонентов стека .............................................................................................. 303 Паттерн: фасадный модуль.............................................................................................. 303 Зачем это нужно ....................................................................................................... 304 Применимость .......................................................................................................... 304 Последствия ............................................................................................................. 304 Внедрение ................................................................................................................. 305 Смежные паттерны .................................................................................................. 305
14 | Оглавление Антипаттерн: модуль обфускации .................................................................................. 305 Зачем это нужно ....................................................................................................... 306 Применимость .......................................................................................................... 306 Последствия ............................................................................................................. 306 Внедрение ................................................................................................................. 306 Смежные паттерны .................................................................................................. 306 Антипаттерн: неразделяемый модуль ............................................................................ 306 Зачем это нужно ....................................................................................................... 307 Применимость .......................................................................................................... 307 Последствия ............................................................................................................. 307 Внедрение ................................................................................................................. 307 Смежные паттерны .................................................................................................. 307 Паттерн: модуль бандла ................................................................................................... 308 Зачем это нужно ....................................................................................................... 309 Применимость .......................................................................................................... 309 Последствия ............................................................................................................. 309 Внедрение ................................................................................................................. 309 Смежные паттерны .................................................................................................. 309 Антипаттерн: спагетти-модуль ....................................................................................... 309 Зачем это нужно ....................................................................................................... 311 Последствия ............................................................................................................. 311 Внедрение ................................................................................................................. 311 Смежные паттерны .................................................................................................. 312 Паттерн: сущность домена инфраструктуры ................................................................. 312 Зачем это нужно ....................................................................................................... 313 Применимость .......................................................................................................... 313 Внедрение ................................................................................................................. 313 Смежные паттерны .................................................................................................. 313 Построение уровня абстрагирования ......................................................................................... 314 Заключение................................................................................................................................... 315 Глава 17. Использование стеков в качестве компонентов .................................. 316 Обнаружение зависимостей между стеками ............................................................................. 316 Паттерн: сопоставление ресурсов ................................................................................... 317 Зачем это нужно ....................................................................................................... 318 Применимость .......................................................................................................... 318 Последствия ............................................................................................................. 318 Внедрение ................................................................................................................. 319 Смежные паттерны .................................................................................................. 319 Паттерн: поиск данных в стеке ....................................................................................... 320 Зачем это нужно ....................................................................................................... 320 Применимость .......................................................................................................... 320 Последствия ............................................................................................................. 321 Внедрение ................................................................................................................. 321 Смежные паттерны .................................................................................................. 322 Паттерн: поиск по реестру интеграции .......................................................................... 322 Зачем это нужно ....................................................................................................... 323 Применимость .......................................................................................................... 324 Последствия ............................................................................................................. 324 Внедрение ................................................................................................................. 324 Смежные паттерны .................................................................................................. 325
Оглавление | 15 Внедрение зависимости ................................................................................................... 325 Проблемы со смешиванием зависимости и кода определения ............................ 326 Отделение зависимостей от их обнаружения ........................................................ 326 Заключение................................................................................................................................... 328 ЧАСТЬ V. ДОСТАВКА ИНФРАСТРУКТУРЫ ..................................................... 329 Глава 18. Организация кода инфраструктуры ...................................................... 331 Организация проектов и репозиториев...................................................................................... 331 Один репозиторий или много? ........................................................................................ 332 Один репозиторий для всего ........................................................................................... 332 Один репозиторий, несколько сборок .................................................................... 333 Отдельный репозиторий для каждого проекта (микрорепозиторий) .......................... 334 Несколько репозиториев с несколькими проектами ..................................................... 335 Организация различных типов кода .......................................................................................... 336 Файлы поддержки проекта .............................................................................................. 336 Межпроектные тесты ....................................................................................................... 337 Хранение интеграционных тестов в проекте ........................................................ 338 Отдельные проекты интеграционных тестов ................................................................. 338 Организация кода по концепции предметной области ................................................. 339 Организация файлов конфигурационных значений ...................................................... 340 Управление инфраструктурным кодом и кодом приложения ................................................. 341 Доставка инфраструктуры и приложений ...................................................................... 341 Тестирование приложений с инфраструктурой ............................................................. 342 Тестирование инфраструктуры перед интеграцией ...................................................... 343 Использование инфраструктурного кода для развертывания приложений ................ 344 Заключение................................................................................................................................... 346 Глава 19. Доставка инфраструктурного кода ........................................................ 347 Доставка инфраструктурного кода ............................................................................................ 347 Сборка инфраструктурного проекта ............................................................................... 348 Инфраструктурный код упаковки как артефакт ............................................................ 349 Использование репозитория для доставки инфраструктурного кода .......................... 349 Специализированный репозиторий артефактов .................................................... 350 Репозиторий инструмента ....................................................................................... 350 Общий репозиторий для хранения файлов ............................................................ 351 Доставка кода из репозитория исходного кода ..................................................... 351 Интеграция проектов ................................................................................................................... 351 Паттерн: интеграция проекта во время сборки .............................................................. 353 Зачем это нужно ....................................................................................................... 353 Применимость .......................................................................................................... 354 Последствия ............................................................................................................. 354 Внедрение ................................................................................................................. 354 Смежные паттерны .................................................................................................. 355 Паттерн: интеграция проекта во время доставки .......................................................... 355 Зачем это нужно ....................................................................................................... 356 Применимость .......................................................................................................... 357 Последствия ............................................................................................................. 357 Внедрение ................................................................................................................. 357 Смежные паттерны .................................................................................................. 358
16 | Оглавление Паттерн: интеграция проекта во время применения ..................................................... 358 Зачем это нужно ....................................................................................................... 359 Применимость .......................................................................................................... 359 Последствия ............................................................................................................. 359 Внедрение ................................................................................................................. 359 Смежные паттерны .................................................................................................. 360 Использование скриптов для обертывания инструментов инфраструктуры ......................... 361 Сборка значений конфигурации ..................................................................................... 361 Упрощение скриптов-оболочек ...................................................................................... 362 Заключение................................................................................................................................... 363 Глава 20. Командные рабочие процессы ................................................................ 364 Люди ............................................................................................................................................. 365 Кто пишет инфраструктурный код? .......................................................................................... 367 Применение кода к инфраструктуре .......................................................................................... 369 Применение кода с вашей локальной рабочей станции ............................................... 369 Применение кода из централизованной службы ........................................................... 370 Персональные инфраструктурные инстансы ................................................................. 371 Ветви исходного кода в рабочих процессах .................................................................. 373 Предотвращение конфигурационной энтропии ........................................................................ 374 Сведите к минимуму задержку автоматизации ............................................................. 374 Избегайте непродуманного применения изменений ..................................................... 375 Применяйте код непрерывно........................................................................................... 375 Неизменяемая инфраструктура ....................................................................................... 375 Управление в конвейерно-ориентированном потоке задач ..................................................... 376 Перетасовка обязанностей ............................................................................................... 377 Сдвиг влево ....................................................................................................................... 378 Пример процесса для инфраструктуры как кода с управлением ................................. 378 Заключение................................................................................................................................... 379 Глава 21. Безопасное изменение инфраструктуры ............................................... 380 Уменьшите объем изменений ..................................................................................................... 380 Небольшие изменения ..................................................................................................... 382 Пример рефакторинга ...................................................................................................... 384 Отправка неполных изменений в продакшен ........................................................................... 385 Параллельные инстансы .................................................................................................. 386 Обратно совместимые преобразования .......................................................................... 389 Переключатели функций ................................................................................................. 390 Изменение действующей инфраструктуры ............................................................................... 392 Инфраструктурная хирургия ........................................................................................... 394 Расширение и сжатие ....................................................................................................... 396 Изменения нулевого времени простоя ........................................................................... 399 Сине-зеленые изменения ......................................................................................... 400 Преемственность ......................................................................................................................... 400 Преемственность за счет предотвращения ошибок ...................................................... 401 Непрерывность за счет быстрого восстановления ........................................................ 402 Непрерывное аварийное восстановление ....................................................................... 403 Хаос-инжиниринг ............................................................................................................. 404 Планирование неудач ....................................................................................................... 404
Оглавление | 17 Непрерывность данных в меняющейся системе ....................................................................... 406 Блокировка ........................................................................................................................ 407 Разделение ......................................................................................................................... 407 Репликация ........................................................................................................................ 407 Перезагрузка ..................................................................................................................... 407 Смешение подходов к обеспечению непрерывности данных ...................................... 408 Заключение................................................................................................................................... 408 Предметный указатель ............................................................................................... 410 Об авторе ....................................................................................................................... 416
Предисловие Десять лет назад IT-директор одного глобального банка съязвил, когда я предложил ему присмотреться к частным облачным технологиям и инструментарию для автоматизации инфраструктуры. «Может быть, такие штуки хороши для стартапов, но наша организация слишком велика, и наши требования слишком сложные». Всего несколько лет назад многие предприятия даже не стали бы рассматривать использование общедоступных облаков. Сегодня облачные технологии повсюду. Даже самые крупные, ультраконсервативные организации стремительно берут на вооружение стратегию «сначала облака». Те организации, которые не видят для себя возможности положиться на публичные облака, обустраивают динамически изменяемую инфраструктуру в своих датацентрах1 . Возможности этих платформ развиваются и улучшаются настолько быстро, что сложно игнорировать их, не рискуя при этом морально устареть. Облачные технологии и технологии автоматизации убирают барьеры, мешающие вносить изменения в продакшен-системы, и это сопряжено с новыми вызовами. Притом что большинство организаций стремятся ускорить темп изменений, но для них непозволительно игнорировать риски, и, следовательно, они нуждаются в управлении. Традиционные процессы и приемы для безопасного изменения инфраструктуры не рассчитаны на то, чтобы справляться со столь быстрыми переменами. Такие подходы к работе обычно притупляют достоинства современных облачных технологий, то есть замедляют работу и вредят стабильности2 . В главе 1 я использую термины «железный век» и «облачный век» (см. разд. «Из железного века в облачный»), чтобы описать, чем отличается философия, применяемая при управлении физической инфраструктурой (где исправление ошибок — процесс долгий и дорогостоящий), от философии управления виртуальной инфраструктурой, где ошибки поддаются быстрому обнаружению и исправлению. Инструменты для программирования инфраструктуры создают возможности для работы в таком ключе, чтобы вводить изменения в систему можно было чаще, 1 Так, многим государственным и финансовым организациям из стран, где отсутствуют облачные провайдеры, законодательно запрещено держать за рубежом хостинг с данными или выполнять транзакции за рубеж. 2 Исследование, опубликованное DORA в State of DevOps Report (https://dora.dev/), указывает на то, что тяжеловесность процессов управления изменениями коррелирует с плохой производительностью по устранению отказов при изменениях и другими показателями, характеризующими эффективность сдачи программных продуктов.
Предисловие | 19 быстрее и надежнее, повышая общее качество систем. Но эти достоинства не привносит в работу сам инструмент; польза ощущается, когда умеешь с ним обращаться. Фокус в том, чтобы, опираясь на технологии, придать процессу внесения изменений известный уровень качества, надежности и соответствия стандартам. Зачем я написал эту книгу Первое издание книги я написал, поскольку не видел ни одной слаженной подборки рекомендаций о том, как управлять программированием инфраструктуры. В разных блогах, докладах с конференций и в документации по продуктам и проектам была целая россыпь советов. Но практикующему специалисту приходилось тщательно просеивать всю эту информацию и самостоятельно составлять для себя стратегию, а у большинства из нас просто нет на это времени. Писать первое издание было увлекательно. Занимаясь этим, мне довелось попутешествовать и пообщаться с людьми со всего мира, которые делились со мной своим опытом. Эти беседы натолкнули меня на новые мысли, поставили меня перед новыми вызовами. Я усвоил, что ценность написания книги, выступления на конференциях, консультирования клиентов — в том, как при этом завязываются разговоры. В пределах отрасли мы по-прежнему собираемся, делимся идеями по поводу того, как управлять программированием инфраструктуры, и оттачиваем их. Что нового и особенного во втором издании С тех пор, как в июне 2016 года вышло первое издание, многое изменилось. В том издании был подзаголовок «Управление серверами в облаке», продиктованный тем, что в ту пору бо´льшая часть автоматизации инфраструктуры сводилась к конфигурированию серверов. С тех пор значительно более важная роль стала отводиться контейнерам и кластерам, и обслуживание инфраструктуры превратилось в управление совокупностями инфраструктурных ресурсов, предоставляемых на облачных платформах, — эти совокупности я буду называть в данной книге стеками. Таким образом, второе издание в большей степени посвящено выстраиванию стеков, для чего предназначены такие инструменты, как CloudFormation и Terraform. Я исхожу из того, что мы используем инструменты управления стеками для сборки инфраструктурных совокупностей, обеспечивающих подходящую среду для исполнения приложений. К числу таких сред могут относиться серверы, кластеры и бессерверные среды выполнения. Я значительно пересмотрел некоторые вещи, учитывая, что мне довелось узнать о развитии проблем и потребностей команд, занятых выстраиванием инфраструктуры. Как я уже упоминал в этом предисловии, считаю, что обеспечение безопасности и легкости изменения инфраструктуры — ключевое достоинство концепции «программирование инфраструктуры». По-моему, важность такого подхода обычно недооценивается; считается, что инфраструктура — это обеспечение из разряда «построил и забыл».
20 | Предисловие Но мне попадалось слишком много таких команд, которые едва справляются с требованиями своих организаций: они не в состоянии расширяться и масштабироваться с достаточной скоростью, держать темп доставки ПО либо обеспечивать ожидаемый уровень надежности и безопасности. А если вникнуть в детали тех вызовов, что перед ними встают, оказывается, что эти люди просто завалены задачами по обновлению, латанию и улучшению своих систем. Поэтому я сделал акцент на этих вызовах; фактически они являются центральной темой книги. В этом издании вводятся три ключевые практики, которых нужно придерживаться при программировании инфраструктуры, чтобы все изменения вносились легко и безопасно: Все определять как код Смысл приема очевиден из названия практики. Она обеспечивает воспроизводимость и согласованность. Постоянно тестировать и сдавать всю работу, находящуюся в процессе выполнения Каждое изменение повышает безопасность, а также позволяет двигаться вперед быстрее и увереннее. Создавать небольшие простые элементы, которые можно менять независимо друг от друга Такие фрагменты менять проще и безопаснее, чем более крупные. Три этих практики усиливают друг друга. Код легко отслеживать, версионировать и доставлять на всех этапах процесса управления изменениями. Мелкие фрагменты проще поддаются непрерывному тестированию. Если приходится непрерывно тестировать каждый фрагмент в отдельности, то нужно поддерживать слабосвязанный дизайн. Эти практики и детали их применения знакомы из разработки ПО. В первом издании книги я опирался на практики разработки и доставки программного обеспечения, принятые в философии Agile. В этом издании я также обращаюсь к правилам и приемам эффективного проектирования. В последние несколько лет мне доводилось наблюдать за работой команд, с трудом поддерживавших сравнительно крупные и сложные инфраструктурные системы, поэтому я включил в книгу несколько глав о том, как это делается. Также я видел, что многим командам сложно организовать программирование инфраструктуры и придерживаться этого метода, поэтому я затронул различные «болевые точки». Рассказываю, как поддерживать в базах кода порядок, как предоставлять для инфраструктуры инстансы «на разработку» и «на тестирование», как управлять совместной работой множества людей, в том числе тех, кто работает на управляющих должностях.
Предисловие | 21 Что дальше Я не думаю, что программирование инфраструктуры как промышленная отрасль уже состоялась. Надеюсь, в этой книге удастся адекватно показать, какие приемы сегодня считаются эффективными в разных командах, а также наметить, к чему следует стремиться. Я вполне уверен, что в ближайшие пять лет будут развиваться как инструментарии, так и подходы. Возможно, нам предстоит увидеть, как библиотеки для программирования инфраструктуры будут создаваться на более универсальных языках, и мы, возможно, станем динамически генерировать инфраструктуру, а не заниматься низкоуровневым задаванием статических деталей окружений. Нам определенно нужно улучшить подходы к управлению изменениями в «горячей» инфраструктуре. Насколько мне известно, большинству команд страшно применять код на уровне горячей инфраструктуры (в одной команде название «Terraform» переиначивали в «Terrorform», но подобные чувства не чужды и пользователям других инструментов). Чего ожидать и чего не стоит ожидать от этой книги Основной тезис этой книги в том, что, исследуя различные способы работы с инструментами для реализации инфраструктуры, можно повысить качество предоставляемых сервисов. Мы планируем полагаться на скорость и частоту доставки, чтобы повысить надежность и качество предоставляемого продукта. Поэтому акцент в этой книге делается не столько на конкретных инструментах, сколько на том, как их использовать. Хотя я и упоминаю для примера некоторые инструменты, предназначенные для решения конкретных задач, например конфигурирования серверов и предоставления стеков, вы не найдете в книге подробностей о том, как использовать конкретный инструмент или облачную платформу. Вы найдете паттерны, практики и приемы, которые должны пригодиться вам независимо от того, с какими именно инструментами и платформами вы работаете. Вы не найдете примеров кода для работы с реальными инструментами или облаками. Инструменты в этой сфере меняются слишком быстро, чтобы в таких условиях поддерживать хотя бы некоторую актуальность примеров кода, но советы из этой книги будут устаревать не так быстро и будут применимы для широкого среза инструментов. Для иллюстрации концепций я пишу примеры на псевдокоде для вымышленных инструментов. На сайте книги (https://infrastructure-as-code.com/) даются ссылки на проекты и примеры кода. Эта книга не рассказывает, как использовать операционную систему Linux, как конфигурировать кластеры Kubernetes или настраивать сетевую маршрутизацию. За рамки этой книги выходит рассказ о том, как обзаводиться инфраструктурными ресурсами для создания всех этих вещей, а также как предоставлять их с помощью
22 | Предисловие кода. Я поделюсь различными паттернами топологии кластеров и подходами к программному определению кластеров и управлению кластерами. Опишу паттерны предоставления, конфигурирования и изменения серверных инстансов в коде. Практики, описанные в этой книге, следует дополнить ресурсами по конкретным операционным системам, технологиям кластеризации и облачным платформам. Еще раз оговорюсь, что эта книга объясняет подходы к использованию инструментов и технологий, поэтому актуальна безотносительно того, каким именно инструментом вы пользуетесь. Кроме того, в этой книге лишь поверхностно рассмотрены вопросы эксплуатации, в частности мониторинг, наблюдаемость, агрегация логов, управление идентификационной информацией и другие проблемы, которые необходимо решать для управления серверами в облачной среде. Этот текст должен помочь вам управлять необходимой инфраструктурой, программируя ее, но подробности о конкретных сервисах, опять же, следует искать за пределами этой книги. Исторический контекст программирования инфраструктуры Инструменты и практики программирования инфраструктуры появились задолго до самого термина. Системные администраторы издавна использовали скрипты в качестве подспорья для управления системами. Первую ласточку, систему CFEngine (https://cfengine.com/), Марк Берджесс (Mark Burgess) создал в 1993 году. Я впервые научился полностью автоматизировать с помощью кода предоставление и обновление серверов на сайте Infrastructures.Org (http://www.infrastructures.org/) еще в начале 2000-х3 . Парадигма программирования инфраструктуры развивалась одновременно с движением DevOps. Эндрю Клей-Шефер (Andrew Clay-Shafer) и Патрик Дебуа (Patrick Debois) дали старт движению DevOps, выступив с рассказом о нем на конференции Agile 2008. Термин «Infrastructure as Code» («программирование инфраструктуры») я впервые встретил в выступлении «Гибкая инфраструктура», которым КлейШефер отметился на конференции Velocity в 2009 году; это выступление резюмировано в статье Джона Уиллиса (John Willis). Адам Джейкоб (Adam Jacob, сооснователь компании Chef) и Люк Канье (Luke Kanies, основатель компании Puppet) также употребляли такой термин примерно в то же время. Для кого эта книга Эта книга — для тех, кто участвует в предоставлении и использовании инфраструктуры для доставки и выполнения ПО. Возможно, у вас есть опыт управления системами и инфраструктурой либо разработки и доставки программного обеспе- 3 Контент на этом сайте датирован летом 2020 года, хотя на самом деле он не обновлялся с 2007 года.
Предисловие | 23 чения. Может быть, вы работали на должности программиста, тестировщика, архитектора или менеджера. Предполагаю, что вы имели некоторый практический опыт с облачной или виртуализованной инфраструктурой, а также с инструментами для программной автоматизации инфраструктуры. Для читателей, ранее не сталкивавшихся с программированием инфраструктуры, эта книга должна послужить хорошим введением в тему, однако вы выжмете из нее максимум, если уже знаете, как устроена инфраструктура облачных платформ, а также базово понимаете хотя бы один инструмент для программирования инфраструктуры. Те, кто более поднаторел в работе с такими инструментами, найдут в книге как старые, так и новые концепции и подходы. Этот текст должен послужить общим знаменателем и артикулировать вызовы и решения так, что из него смогут извлечь пользу опытные команды и практикующие специалисты. Принципы, практики, паттерны Терминами «принципы», «практики» и «паттерны» (а также «антипаттерны») я обозначаю важнейшие концепции. Вот что я под ними понимаю: Принцип Принцип — это правило, помогающее выбрать одно из потенциально возможных решений. Практика Практика — это способ реализации чего-либо. Конкретная практика не всегда является единственно возможным способом выполнения какой-либо работы, а в конкретной ситуации, возможно, является и не лучшим способом. Следует руководствоваться принципами, выбирая практику, наиболее приемлемую в конкретной ситуации. Паттерн Паттерн — это потенциальное решение проблемы. Он очень похож на практику в том, что эффективность паттерна может отличаться от ситуации к ситуации. Каждый паттерн описывается в таком формате, который помогает вам оценить, насколько данный паттерн релевантен для решения стоящей перед вами задачи. Антипаттерн Антипаттерн — это потенциальное решение, которого в большинстве случаев следует избегать. Зачастую это идея, которая лишь кажется хорошей, либо такая практика, которой вы начинаете заниматься, даже не осознавая этого. Почему я не пользуюсь термином «наилучшие практики» В нашей отрасли любят говорить о «наилучших практиках» (best practices). Проблема в том, что такой термин зачастую наводит на мысль, будто у проблемы есть всего одно решение, независимо от контекста.
24 | Предисловие Я предпочитаю описывать практики и паттерны, указывать, в каких случаях они полезны и какие ограничения им присущи. Действительно, некоторые из них я описываю как более эффективные или более уместные, но стараюсь всегда оставаться открытым для альтернатив. Если я полагаю, что некоторые практики менее эффективны, чем другие, я объясняю, почему так считаю. Примеры с ShopSpinner По всей книге я иллюстрирую концепции на примерах с выдуманной компанией, которая называется ShopSpinner. Компания ShopSpinner создает и поддерживает интернет-магазины для своих клиентов. ShopSpinner использует FCS (Fictional Cloud Service, «вымышленный облачный сервис»). Это общедоступный провайдер IaaS («инфраструктуры как услуги»), в частности предоставляющий сервисы FSI (Fictional Server Images, «вымышленные серверные образы») и FKS (Fictional Kubernetes Service, «вымышленный сервис Kubernetes»). Компания работает с инструментом Stackmaker — аналогом Terraform, CloudFormation и Pulumi — для определения инфраструктуры в своем облаке и управления ею. Она конфигурирует серверы с помощью инструмента Servermaker, во многом похожего на Ansible, Chef или Puppet. Инфраструктура и системный дизайн ShopSpinner могут отличаться в зависимости от того, какой момент я пытаюсь пояснить; то же касается синтаксиса кода и аргументов командной строки для вымышленных инструментов. Соглашения, используемые в книге В книге используются следующие типографские соглашения: Курсив Для обозначения новых терминов, названий и расширений файлов. Полужирный шрифт Для оформления адресов URL и электронной почты. Моноширинный шрифт Используется для листингов программ, а также в тексте для обозначения элементов программ, например названий функций, баз данных, типов данных, переменных среды, операторов и ключевых слов. Моноширинный полужирный шрифт Используется для обозначения команд или другого текста, который вводится пользователем. Моноширинный курсив Используется для обозначения текста, который нужно заменить предоставляемыми пользователем значениями или значениями, определяемыми контекстом.
Предисловие | 25 Данное изображение обозначает подсказку или совет. Данное изображение обозначает общее замечание. Данное изображение обозначает предупреждение или предостережение Благодарности Эта книга, как и первое издание, — плод не только моего труда, но и слияния и консолидации всего лучшего, что я смог почерпнуть от множества людей. Их было так много, что уже не всех я в силах вспомнить и отблагодарить по достоинству. Пожалуйста, извините, если ниже не найдете своего имени. Мне неизменно нравится перебрасываться идеями с Джеймсом Льюисом (James Lewis); наши беседы и его тексты и выступления прямо или косвенно повлияли на очень многие разделы этой книги. Он любезно поделился своим глубоким опытом в проектировании ПО и широкой осведомленностью на различные другие темы, дав мне пищу для размышлений над почти финальным черновиком книги. Его рекомендации помогли мне укрепить те связи, которые я пытался проследить между программной инженерией и программированием инфраструктуры. С самого начала мою работу великодушно поддерживал Мартин Фаулер (Martin Fowler). Меня вдохновляет его умение почерпнуть опыт у разных людей, самостоятельно применить их знания и восприятие и оформить все это в ясный и полезный совет. Тьерри де Паув (Thierry de Pauw) был самым вдумчивым моим рецензентом и весьма мне помог. Он прочел множество черновиков и дал обратную связь, рассказав мне, что показалось ему новым и полезным, какие идеи подтверждаются на его собственном опыте, а какие детали в чистом виде ему не попадались. Мне необходимо поблагодарить Абигайль Бенгсер (Abigail Bangser), Джона Барбера (Jon Barber), Макса Гриффитса (Max Griffiths), Энн Симмонс (Anne Simmons) и Клэр Уолкли (Claire Walkley) за то, как они мотивировали и вдохновляли меня. Многие мысли и идеи, благодаря которым эта книга стала лучше, я почерпнул от коллег. Джеймс Грин (James Green) просветил меня по поводу инженерии данных и машинного обучения в контексте инфраструктуры. Пэт Дауни (Pat Downey) объяснил, как пользуется расширением и компактификацией при работе с инфраструктурой. Винченцо Фабрици (Vincenzo Fabrizi) указал мне на важность инверсии управления при работе с инфраструктурными зависимостями. Эффи Элден (Effy Elden) — неиссякаемый источник знаний о ландшафте инфраструктурных инструментов. Мориц Хайбер (Moritz Heiber) прямо и косвенно повлиял на содержание
26 | Предисловие этой книги, однако было бы слишком самонадеянно рассчитывать, что он на 100% с ней согласится. В компании ThoughtWorks мне выпала возможность общаться со многими коллегами и клиентами по поводу программирования инфраструктуры, обсуждать эту и смежные темы в ходе воркшопов, проектов и на онлайновых форумах. Вот лишь немногие из этих людей: Ама Асаре (Ama Asare), Нилахья Чаттерджи (Nilakhya Chatterjee), Одри Консейсан (Audrey Conceicao), Патрик Дейл (Patrick Dale), Дхавал Доши (Dhaval Doshi), Филип Фафара (Filip Fafara), Адам Фэхи (Adam Fahie), Джон Феминелла (John Feminella), Марио Фернандес (Mario Fernandez), Луиза Франклин (Louise Franklin), Хайко Жерин (Heiko Gerin), Джаррад «Барри» Гудвин (Jarrad “Barry” Goodwin), Эмили Горценски (Emily Gorcenski), Джеймс Грегори (James Gregory), Кол Харрис (Col Harris), Принс М. Джейн (Prince M Jain), Эндрю Джонс (Andrew Jones), Айко Клостерманн (Aiko Klostermann), Чарльз Корн (Charles Korn), Вишвас Кумар (Vishwas Kumar), Пунит Лэд (Punit Lad), Суйя Лю (Suya Liu), Том Клемент Океч (Tom Clement Oketch), Геральд Шмидт (Gerald Schmidt), Босс Супанат Потхиваракорн (Boss Supanat Pothivarakorn), Родриго Реч (Rodrigo Rech), Флориан Зелльмайр (Florian Sellmayr), Владимир Снеблич (Vladimir Sneblic), Иша Сони (Isha Soni), Видьясари Стелла (Widyasari Stella), Пол Валла (Paul Valla), Шрикант Венугопалан (Srikanth Venugopalan), Анкит Вал (Ankit Wal), Пол Йео (Paul Yeoh) и Цзяюй И (Jiayu Yi). Также благодарю Кента Спиллнера (Kent Spillner) — в этот раз помню, за что. Много было людей, рецензировавших различные черновики этого издания и поделившихся отзывами о них, в том числе Арташес Арабаян (Artashes Arabajyan), Альберт Аттард (Albert Attard), Саймон Биссон (Simon Bisson), Филлип Кэмпбелл (Phillip Campbell), Марио Чекки (Mario Cecchi), Карлос Конде (Carlos Conde), Бамдад Даштбан (Bamdad Dashtban), Марк Хофер (Marc Hofer), Виллем ван Кетвих (Willem van Ketwich), Барри О’Рейли (Barry O’Reilly), Роб Парк (Rob Park), Роберт Куинливан (Robert Quinlivan), Васин Ватханнашрисонг (Wasin Watthanasrisong) и Ребекка Уирфс-Брок (Rebecca Wirfs-Brock). Глубоко признателен Вирджинии Уилсон (Virginia Wilson), моему редактору, сопровождавшей меня на долгом и изнурительном пути к созданию этой книги. Мой коллега Джон Амаланатан (John Amalanathan) превратил мои корявые схемы в изысканные произведения искусства, которые вы найдете на страницах книги, и проявил при этом великое терпение и добросовестность. Меня всемерно поддерживал работодатель, компания ThoughtWorks. Во-первых, на работе мне создали все условия, чтобы я мог учиться у феноменальных людей. Вовторых, там поддерживается культура, стимулирующая сотрудников привносить свои идеи в отрасль. В-третьих, меня всячески поддерживали, когда мы вместе с коллегами и клиентами исследовали и тестировали новые способы работы. Ашок Субраманьян (Ashok Subramanian), Рут Харрисон (Ruth Harrison), Рени Хокинс (Renee Hawkins), Кен Магрейдж (Ken Mugrage), Ребекка Парсонс (Rebecca Parsons) и Гаятри Рао (Gayathri Rao) среди прочих помогли мне считать этот проект не личным делом, а чем-то гораздо бо´льшим. Наконец, самое главное: признаюсь в вечной любви к Озлем (Ozlem) и Эрелу (Erel), выдержавшим мою одержимую работу над этой книгой. Снова.
ЧАСТЬ I Основы
ГЛАВА 1 Что такое программирование инфраструктуры Если вы работаете в команде, собирающей и эксплуатирующей IT-инфраструктуру, то технология автоматизации облаков и инфраструктуры должна помочь вам быстрее выдавать больший объем полезной работы, причем делать это надежнее. Но на практике такая работа часто приводит к разрастанию и усложнению инфраструктуры, а также к тому, что приходится управлять самыми разными вещами. Эти технологии приобретают особую важность в ходе цифровизации организаций. Под словом «цифровой» люди в строгих костюмах понимают, что программные системы критически важны для тех дел, которыми занимается организация1 . Переход к цифровым технологиям требует от вас выполнять больше работы в более краткие сроки. Необходимо добавлять и поддерживать еще больше сервисов. Больше деловой активности. Больше сотрудников. Больше клиентов, поставщиков и других заинтересованных лиц. Облака и инструменты автоматизации в данной ситуации полезны тем, что значительно упрощают дополнение и изменение инфраструктуры. Но многим командам не удается выкроить время даже на обслуживание той инфраструктуры, что у них уже есть. Что пользы в погоне за упрощением наделать себе еще дополнительных дел. Как сказал мне один из клиентов, «когда мы перешли на использование облаков, сор, копившийся в избе, полыхнул». Многие реагируют на угрозу такого несдерживаемого хаоса, ужесточая процессы управления изменениями. Надеются, что смогут предотвратить хаос, ограничив перемены и взяв их под контроль. Так они заковывают облако в цепи. С таким подходом сопряжены две проблемы. Во-первых, теряются преимущества облачных технологий, а во-вторых, пользователей как раз привлекают эти преимущества. Поэтому пользователи сторонятся тех организаций, где пытаются ограничить хаос. В наихудших ситуациях управление рисками полностью игнорируется, принимается решение, что в дивном новом облачном мире такое управление не требуется. На вооружение берется «ковбойский» подход к IT, с которым связаны уже совсем иные проблемы2 . 1 Такой тезис противоречит тому, что те же самые люди говорили еще несколько лет назад, утверждая, что «программы не являются коренной частью нашего бизнеса». Приняв такую точку зрения и отдав IT на аутсорс, эти организации обнаружили, что их обходят конкуренты, возглавляемые людьми, расценивающими софт как козырь в конкурентной борьбе, а не как лишнюю статью расходов, которую стоит урезать. 2 Под «ковбойским» подходом к IT я понимаю создание IT-систем без какой-либо методологии и без учета долгосрочных последствий. Зачастую люди, никогда не занимавшиеся поддержкой систем в продакшене, избирают скорейший путь, не удосужившись подумать о безопасности, поддержке, производительности и других эксплуатационных аспектах.
30 | Часть I. Основы В этой книге я исхожу из того, что облачными технологиями и автоматизацией можно воспользоваться, чтобы вносить изменения легко, безопасно, быстро и ответственно. Эти бонусы не идут «в комплекте» с инструментами автоматизации и облачными платформами, а зависят от того, как вы используете эти технологии. DevOps и программирование инфраструктуры DevOps — это движение, призванное частично устранить барьеры и трения между различными отделами в организации, т. е. между разработчиками, администраторами и другими заинтересованными лицами, участвующими в проектировании, создании и эксплуатации софта. Хотя технологическая сторона DevOps — наиболее наглядная и в некоторых отношениях простейшая грань DevOps, на слаженность и эффективность операций больше всего влияют культура, люди и процессы. Технологические и инженерные практики, в частности программирование инфраструктуры, должны поддерживать усилия по наведению мостов и улучшению совместной работы. В этой главе я объясняю, почему современная динамичная инфраструктура требует мировосприятия, присущего «облачному веку». Такое мировосприятие принципиально отличается от традиционного подхода, принятого в железном веке, привычного для нас по работе со статичными дооблачными системами. Я описываю три ключевые практики для внедрения программирования инфраструктуры: определяем все как код, постоянно тестируем и сдаем все, над чем работаем, а наши системы собираем из небольших слабосвязанных фрагментов. Кроме того, в этой главе я привожу доводы в пользу перехода к облачному веку инфраструктуры. При таком подходе отбрасывается ложная дихотомия «компромисс между скоростью и качеством». Наоборот, мы ускоряемся, именно чтобы повысить качество, а на качество опираемся для ускоренного достижения готового результата. Из железного века в облачный Технологии облачного века обеспечивают ускоренное предоставление и изменение инфраструктуры по сравнению с традиционными технологиями железного века (табл. 1.1). Таблица 1.1. Технологические изменения, присущие облачному веку Железный век Облачный век Физическое аппаратное обеспечение Виртуализованные ресурсы На предоставление уходят недели На предоставление уходят минуты Ручное управление процессами Автоматизированные процессы Правда, эти технологии не обязательно упрощают управление вашими системами и их наращивание. Если перенести в неограниченную облачную инфраструктуру систему, отягощенную техническим долгом (https://martinfowler.com/bliki/ TechnicalDebt.html), хаос только усилится.
Глава 1. Что такое программирование инфраструктуры | 31 Может быть, удобно было бы использовать проверенные традиционные модели управления, чтобы контролировать скорость и хаос, привносимые сравнительно новыми технологиями. Тщательное заблаговременное проектирование, дотошное изучение изменений, строгое разделение зон ответственности — так мы и наведем порядок! К сожалению, такие модели оптимизации рассчитаны на железный век, где изменения — дело медленное и дорогое. Они сразу требуют браться за дополнительную работу, чтобы таким образом сократить время на внесение изменений на последующих этапах. Очевидно, такой подход целесообразен, когда изменения вносятся медленно и это затратный процесс. Но в облаке изменения вносятся дешево и быстро. Эту скорость следует применить себе на пользу, чтобы можно было учиться и непрерывно улучшать вашу систему. При методах работы, принятых в железном веке, обучение и улучшение даются тяжелее всего. Нужно не сочетать тихоходные процессы железного века со скоростными технологиями облачного, а усвоить новое мировосприятие. Пусть эти быстрые технологии помогут вам снизить риски и повысить качество. Для этого требуется фундаментально пересмотреть подходы и мышление относительно изменений и рисков (табл. 1.2). Таблица 1.2. Как принято работать в облачном веке Железный век Облачный век Цена изменений высока Цена изменений низка Изменения сродни отказам (изменениями приходится «управлять», «контролировать» их) Изменения сродни обучению и улучшению Упреждение отказов Максимизация скорости улучшений Доставка большими партиями, тестирование по завершении Доставка в формате мелких изменений, непрерывное тестирование Длительные релизные циклы Краткие релизные циклы Монолитные архитектуры (подвижных элементов мало, они сравнительно крупные) Микросервисные архитектуры (детали мелкие, их много) Конфигурирование физическое или через графический пользовательский интерфейс Программирование конфигурации Программирование инфраструктуры — это подход облачного века к управлению изменениями, при котором непрерывные изменения применяются для обеспечения высокой надежности и качества. Программирование инфраструктуры Программирование инфраструктуры — это подход к автоматизации инфраструктуры, основанный на практиках, принятых в разработке ПО. В нем делается акцент на согласованных повторяемых процедурах, используемых для предоставления и из-
32 | Часть I. Основы менения систем и их конфигурации. Вы вносите изменения в код, затем с помощью автоматизации тестируете и применяете эти изменения в ваших системах. На протяжении всей этой книги я объясняю, как инженерные практики, присущие технологии Agile (например, разработка через тестирование (TDD), непрерывная интеграция (CI) и непрерывная доставка (CD)), обеспечивают быстрое и безопасное изменение инфраструктуры. Также я описываю, как современное проектирование ПО помогает создавать надежную и удобную в поддержке инфраструктуру. Эти практики подкрепляют друг друга. Хорошо спроектированная инфраструктура легче тестируется, и доставка в ней организована лучше. Автоматизированное тестирование и доставка способствуют более простому и чистому проектированию. Достоинства программирования инфраструктуры Итак, организации, берущие на вооружение программирование инфраструктуры для управления динамическими ресурсами, надеются на определенные улучшения, в частности: использование IT-инфраструктуры как движущего фактора для быстрой генерации ценности; экономия усилий и сокращение рисков, связанных с внесением изменений в инфраструктуру; помощь пользователям инфраструктуры в получении доступа к нужным им ресурсам, причем вовремя; предоставление общего инструментария для программистов, администраторов и других заинтересованных лиц; создание надежных, безопасных и экономически эффективных систем; обеспечение прозрачности управления, безопасности и соблюдения норм; оптимизация скорости устранения неисправностей и восстановления после отказов. Программирование инфраструктуры как оптимизация в расчете на изменения Притом что именно с изменениями сопряжены основные риски, возникающие в продакшен-системе, непрерывные изменения неизбежны, более того — систему можно улучшить, лишь внося в нее изменения. Поэтому целесообразно оптимизировать ваши возможности вносить изменения и очень быстро, и надежно3 . Это под- 3 По данным Джина Кима (Gene Kim), Джорджа Спэффорда (George Spafford) и Кевина Бера (Kevin Behr), изложенным в The Visible Ops Handbook (Институт IT-процессов), из-за изменений возникает 80% незапланированных простоев.
ГЛАВА 21 Безопасное изменение инфраструктуры Тема частого и быстрого внесения изменений проходит через всю книгу. Как упоминалось в самом начале (см. разд. «Возражение: “приходится выбирать между скоростью и качеством”» гл. 1), скорость вовсе не делает системы нестабильными, а способствует стабильности, и наоборот. Мантра не «двигайся быстро и ломай», а скорее, «двигайся быстро и улучшай». Однако стабильность и качество не являются результатом оптимизации исключительно по скорости. Исследование, процитированное в главе 1, показывает, что попытки оптимизировать либо скорость, либо качество не приводят ни к одному из результатов. Ключ — оптимизировать обоих. Сосредоточьтесь на возможности частого, быстрого и безопасного внесения изменений, а также на быстром обнаружении и устранении ошибок. Все, что рекомендуется в этой книге, — от использования кода для последовательного построения инфраструктуры до непрерывного тестирования и разбиения системы на более мелкие части, — позволяет вносить быстрые, частые и безопасные изменения. Но частые изменения инфраструктуры создают проблемы для бесперебойного предоставления услуг. В этой главе рассматриваются эти проблемы и методы их решения. Мышление, лежащее в основе этих методов, заключается не в том, чтобы рассматривать изменения как угрозу стабильности и непрерывности, а в том, чтобы использовать динамичный характер современной инфраструктуры. Используйте принципы, практики и приемы, описанные в этой книге, чтобы свести к минимуму сбои в работе из-за изменений. Уменьшите объем изменений Agile, XP, Lean и подобные подходы оптимизируют скорость и надежность доставки, внося изменения небольшими инкрементами. Легче спланировать, внедрить, протестировать и отладить небольшое изменение, чем крупное, поэтому мы стремимся уменьшить размеры порций1 . Конечно, нам часто приходится вносить в наши системы существенные изменения, но мы можем сделать это, разбив их на небольшой набор изменений, которые мы можем доставить по одному за раз. 1 Дональд Г. Рейнертсен (Donald G. Reinertsen) описывает концепцию уменьшения размера порции в своей книге The Principles of Product Development Flow (издательство Celeritas).
Глава 21. Безопасное изменение инфраструктуры | 381 Например, команда ShopSpinner изначально построила свою инфраструктуру с помощью единственного стека инфраструктуры. Стек включал в себя кластер вебсервера и сервер приложений. Со временем члены команды добавили больше серверов приложений и превратили некоторые из них в кластеры. Они поняли, что использование кластера веб-сервера и всех серверов приложений в одной VLAN — неудачный проект, поэтому они улучшили дизайн своей сети и переместили эти элементы в разные VLAN. Они также решили последовать совету из этой книги и разделить свою инфраструктуру на несколько стеков, чтобы упростить их индивидуальное изменение. Первоначальная реализация ShopSpinner представляла собой один стек с одной VLAN (рис. 21.1). Рис. 21.1. Пример начальной реализации: один стек, одна VLAN Команда планирует разделить свой стек на несколько стеков. К ним относятся shared-networking-stack и application-infrastructure-stack, рассмотренные в примерах из предыдущих глав этой книги. План также включает web-cluster-stack для управления контейнерным кластером для интерфейсных веб-серверов и applicationdatabase-stack для управления инстансом базы данных для каждого приложения (рис. 21.2). Команда также разделит свою единственную сеть VLAN на несколько сетей VLAN. Серверы приложений будут распределены по этим виртуальным локальным сетям для обеспечения избыточности (рис. 21.3). В главе 17 описаны варианты проектирования и некоторые паттерны реализации для разделения этих примеров стеков. Теперь мы можем изучить способы перехода от одной реализации к другой в системе продакшена.
382 | Часть V. Доставка инфраструктуры Рис. 21.2. План разделения нескольких стеков Рис. 21.3. План создания нескольких VLAN Небольшие изменения Самый большой бардак, который я создавал в коде, был, когда я к отправке накапливал локально слишком много работы. Заманчиво покончить сразу со всей работой, которую вы наметили. Куда труднее внести небольшое изменение, которое лишь немного продвинет вас к цели. Внедрение крупных изменений в виде серии небольших изменений требует нового мышления и новых привычек.
Глава 21. Безопасное изменение инфраструктуры | 383 К счастью, путь указан миром разработки программного обеспечения. Я включил в эту книгу множество методов, поддерживающих построение систем по частям, в том числе TDD, CI и CD. Средством реализации является постепенное тестирование и внесение изменений в код с использованием конвейера, как описано в главе 8 и упоминается на протяжении всей книги. Вы должны иметь возможность внести в свой код небольшое изменение, отправить его, получить отзыв о том, работает ли код, и запустить его в продакшен. Команды, которые используют эти методы, очень часто эффективно продвигают изменения. Один инженер может вносить изменения каждый час или около того, и каждое изменение интегрируется в основную кодовую базу и проверяется на готовность к работе в полностью интегрированной системе. Люди используют различные термины и методы для внесения значительных изменений в виде серии небольших изменений: Инкрементный Инкрементное изменение — это изменение, которое добавляет одну часть запланированной реализации. Вы можете построить пример системы ShopSpinner постепенно, реализуя один стек за раз. Сначала создайте разделяемый сетевой стек. Затем добавьте стек веб-кластера. Наконец, создайте инфраструктурный стек приложений. Итеративный Итеративное изменение обеспечивает прогрессивное улучшение системы. Начните создавать систему ShopSpinner, создав базовую версию из всех трех стеков. Затем внесите ряд изменений, каждое из которых расширяет возможности стеков. Ходячий скелет Ходячий скелет (https://wiki.c2.com/?WalkingSkeleton) — это базовая реализация основных частей новой системы, которую вы реализуете, чтобы проверить ее общий проект и структуру2 . Люди часто создают ходячий скелет для инфраструктурного проекта вместе с аналогичными первоначальными реализациями приложений, которые будут работать на нем, чтобы команды могли увидеть, как могут работать доставка, развертывание и операции. Первоначальная реализация и выбор инструментов и сервисов для скелета часто не те, которые запланированы на долгосрочную перспективу. Например, вы можете планировать использовать полнофункциональное решение для мониторинга, но построить свой ходячий скелет, используя более простые службы, предоставляемые вашим облачным провайдером. Рефакторинг Рефакторинг (https://refactoring.com/) включает в себя изменение дизайна системы или компонента системы без изменения ее поведения. Рефакторинг часто 2 В книге Стива Фримена (Steve Freeman) и Нэта Прайса (Nat Pryce) Growing Object-Oriented Software, Guided by Tests (Addison-Wesley) ходячим скелетам посвящена отдельная глава.
384 | Часть V. Доставка инфраструктуры проводится, чтобы подготовить почву для изменений, которые поведение3 меняют. Рефакторинг может улучшить ясность кода, чтобы его было легче изменять, или реорганизовать код, чтобы он соответствовал запланированным изменениям. Пример рефакторинга Команда ShopSpinner решает разбить свой текущий стек на несколько стеков и инстансов стека. Запланированная реализация включает один инстанс стека для контейнерного кластера, в котором размещены его веб-серверы, и еще один для разделяемых сетевых структур. У группы также будет пара стеков для каждой службы: один для сервера приложений и связанной с ним сети и один для инстанса базы данных для этой службы (рис. 21.4). Рис. 21.4. План декомпозиции стека Члены команды также хотят заменить свой продукт контейнерного кластера, перейдя с кластера Kubernetes, который они развертывают сами, на виртуальные машины, чтобы использовать «Контейнеры как службу», предоставляемую их поставщиком облачных услуг (см. разд. «Решения с кластерами приложений» гл. 14). Команда решает поэтапно реализовать свою декомпозированную архитектуру. Первый шаг — извлечь контейнернный кластер в его собственный стек, а затем заменить контейнерный продукт в этом стеке (рис. 21.5). Этот план является примером использования рефакторинга для внесения изменений. Изменение решения контейнерного кластера будет проще, когда он изолирован в собственный стек, чем когда он является частью большого инфраструктурно- 3 Кент Бек (Kent Beck) в своей статье SB Changes описывает рабочие процессы для внесения «больших изменений небольшими безопасными шагами». Это включает в себя внесение ряда изменений, одни из которых приводят код в порядок, подготавливая его к изменению поведения, а другие вносят поведенческие изменения. Ключевым моментом является то, что каждое изменение делает одно или другое, а не то и другое одновременно.
406 | Часть V. Доставка инфраструктуры ваша команда должна рассмотреть, есть ли новый сценарий сбоя, который нужно определить и спланировать. Вы должны внедрить проверки, чтобы проверить свои неудачные сценарии. Например, если вы считаете, что когда на вашем сервере закончится место на диске, приложение перестанет принимать транзакции, автоматически добавит новые инстансы сервера и предупредит вашу команду, у вас должен быть автоматизированный тест, который проверяет этот сценарий. Вы можете протестировать это на стадии конвейера (тестирование доступности, как описано в разд. «Что следует тестировать на уровне инфраструктуры» гл. 8) или с помощью эксперимента хаоса. Инкрементное улучшение непрерывности Легко определить амбициозные меры по восстановлению, когда ваша система корректно обрабатывает все мыслимые сбои, не прерывая работу. Я никогда не знал команды, у которой было бы время и ресурсы, чтобы создать хотя бы половину того, что ей хотелось бы. Сопоставляя сценарии сбоев и меры по их устранению, вы можете определить дополнительный набор мер, которые вы могли бы реализовать. Разбейте их на отдельные истории реализации и приоритизируйте их в ваших планах в зависимости от вероятности сценария, потенциального ущерба и стоимости реализации. Например, хотя было бы неплохо автоматически расширять дисковое пространство для вашего приложения, когда оно заканчивается, получение предупреждения до того, как оно закончится, является ценным первым шагом. Непрерывность данных в меняющейся системе Многие практики и методы облачного века для развертывания программного обеспечения и управления инфраструктурой с радостью рекомендуют небрежное уничтожение и расширение ресурсов, махнув рукой на проблему данных. Вас можно простить, если вы думаете, что хипстеры DevOps считают всю идею данных возвратом к железному веку, — в конце концов, правильное двенадцатифакторное приложение (https://12factor.net/) не имеет состояния. Большинство систем в реальном мире используют данные, и люди могут быть трогательно привязаны к ним. Данные могут представлять собой проблему при поэтапном изменении системы, как описано в разд. «Отправка неполных изменений в продакшен» данной главы. Запуск параллельных инстансов инфраструктуры хранения может привести к несогласованности или даже повреждению данных. Многие подходы к постепенному развертыванию изменений полагаются на возможность их отката, что может быть невозможно при изменении схемы данных. Динамическое добавление, удаление и восстановление ресурсов инфраструктуры, на которых размещены данные, является особенно сложной задачей. Тем не менее есть способы справиться с этим в зависимости от ситуации. Некоторые подходы — блокировка, разделение, репликация и перезагрузка.
Глава 21. Безопасное изменение инфраструктуры | 407 Блокировка Некоторые инфраструктурные платформы и инструменты управления стеком позволяют блокировать определенные ресурсы, чтобы они не были удалены командами, которые в противном случае уничтожили бы их. Если вы укажете этот параметр для элемента хранилища, то инструмент откажется применять изменения к этому элементу, позволяя членам команды внести изменения вручную. Однако с этим есть несколько проблем. В некоторых случаях, если вы применяете изменение к защищенному ресурсу, инструмент может оставить стек в частично измененном состоянии, что может привести к простою служб. Но фундаментальная проблема заключается в том, что защита некоторых ресурсов от автоматических изменений поощряет внесение изменений вручную. Ручная работа провоцирует ручные ошибки. Гораздо лучше найти способ автоматизировать процесс, который безопасно изменяет вашу инфраструктуру. Разделение Вы можете отделить ресурсы, на которых размещены данные, от других частей системы; например, путем создания отдельного стека (пример этого приведен в разд. «Паттерн: микростек» гл. 5). Вы можете безнаказанно уничтожить и перестроить вычислительный инстанс, отключив и снова подключив его дисковый том. Хранение данных в базе данных обеспечивает еще бо´льшую гибкость, потенциально позволяя добавлять несколько вычислительных инстансов. Вам по-прежнему нужна стратегия обеспечения непрерывности данных для стека, в котором хранятся данные, но это сужает масштаб проблемы. Вы можете полностью снять вопросы с преемственностью данных, используя предоставляемую на хостинге службу DBaaS. Репликация В зависимости от данных и того, как они управляются, вы можете реплицировать их в нескольких инстансах инфраструктуры. Классический пример — кластер распределенной базы данных, который реплицирует данные между узлами. При правильной стратегии репликации данные повторно загружаются на недавно перестроенный узел с других узлов кластера. Эта стратегия терпит неудачу, если теряется слишком много узлов, что может произойти при серьезном сбое хостинга. Таким образом, этот подход работает как первая линия защиты, для сценариев с более серьезными отказами необходим другой механизм. Перезагрузка Наиболее известным решением для обеспечения непрерывности данных является резервное копирование и восстановление данных из более надежной инфраструктуры хранения. Когда вы перестраиваете инфраструктуру, в которой размещаются
408 | Часть V. Доставка инфраструктуры данные, вы сначала создаете резервную копию данных. Вы перезагружаете данные в новый инстанс после его создания. Вы также можете делать периодические резервные копии, которые вы можете перезагружать в сценариях восстановления, хотя вы потеряете все изменения данных, которые произошли между резервным копированием и восстановлением. Это можно свести к минимуму и, возможно, устранить путем потоковой передачи изменений данных в резервную копию, например записи журнала транзакций базы данных. Облачные платформы предоставляют различные услуги хранения, как описано в разд. «Ресурсы для хранения данных» гл. 3, с разным уровнем надежности. Например, сервисы хранения объектов, такие как AWS S3, обычно имеют более надежные гарантии сохранности данных, чем сервисы блочного хранения, такие как AWS EBS. Таким образом, вы можете реализовать резервное копирование путем копирования или потоковой передачи данных в том хранилища объекта. Вы должны автоматизировать процесс не только резервного копирования данных, но и их восстановления. Ваша инфраструктурная платформа может предоставить способы легко это сделать. Например, вы можете автоматически сделать моментальный снимок тома дискового хранилища перед внесением в него изменений. Вы можете использовать моментальные снимки дисковых томов для оптимизации процесса добавления узлов в систему, такую как кластер базы данных. Вместо того чтобы создавать новый узел базы данных с пустым томом хранилища, присоединение его к клону диска другого узла может ускорить синхронизацию и перевести узел в оперативный режим. «Непроверенные резервные копии равнозначны отсутствию резервных копий» — распространенная поговорка в нашей отрасли. Вы уже используете автоматизированное тестирование для различных аспектов вашей системы, учитывая, что вы следуете практике программирования инфраструктуры. Таким образом, вы можете сделать то же самое со своими резервными копиями. Запустите процесс восстановления из резервной копии в конвейере или в качестве эксперимента с хаосом, в продакшене или не в продакшене. Смешение подходов к обеспечению непрерывности данных Лучшим решением часто является комбинация разделения, репликации и перезагрузки. Разделение данных создает пространство для более гибкого управления другими частями системы. Репликация сохраняет данные доступными большую часть времени. А перезагрузка данных — это запасной вариант для более экстремальных ситуаций. Заключение Сторонники современных методов управления инфраструктурой облачного века часто не обращают внимания на непрерывность. Наиболее известные подходы к обеспечению надежной работы систем основаны на предпосылке железного века
Глава 21. Безопасное изменение инфраструктуры | 409 о том, что внесение изменений дорого и рискованно. Эти подходы, как правило, подрывают преимущества облака, Agile и других подходов, ориентированных на быстрый темп изменений. Я надеюсь, что эта глава объяснила, как использовать мышление облачного века, чтобы сделать системы более надежными не вопреки быстрому темпу изменений, а благодаря ему. Вы можете использовать динамический характер современных инфраструктурных платформ и сделать четкий акцент на тестировании и согласованности, которые исходят от методов гибкого проектирования. Результатом является высокий уровень уверенности в том, что вы можете постоянно улучшать свою систему и использовать сбои как возможность учиться и совершенствоваться.
Предметный указатель A Accelerate 33, 35, 37, 39 ADR 73 AFS 56 Agile 20, 22, 32, 35, 36, 62, 129, 130, 134, 191, 380, 401, 409 AKS 259, 262 Amazon 207, 235 AMI 158, 207, 235, 237, 241, 242, 251 Aminator 237 Ansible 24, 46, 50, 63, 66, 68, 70, 78, 176, 200, 201, 220, 221, 223 Ansible Tower 123, 200, 227 Apache Mesos 188 API 51, 58, 62, 65, 78, 79, 81, 123, 125, 126, 139, 140, 157–159, 194, 209, 213, 217, 229, 237, 238, 261, 265, 317, 327 ◊ шлюзовой 195 API-шлюз 58 App Service Plans 189 AppVeyor 149 APT 124 ARM 254 ASG 54 Atlantis 149, 371 AWS 49, 52–55, 57, 233, 241 AWS CDK 64, 68, 302, 319, 321 AWS CodeBuild 149 AWS CodePipeline 149 AWS EBS 408 AWS EC2 237 AWS ECS 258 AWS ECS Services 189 AWS Elastic BeanStalk 52 AWS Image Builder 238 AWS S3 230, 408 AWS SDK 65 Awspec 161 Azure 57, 189, 235 Azure Devops 52 Azure Image Builder 238 Azure Pipelines 149 Azurite 159 B BaaS 276 Bamboo 148 Bash 63, 176, 240, 361 Bazel 355 blackbox 126 Borg Google 188 BoxFuse 149 Buck 355 BuildKite 149 C CaaS 54 Capistrano 186 CD 32, 39, 62, 117, 129, 191, 227, 241, 351, 371, 383 CDC 360 CDN 58 CentOS 237 CFAR 261 CFEngine 22, 79, 196, 200 cfn_nag 158 CFR 132, 378 checkov 158 Chef 22, 24, 43, 46, 63, 66, 67, 70, 71, 78, 79, 176, 196, 200–202, 221, 223, 344, 345, 349, 375 Chef Community Cookbooks 351 Chef Infra Server 123 Chef Server 200, 350 CI 32, 39, 62, 84, 117, 129, 177, 191, 227, 383 CircleCI 149 Clarity 161 CLI 60 CloudFormation 19, 24, 50, 64, 66, 70, 78, 97, 100, 142, 190, 301, 321 CloudFormation Linter 158
Предметный указатель | 411 CloudFoundry 70 Cloud-init 229 Cloud-native 182 CMDB 120 CNAB 189 Cobbler 211 ConcourseCI 116, 149, 371 Consul 124, 275 Cookbook 61, 201 CPU 65 Cron-задание 200, 229 Crowbar 211 Cкриптинг 186 D DBaaS 53, 56, 154, 407 DBDeploy 191 db-migrate 191 DC/OS 188 DDD 313 DDNS 194 Debian 124 Debian Preseed 208 DevOps 18, 22, 30, 33, 36, 341, 406 DI 326, 328 DNS 53, 58, 194 DNS-запись 303, 308 DNS-имя 302 Docker 54, 184, 185, 188, 260, 349, 350 doozerd 124 Drone 149 Dropwizard 344, 345 DRY 283, 306 DSL 63, 64, 69–71, 196 DVD 242 E EBS 241 ECS 259, 262 EDGE ◊ модель 44 EKS 259, 262 entr 131 Envoy 275 etcd 124 F FaaS 55, 182, 185, 190, 211, 259, 275, 276, 295 Fabric 186 Facebook 354, 355 FAI 211 FCS 238 Flyway 191 Foreman 211 FSI 238 G GCP 57 GDPR 272 gems 349 Git 332 git-crypt 126 GitHub Actions 148, 149 GitLab CD 149 GitLab CI 149 GitOps 150, 351, 357, 375, 376 GKE 259, 262 Go 71 GoCD 116, 149, 371 Google 354, 355 Gradle 354, 361 GUI 62 H HashiCorp Vaul 128 HCL 68, 71, 301 Helm 345 Helm-диаграмма 70, 185, 189 Heroku 52 HTTP/S 58 HTTPS 133, 166, 193 HTTP-запрос 210, 275 HTTP-сервис 195 I IaaS 24, 50, 51, 63 IAM 126 IDE 71, 131 inotifywait 131 Inspec 161, 206 IP-адрес 58, 166, 193, 302, 303, 325, 391, 393 ◊ статический 398 ISO 242 ISO-файл 198 Istio 275
412 | Предметный указатель J Java 64, 96, 184, 185, 188, 199, 201, 205, 206, 255, 312 JavaScript 349 Jenkins 116, 148, 371 JEOS 243 JSON 56, 69 JVM 205, 206 K Kanban 131 kops 260 Kubeadm 260 Kubernetes 70, 150, 182, 185, 189, 258–260, 269, 371, 384, 386 kubespray 260 L Lean 35, 36, 131, 380 Linkerd 275 Linux 197, 236, 238, 245, 248, 249, 255–257, 344 Linux Red Hat 254 Linux Ubuntu 254 Liquidbase 191 Localstack 159 LSP 131 M MAAS 211 Make 176, 354, 361 Maven 354 Mercurial 332 Mesos 258, 260 MIG 54 Molecule 176 MSBuild 354 MTBF 401 MTTR 401 MySQL 56 N Netflix 237, 404 NFR 132 NFS 56 Nomad 258, 260 NPM 349 NuGet 349 O Octopus Deploy 345 ORAS 350 P PaaS 50, 52, 54, 82 Packer 70, 237, 238, 242, 251, 350 Pants 355 PCI 165, 272, 298 Perforce 332 Perl 63, 196 pip 349 Pivotal Diego 258 Playbook 61, 201 Please 355 Postgres 56 PowerShell 63, 240, 361 Pulumi 24, 50, 64, 68, 302, 320, 321 Pulumi for Teams 371 Puppet 22, 24, 46, 63, 66, 70, 78, 79, 196, 200, 201, 221, 223, 375 PuppetDB 123 Puppetmaster 200 PXE boot 211 Python 63, 64, 176, 184, 349, 361 Python pip 202 Q QA 366, 378 R Rake 176, 354, 361 RAM 65 Rebar 211 Red Hat 124, 237 Red Hat Kickstart 208 RPM 185, 202, 344, 345 RPM-файл 349 Ruby 63, 65, 71, 176, 184, 185, 199, 349 S S3 350 SaaS 149, 224, 227 Salt Mine 123 Saltstack 63, 200, 230 SDK 65 SDN 57 Serverspec 206 shellcheck 363
Предметный указатель | 413 SLA 365 SLI 365 SLO 365 SMB/CIFS 56 Solaris JumpStart 208 sops 126 SQL 191 SQL Server 56 SRE 378 SRP 284 SSH 227, 228 SSH-ключ 239 StackReference 321 T tarballs 349, 350 Taskcat 161 TDD 32, 62, 129, 177, 383 Team City 148 Terraform 19, 21, 24, 50, 64, 66–68, 70, 71, 78, 83, 97, 100, 115, 124, 142, 149, 158, 160, 177, 190, 209, 301, 319–321, 369, 394 Terraform Cloud 150, 371 Terraform Registry 351 Terragrunt 116 Terratest 161, 206 Test Kitchen 176 tflint 158 Tinkerbell 211 Tomcat 220, 245, 255 transcrypt 126 TravisCI 149 TypeScript 64, 71 U UI 198, 208 V VCS 62 Visual Basic for Applications 62 VLAN 52, 57, 68, 81, 267, 303, 316, 317, 319, 321, 322, 326, 327, 381, 382, 389, 390–395, 397, 399 VM 54 VMware 43, 49, 52, 196, 235 VM-шаблон 235 VPC 52, 57 VPN 58 W Weave Cloud 189, 371 WeaveWorks 150 Windows MSI 185 X XML 56, 69 XP 129, 380 Y YAGNI 307 YAML 64, 68, 69, 70 YUM 124 Z ZIP 349, 350 Zookeeper 124 А Автовосстановление 210 Автомасштабирование 210 Автоматизация 45, 47 Антипаттерн 23 Артефакт 349, 358 Б Багтрекинг 248 Балансировка нагрузки 285 В Версионирование 246 ◊ семантическое 246, 249 Ветви 373 Ветвление функций 84 Внедрение зависимостей 326 Время выполнения 37 Д Дублирование 283
414 | Предметный указатель З Закон ◊ Деметры 285 ◊ Конвея 294, 296, 331, 339 Зона поражения 83, 86, 93, 94 И Инстанс 77, 89 ◊ кластера 159 ◊ персистентный 138 ◊ сервера 238 ◊ стека 79, 85, 92, 93, 97, 111, 114, 155, 159 ◊ эфемерный 138 Инфраструктурная платформа 50, 51 Инфраструктурная хирургия 295 Инфраструктурный стек 50 К Картирование потока создания ценности 368 Квадрант 35 Кеш 58 Кластер 261 ◊ для хостинга приложений 54 ◊ серверов 54 Код ◊ декларативный 64, 67–69, 135, 136 ◊ идемпотентный 67 ◊ императивный 64 ◊ рефакторинг 71 Командная строка 104, 131, 208, 241 Коммит 63, 72 Контейнер 54, 259 Континуум 35 Конфигурационная энтропия 44, 45, 95, 224, 374 Л Линковка 352 ◊ динамическая 352 ◊ статическая 352 Линтинг 157 Логирование 134 Лямбда-пакет 185 М Манифест развертывания 188 Маршалинг 361 Маршрут 58 Масштабирование 290 Миграция схемы 191 Модель нулевого доверия 57 Модульность 281 Мониторинг 134, 152, 201, 223 Н Непрерывная доставка 32, 39, 62, 63, 104, 106, 113, 117, 130, 132, 148, 149, 227, 241 Непрерывная интеграция 32, 39, 62, 63, 84, 104, 117, 132, 149, 191, 227 Непрерывное развертывание 191 О Окружение 89, 92, 102 ◊ копирование и вставка 94 ◊ масштабируемость 90 ◊ отказоустойчивость 90 ◊ переменные 105 ◊ продакшен 93 ◊ сегрегация 91 ◊ согласованность 91 Оркестрация 175, 176, 239, 260, 327 ОС 198, 199, 208, 211, 215, 218, 219, 221, 231 П Пакет 222 Парное программирование 131, 133 Паттерн 23 Плейбук 201, 220 Правило трех 307 Практика 23 Примитив 53 Принцип 23 ◊ минимальных привилегий 57 Прицеп 194, 273 Проект 331 Прокси 58 Протокол языкового сервера 131 Процент неудачных изменений 37 Р Радиус поражения 290 Разделение ответственности 201 Разработка через тестирование 62
Предметный указатель | 415 Реестр 119 ◊ конфигурационный 120, 122–124 ◊ параметров стека 120 Репозиторий 63, 110, 115, 116, 144, 149, 198, 216, 222, 229, 230, 332, 349 ◊ микрорепозиторий 334 ◊ монорепозиторий 333, 354 Рефакторинг 101, 167, 204, 311, 383 Роль 203, 255 ◊ наследование 203 С Сборка образа 235 ◊ онлайновая 237, 238 ◊ офлайновая 237 Сборник рецептов 201, 202 Сдвиг влево 378 Сегрегация 271 Сервер ◊ клонирование 212 ◊ неизменяемый 224 ◊ образ 213 Сетевой адресный блок 57 Система контроля версий 62, 63 Сканер уязвимостей 133 Скаффолдинг 130 Скрипт 63, 64, 66, 67, 104, 106, 107, 121, 175, 176, 209, 213, 220, 229, 230, 240, 326, 337 Снежинка 42 Спираль страха перед автоматизацией 46 Среднее время восстановления, СВВ 37 Стек 19, 64, 73, 77, 78, 85, 89, 92, 268 ◊ группы приложений 82, 84 ◊ инфраструктурный 77 ◊ код 78 ◊ микростек 82, 84, 87, 293 ◊ монолитный 82 ◊ обертка 95, 113, 115 ◊ переиспользуемый 95, 97 ◊ потребитель 164, 165 ◊ провайдер 164, 165 ◊ проект 92, 96 ◊ сервисный 82, 86 ◊ структурирование 82 ◊ тестовый персистентный 168 эфемерный 169 Т Тест ◊ интеграционный 141 ◊ модульный 132, 141 ◊ пользовательского функционала 132, 141 ◊ швейцарский сыр 143 Тестирование 130, 337 ◊ непрерывное 131 ◊ окончательное 131 ◊ онлайновое 139, 159, 206, 269, 290 ◊ оперативное 131 ◊ офлайновое 139, 156, 206 ◊ прогрессивное 140, 144, 204, 337 Тестовая пирамида 141 Тестовые двойники 138, 139, 163, 164, 290 ◊ заглушки 139 ◊ имитационные объекты 139 ◊ фиктивные объекты 139 Тестовые контексты 165 Тестовый контекст 163 Тестовый набор 132, 133, 140 Технический долг 30, 36, 46, 72, 83, 130, 204, 281 Тикет 219 Ф Фиксация 170 Х Ходячий скелет 383 Ч Частота развертывания 37 Ш Шлюз 58
Об авторе Киф Моррис — глобальный директор по облачной инженерии в компании ThoughtWorks. В разных компаниях — от транснациональных предприятий до зарождающихся стартапов — он помогает найти общий язык специалистам, работающим на разных ролях, в разных регионах и отраслях. Ему нравится работать и говорить с людьми, занимаясь при этом исследованием наилучших инженерных практик, принципов проектирования архитектуры, а также приемов доставки при возведении систем в облаке. Еще в начале 1990-х Киф поднял во Флориде свою первую онлайновую систему; это была электронная доска объявлений. Позже он поступил в магистратуру по информатике в Университет Теннесси, так как полагал, что это самый легкий способ обзавестись постоянным выходом в Интернет. Он присоединился к команде системных администраторов с факультета информатики, благодаря чему смог поучаствовать в управлении сотнями машин, на которых работали самые разные виды Unix. Когда начал набухать пузырь доткомов, Киф перебрался в Лондон — город привлек его своим мультикультурным и индустриальным разнообразием. Там он до сих пор и живет с женой, сыном и котом. Большинство компаний, в которых Киф работал до перехода в Thoughtworks, по компоновке и масштабу можно охарактеризовать как постстартапы. Должности, на которые он претендовал и/или которые получал: инженер-программист, системный администратор, заместитель технологического директора, менеджер по НИОКР, менеджер по хостингу, техлид, технический архитектор, консультант, директор по облачной инженерии.