# Работает у меня — так отгрузи саму машину

Экспресс-курс о CI/CD и контейнерах. 21 понятие — deploy, works on my machine, continuous integration, shift left, continuous delivery и deployment, artifact, pipeline, fail fast, container, Docker, image, Kubernetes, desired state, rolling update, rollback, canary, blue-green, infrastructure as code — у каждого английское название, схема, карточка и пример. В конце — шпаргалка по всем понятиям и как они связаны.

- **Author:** Фёдор Чищин
- **Level:** intermediate
- **Reading time:** ~35 минут чтения
- **Published:** 2026-06-13
- **Source:** https://fedorthinks.com/ru/learn/cicd-express

---

## 1. Проблема деплоя

Написать код — лишь половина работы; безопасно показать его пользователям — другая половина. Долго эта вторая половина была медленной, ручной и страшной, и понять почему — ключ ко всему, что её чинит.

### Карта курса: 21 понятие в семи группах

> Карта метро: сначала видишь линии целиком, потом едешь по станциям.

Курс идёт по пути изменения — от ноутбука до пользователя. Сначала **проблема**: почему ручной деплой страшен. Потом **CI** (проверить каждое изменение), **CD** (довезти его до пользователей), **pipeline** (машина, которая всё это делает), **контейнеры** (одинаковая среда везде), **оркестрация** (много контейнеров на многих серверах) и **безопасные деплои** (как выкатывать, чтобы можно было отменить).

_Diagram: Семь групп понятий — по ним идут главы курса._

### Как читать каждое понятие

> Паспорт: одинаковые поля у всех, поэтому их легко сравнивать.

У каждого понятия дальше одно и то же: **английское название** (это термин, по которому его ищут в документации и обсуждают на работе), образ из жизни, **схема** и **карточка** с полями — проблема или «что это», идея, пример, цена или подвох, связи. Главная мысль курса одна: **выкатка должна быть скучной, автоматической и одинаковой везде.**

### Deploy — деплой, и почему руками он страшен

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

**Деплой (deploy)** — это просто «сделай новую версию живой». Старый способ — человек выполняет шаги руками: скопировать файлы на сервер, выполнить команды, скрестить пальцы. Это медленно, чревато ошибками и так рискованно, что команды деплоят редко, — что делает каждый релиз огромным, что делает его ещё рискованнее. Руками деплой становится самым стрессовым моментом недели. Вся область CI/CD существует, чтобы сделать этот момент скучным.

_Diagram: Порочный круг: деплоить руками страшно → деплоят редко → релизы огромные → ещё страшнее._

#### Deploy (деплой, release, выкатка)

- **Что это:** Сделать новую версию приложения живой для пользователей.
- **Пример:** Ручной деплой: зайти на сервер по SSH, скопировать файлы, перезапустить процесс — и надеяться.
- **Подвох:** Руками он медленный и рискованный — поэтому его делают редко, и каждый релиз становится огромным.
- **Связи:** Его автоматизируют **Continuous Delivery** и **Pipeline**; делают безопасным **Rollback**, **Canary** и **Blue-green**.

### Works on my machine — «работает у меня на машине»

> Рецепт, что выходит идеально на твоей кухне и проваливается на чужой, — другая духовка, другая мука, другая высота. Рецепт был не всей историей.

Код, что отлично работает на ноутбуке разработчика, часто ломается в проде, потому что две **среды (environments)** различаются — разные версии, настройки, библиотеки, операционная система. **«Работает у меня на машине» (it works on my machine)** — это панчлайн для целого класса багов, вызванных этими зазорами. Ноутбук и сервер — не одно и то же место, так что «работало там, где я собрал» не гарантирует ничего о том, где оно запущено.

_Diagram: Код один и тот же, а среда разная: другая версия рантайма, библиотек, ОС — и баг есть только в проде._

#### Works on my machine («работает у меня», environment drift)

- **Что это:** Баг, который появляется только в другой среде, потому что среды различаются.
- **Пример:** На ноутбуке Node 20, на сервере Node 16 — код, использующий новую функцию языка, падает только в проде.
- **Подвох:** Код — не вся история: важны версии, настройки, библиотеки и ОС вокруг него.
- **Связи:** Лечится **Container** — приложение везёт свою среду с собой; и **Artifact** — тестируешь то же, что отгружаешь.

### Boring releases — выкатка должна быть скучной

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

Цель всего курса — сделать выкатку **скучной**: настолько автоматизированной, проверенной и повторяемой, чтобы ты выпускал маленькие изменения много раз в день без драмы. Контринтуитивно, деплоить _чаще_ — _безопаснее_: каждый релиз крошечный (**small batches** — маленькие порции), так что если что-то ломается, причина очевидна, а починка мала. Редкие, гигантские, ручные релизы — вот опасные. «Скучный» — высший комплимент, что деплой может заслужить.

_Diagram: Сверху — два огромных страшных релиза. Снизу — десять маленьких: если один сломался, ясно, что именно._

#### Boring releases (small batches, частые маленькие релизы)

- **Проблема:** Большой релиз — сотни изменений, и при поломке непонятно, какое виновато.
- **Идея:** Выпускать маленькие изменения часто — автоматически и без драмы.
- **Пример:** Вместо одного релиза раз в месяц — несколько крошечных релизов в день, каждый в пару строк.
- **Цена:** Нужна автоматизация: руками так часто деплоить невозможно.
- **Связи:** Возможно только с **CI**, **Continuous Delivery** и **Rollback**.

> **Вопрос рамки:** «Выкатить изменение здесь — это спокойный, автоматический, будничный акт, или медленное, ручное, нервное событие, что я избегаю делать слишком часто?»

> Ручные деплои медленны, рискованны и редки — что делает их рискованнее. Цель обратна: выкатка настолько автоматическая и малая, что она скучна, делается много раз в день.

## 2. Continuous Integration

Первая половина CI/CD — про то, чтобы ловить проблемы в тот миг, как они появляются, автоматически собирая и тестируя каждое изменение, как оно прилетает, — чтобы общая кодовая база всегда работала.

### Continuous Integration (CI) — непрерывная интеграция

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

**Непрерывная интеграция (continuous integration, CI)** значит: каждый раз, как кто-то предлагает изменение, автоматическая система собирает проект и гоняет по нему тесты — за минуты, без человеческих рук. Если изменение ломает сборку или валит тест, ты узнаёшь сразу, пока оно мало и свежо в голове. CI — это всегда-включённый страж, что проверяет каждый вклад, прежде чем он натворит бед.

_Diagram: Каждый коммит попадает на CI-сервер: сборка и тесты. Прошло — можно мёржить; упало — автор узнаёт через минуты._

#### Continuous Integration (CI, непрерывная интеграция)

- **Проблема:** Сломанное изменение замечают через недели, когда оно уже переплелось с другими.
- **Идея:** Автоматически собирать и тестировать каждое изменение в момент, когда оно пришло.
- **Пример:** На каждый pull request сервис CI (например, GitHub Actions) запускает сборку и тесты и ставит зелёную или красную отметку.
- **Цена:** Нужны хорошие автотесты — CI проверяет только то, что ты проверяешь тестами.
- **Связи:** Ловит рано (**Shift left**), держит **Green main branch**; первый этап любого **Pipeline**.

### Shift left — лови поломку, пока она мала

> Заметить один криво положенный кирпич легко починить; обнаружить его лишь после постройки трёх этажей сверху — катастрофа. Рано — дёшево; поздно — дорого.

Ценность CI — в тайминге. Баг, пойманный в миг внесения, тривиально починить — ты точно знаешь, что изменилось. Тот же баг, обнаруженный недели спустя под всем, что построено сверху, может занять дни на распутывание. Это идея **shift left** — «сдвинуть влево» обнаружение проблем на временной шкале, ближе к моменту изменения. CI сдвигает поиск поломки с «много позже, смешано со всем» на «прямо сейчас, изолированно».

_Diagram: Чем позже нашли баг, тем дороже его чинить. CI сдвигает обнаружение влево — к самому коммиту._

#### Shift left (ловить рано)

- **Что это:** Находить проблемы как можно раньше — ближе к моменту изменения.
- **Пример:** Тест упал через 3 минуты после коммита — ты знаешь, какая строка виновата. Тот же баг в проде через месяц — дни расследования.
- **Подвох:** Проверки должны быть быстрыми: если CI идёт час, люди перестают его ждать.
- **Связи:** Главная ценность **CI**; тот же дух у **Fail fast**.

### Green main branch — главная ветка всегда рабочая

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

Глубже цель CI — держать **главную ветку (main branch)**, общую доверенную версию, всегда в рабочем состоянии. Изменение присоединяется к main, лишь если собирается и проходит тесты, так что main никогда не становится сломанным месивом, что блокирует всю команду. Это и делает возможной частую, уверенную выкатку: когда main всегда работает, можно выпускать из него в любой миг.

_Diagram: Ветка A прошла CI и влилась в main. Ветка B упала на CI — её не пустят, пока не починят._

#### Green main branch (main всегда зелёный)

- **Проблема:** Сломанный main блокирует всю команду и не даёт выпустить релиз.
- **Идея:** В main попадает только то, что собралось и прошло тесты.
- **Пример:** Правило репозитория: кнопка «Merge» неактивна, пока проверки CI не зелёные.
- **Цена:** Иногда приходится ждать CI и чинить тесты до мёржа.
- **Связи:** Обеспечивается **CI**; позволяет **Continuous Delivery** выпускать из main в любой момент.

> **Вопрос CI:** «Каждое ли изменение автоматически собирается и тестируется до того, как присоединится к общему коду, — чтобы поломка ловилась сразу, а main всегда работал?»

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

## 3. Continuous Delivery

Если CI следит, что каждое изменение хорошо, CD автоматизирует доставку этого хорошего изменения пользователям — превращая релиз из ручного ритуала в кнопку или вовсе без кнопки.

### Continuous Delivery (CD) — автоматизируй релиз, а не только тесты

> Заводская линия, что не останавливается на проверке качества, а несёт одобренный продукт до самого погрузочного дока и в грузовик, — никто не таскает коробки руками.

**Непрерывная доставка (continuous delivery, CD)** расширяет CI: после того как изменение прошло все автоматические проверки, система автоматически готовит его к релизу и может выкатить в прод. Ручные, чреватые ошибками шаги деплоя становятся кодом, что выполняется одинаково каждый раз. **CI доказывает, что изменение хорошо; CD доставляет это хорошее изменение пользователям** — без человека, печатающего команды в сервер в полночь.

_Diagram: CI отвечает за «изменение хорошее», CD — за «оно у пользователей». Весь путь — автоматический._

#### Continuous Delivery (CD, непрерывная доставка)

- **Проблема:** Изменение проверено, но выпускают его всё равно руками — медленно и с ошибками.
- **Идея:** Шаги релиза — это код; каждое хорошее изменение автоматически готово к выкатке.
- **Пример:** После зелёного CI скрипт собирает пакет, кладёт его в хранилище и одной кнопкой раскатывает в прод.
- **Цена:** Нужно один раз описать весь путь релиза кодом и доверять своим автотестам.
- **Связи:** Строится на **CI**; отгружает **Artifact**; работает внутри **Pipeline**.

### Continuous Delivery vs Continuous Deployment — кнопка или без кнопки

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

Есть тонкое разделение. **Continuous delivery** (непрерывная доставка) значит, что каждое хорошее изменение автоматически делается _готовым_ к деплою, но человек жмёт кнопку, чтобы выпустить. **Continuous deployment** (непрерывное развёртывание) идёт дальше: каждое прошедшее изменение выкатывается в прод автоматически, вообще без кнопки. Оба — «CD»; разница в том, одобряет ли человек финальный шаг.

_Diagram: Сверху — delivery: финальный шаг одобряет человек. Снизу — deployment: прошло проверки — сразу в прод._

#### Continuous Delivery vs Continuous Deployment (две буквы «D» в CD)

- **Что это:** Delivery — готово к релизу, человек жмёт кнопку. Deployment — релиз сам, без кнопки.
- **Пример:** Банк выпускает по кнопке после согласования (delivery); веб-сервис выкатывает каждый зелёный коммит сам (deployment).
- **Подвох:** Выбор зависит от того, насколько ты доверяешь своим автоматическим проверкам.
- **Связи:** Обе — виды **Continuous Delivery**; без кнопки особенно нужны **Canary** и **Rollback**.

### Artifact — артефакт: то, что ты отгружаешь

> Запечатанная, подписанная коробка, упакованная раз и затем отгружаемая, хранимая и доставляемая как единое целое, — а не пересобираемая из россыпи частей на каждой остановке.

Пайплайн производит **артефакт (artifact)** — единый, собранный, версионированный пакет твоего приложения, готовый запускаться. Ты собираешь его раз, и ровно тот же артефакт движется через тестирование, staging и прод, так что то, что ты тестировал, — в точности то, что ты отгружаешь. Если пересобирать на каждом этапе, могли бы вкрасться тонкие различия. **Build once, deploy everywhere** — один артефакт, собранный раз, развёрнутый везде, — убирает целый класс сюрпризов «но в тестах же прошло».

_Diagram: Собрали один раз — версия v1.4.2 едет и в тесты, и в staging, и в прод. Никаких пересборок по дороге._

#### Artifact (артефакт, build once — deploy everywhere)

- **Что это:** Один собранный, версионированный пакет приложения, готовый к запуску.
- **Пример:** `app v1.4.2` — один и тот же пакет проходит тесты, staging и прод.
- **Подвох:** Пересборка на каждом этапе — и в прод едет уже не то, что тестировали.
- **Связи:** Выход **Pipeline**; у контейнеров артефакт — это **Image**; делает возможным **Rollback**.

> **Вопрос CD:** «Как только изменение доказано хорошим, течёт ли оно к пользователям автоматически как один протестированный артефакт — или кто-то всё ещё собирает и деплоит его руками?»

> Непрерывная доставка автоматизирует релиз каждого хорошего изменения как единого собранного артефакта — жмёт ли человек финальную кнопку (delivery) или оно отгружается само (deployment).

## 4. Pipeline

CI и CD приводит в действие пайплайн: автоматическая сборочная линия, через которую изменение едет от коммита до прода, останавливаясь, если что-то идёт не так по пути.

### Pipeline — пайплайн, автоматическая сборочная линия

> Линия автозавода: шасси движется через сварку, покраску и проверку по порядку, каждая станция делает своё дело, прежде чем передать дальше, — ни один шаг не пропущен, ничего не таскают руками.

**Пайплайн (pipeline)** — это последовательность автоматических **этапов (stages)**, через которые проходит изменение на пути в прод, — обычно **build** (сборка), потом **test** (тесты), потом **deploy** (деплой). Коммит входит в один конец и, если всё хорошо, живой релиз выходит из другого, без человеческих шагов между. Пайплайн — это конкретная машина, что делает CI/CD реальным: вот где «автоматизировать весь путь» живёт на самом деле.

_Diagram: Коммит → build → test → deploy → живой релиз. Всё внутри рамки делает машина, а не человек._

#### Pipeline (пайплайн, CI/CD pipeline)

- **Что это:** Заданная последовательность автоматических этапов от коммита до прода.
- **Пример:** Файл конфигурации в репозитории описывает три этапа: `build` → `test` → `deploy`; сервис CI запускает их на каждом коммите.
- **Подвох:** Пайплайн тоже код: его надо поддерживать, и медленный пайплайн тормозит всю команду.
- **Связи:** Внутри живут **CI** и **Continuous Delivery**; защищён **Fail fast**; на выходе — **Artifact**.

### Fail fast — падай быстро: красный — стоп, зелёный — езжай

> Сборочная линия со шнуром, что любой может дёрнуть, чтобы остановить всё в миг появления дефекта, — и светофор на линии: зелёный — работа течёт дальше; красный — всё ждёт, пока проблему не расчистят.

Хороший пайплайн построен, чтобы **падать быстро (fail fast)**: если сборка ломается или тест валится на любом этапе, пайплайн останавливается, и изменение не идёт дальше. Пайплайны говорят на языке **зелёного** (прошёл) и **красного** (упал). Этот простой сигнал заменяет тревожное ручное суждение однозначным шлюзом. Правило команды простое: **никогда не строй на красном, никогда не отгружай на красном**.

_Diagram: Тесты покраснели — линия встала: deploy не запускается, прод не тронут. Зелёный — дальше, красный — стоп._

#### Fail fast (падать быстро, red/green)

- **Проблема:** Сломанное изменение может докатиться до прода, если линию не остановить.
- **Идея:** Любой красный этап сразу останавливает пайплайн; дальше идёт только зелёное.
- **Пример:** Два теста упали — этап `deploy` даже не стартует, команда сначала чинит.
- **Цена:** Нестабильные («мигающие») тесты останавливают линию зря — их надо чинить.
- **Связи:** Свойство безопасности **Pipeline**; тот же дух, что у **Shift left**.

> **Вопрос пайплайна:** «Едет ли каждое изменение по одной автоматической линии build-test-deploy, холодно останавливаясь в миг, как любой этап краснеет, — чтобы ничто сломанное не достигло прода?»

> Пайплайн — это автоматическая сборочная линия от коммита до прода: build, test, deploy, — что падает быстро и встаёт на красном, чтобы ни одно сломанное изменение не проскользнуло.

## 5. Контейнеры

Другая половина истории решает «работает у меня» напрямую: упаковать приложение со всем, что ему нужно, в один блок, что работает одинаково везде. Этот блок — контейнер.

### Container — контейнер: приложение вместе со средой

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

**Контейнер (container)** связывает твоё приложение со всем, что ему нужно для работы, — кодом, библиотеками, настройками, нужными версиями — в один самодостаточный блок. Поскольку он несёт свою среду, он работает одинаково, куда бы ты его ни поставил: ноутбук, тестовый сервер, прод. Контейнер не зависит от того, что установлено на хосте, так что зазоры, что вызывают «работает у меня», просто закрываются.

_Diagram: Внутри контейнера — код, библиотеки, настройки и рантайм. Поэтому он одинаково работает и на ноутбуке, и в проде._

#### Container (контейнер)

- **Что это:** Приложение плюс вся его среда, упакованные в один самодостаточный блок.
- **Пример:** Контейнер с твоим API и Node 20 внутри запускается одинаково на macOS-ноутбуке и Linux-сервере.
- **Подвох:** Контейнер чинит среду, но не баги в коде — тесты всё равно нужны.
- **Связи:** Лечит **Works on my machine**; запускается из **Image**; в масштабе им управляет **Kubernetes**.

### Docker — грузовой контейнер, что дал имя

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

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

_Diagram: Как стандартную коробку берёт любой кран, корабль и грузовик, так Docker-образ запускает любой ноутбук, CI и облако._

#### Docker (докер)

- **Что это:** Инструмент, который сделал контейнеры мейнстримом: собирает и запускает их.
- **Пример:** `docker build` собирает образ из Dockerfile, `docker run` запускает из него контейнер.
- **Подвох:** Стандарт — это коробка, а не содержимое: внутри всё равно должно быть рабочее приложение.
- **Связи:** Делает **Container** и **Image**; их запускает **Kubernetes**.

### Image vs Container — образ и контейнер: рецепт и блюдо

> Рецепт против приготовленного по нему блюда: одно — фиксированный набор инструкций, другое — конкретный экземпляр, которых можно сделать много, все одинаковые.

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

_Diagram: Dockerfile → build → образ (лежит в registry) → run → сколько угодно одинаковых работающих контейнеров._

#### Image vs Container (образ и контейнер)

- **Что это:** Image — замороженный чертёж (рецепт). Container — работающий экземпляр из него (блюдо).
- **Пример:** Один образ `api:1.4.2` — пять одинаковых работающих контейнеров.
- **Подвох:** Менять что-то внутри работающего контейнера бесполезно — меняй образ и пересобирай.
- **Связи:** Image — это **Artifact** для контейнеров; копии из него держит **Kubernetes**.

> **Вопрос контейнера:** «Несёт ли это приложение всю свою среду в контейнере, чтобы работать одинаково на моём ноутбуке и в проде, — вместо того чтобы зависеть от того, что случайно установлено?»

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

## 6. Оркестрация

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

### Orchestration / Kubernetes — дирижёр контейнеров

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

Как только у тебя много контейнеров на многих серверах, что-то должно решать, где каждый работает, перезапускать те, что умерли, и балансировать нагрузку. Это **оркестрация (orchestration)**, и доминирующий инструмент — **Kubernetes**. Ты говоришь ему желаемое состояние — «гоняй пять копий этого сервиса» — и он непрерывно работает, чтобы реальность совпала: размещает контейнеры, следит за ними и исправляет расхождения.

_Diagram: Ты говоришь «5 копий» — Kubernetes сам раскладывает их по серверам (node), следит и перезапускает._

#### Kubernetes (K8s, оркестратор контейнеров)

- **Проблема:** Сотни контейнеров на многих серверах вручную не уследить.
- **Идея:** Оркестратор сам решает, где запустить каждый контейнер, перезапускает упавшие и балансирует нагрузку.
- **Пример:** Описываешь в YAML сервис с `replicas: 5` — Kubernetes держит пять копий на разных серверах.
- **Цена:** Сложная система со своим языком; для одного маленького сервиса часто избыточна.
- **Связи:** Запускает **Container** из **Image**; держит **Desired state**; делает **Rolling update**.

### Desired state — желаемое состояние: самовосстановление и автомасштабирование

> Термостат, что ты ставишь на целевую температуру: он постоянно чувствует комнату и подстраивается сам, без того чтобы ты трогал его снова. Ты объявляешь цель; он её держит.

Оркестрация **декларативна (declarative)**: ты описываешь цель, а не шаги. Скажи «всегда держи пять здоровых копий», и если одна падает, система запускает замену автоматически — **самовосстановление (self-healing)**. Если трафик всплёскивает, она может добавить копий и убрать их, когда спрос падает, — **автомасштабирование (auto-scaling)**. Ты перестаёшь нянчить серверы руками и объявляешь, что хочешь. Этот сдвиг от «делать» к «объявлять» — суть всего.

_Diagram: Бесконечная петля: сравнить желаемое с реальным, исправить расхождение. Упала копия — запустили новую._

#### Desired state (декларативность, self-healing, auto-scaling)

- **Что это:** Ты объявляешь цель («5 здоровых копий»), система сама постоянно приводит реальность к ней.
- **Пример:** Одна копия упала ночью — через секунды на её месте новая, и никто не проснулся.
- **Подвох:** Система держит ровно то, что ты описал: неверная цель тоже будет держаться упорно.
- **Связи:** Сердце **Kubernetes**; та же идея «описать, а не делать руками» у **Infrastructure as Code**.

### Rolling update — накатывающее обновление без простоя

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

Оркестрация даёт обновлять без простоя через **накатывающее обновление (rolling update)**: она заменяет старые контейнеры новыми по несколько за раз, проверяя, что каждый здоров (**health check**), прежде чем продолжить, так что сервис остаётся живым всё время. Если новая версия ведёт себя плохо, она может остановиться и **откатиться (roll back)** к старой автоматически. Так современные сервисы выкатывают обновления без окна обслуживания — вживую, постепенно и обратимо.

_Diagram: Копии меняются с v1 на v2 по несколько за раз, каждая проверяется — сервис работает на всём пути._

#### Rolling update (накатывающее обновление)

- **Проблема:** Обновление через остановку сервиса — это простой для пользователей.
- **Идея:** Менять копии по несколько за раз, проверяя здоровье каждой новой.
- **Пример:** Из четырёх копий v1 сначала две становятся v2, потом оставшиеся две — сервис не падал ни секунды.
- **Цена:** Какое-то время работают обе версии сразу — они должны уметь жить рядом.
- **Связи:** Делает **Kubernetes**; при проблеме — **Rollback**; родственники — **Canary** и **Blue-green**.

> **Вопрос оркестрации:** «Кто держит эти контейнеры работающими, масштабирует их под спрос и обновляет без простоя — я делаю это руками или объявляю желаемое состояние и даю оркестратору его держать?»

> Оркестрация (Kubernetes) гоняет много контейнеров через много машин: ты объявляешь желаемое состояние, а она самовосстанавливается, автомасштабируется и накатывает обновления без простоя.

## 7. Деплоить безопасно

Вся эта машинерия существует, чтобы сделать выкатку безопасной и частой. Финальные привычки — про снижение радиуса взрыва (blast radius) любого одного релиза, потому что самый безопасный деплой — тот, что можно отменить.

### Rollback — откат: всегда имей путь назад

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

Самое важное свойство безопасности — **откат (rollback)**: способность мгновенно вернуться к последней заведомо хорошей версии, когда релиз идёт не так. Поскольку пайплайн отгружает версионированные артефакты, вернуться назад — это просто передеплоить предыдущий. Знание, что можно отменить деплой за секунды, делает частую выкатку безопасной: плохая версия — мелкий, обратимый сбой, а не кризис. **Никогда не отгружай то, что не можешь забрать назад.**

_Diagram: v43 сломалась — передеплоили прошлый хороший артефакт v42. Секунды, а не ночь пожара._

#### Rollback (откат)

- **Проблема:** Плохой релиз уже в проде, а починка займёт часы.
- **Идея:** Мгновенно вернуть последнюю хорошую версию, а чинить — спокойно потом.
- **Пример:** v43 сыпет ошибками — одной командой в прод снова едет артефакт v42.
- **Цена:** Нужны версионированные артефакты; изменения базы данных откатить сложнее, чем код.
- **Связи:** Работает благодаря **Artifact**; встроен в **Rolling update**, **Canary** и **Blue-green**.

### Canary release — канарейка: сначала немногим

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

Деплой **canary** («канарейка») шлёт новую версию сперва малому срезу пользователей. Если их метрики остаются здоровыми, ты выкатываешь её всем, а если нет — забираешь назад, задев почти никого. Так релиз из ставки «всё или ничего» превращается в управляемый, обратимый шаг, и **радиус взрыва (blast radius)** ошибки остаётся маленьким.

_Diagram: Роутер шлёт 5% трафика на новую версию. Метрики в порядке — раскатываем на всех; нет — забираем назад._

#### Canary release (канареечный релиз)

- **Проблема:** Ошибка в новой версии сразу бьёт по всем пользователям.
- **Идея:** Сначала дать новую версию малой доле трафика и смотреть на метрики.
- **Пример:** 5% пользователей получают v2; ошибок не больше, чем у v1, — доля растёт до 100%.
- **Цена:** Нужны роутинг по долям трафика и хорошие метрики, чтобы судить.
- **Связи:** Плохо — **Rollback**; соседи — **Blue-green** и **Rolling update**.

### Blue-green deployment — две среды и один переключатель

> Две одинаковые сцены в театре: на одной идёт спектакль, на другой готовят новый. В нужный момент зрителей просто разворачивают ко второй — а первая стоит готовой на случай отката.

**Blue-green** держит две продакшен-среды и переключает трафик со старой (**blue**) на новую (**green**) разом, с мгновенным переключением назад при нужде. Новая версия разворачивается и проверяется, пока старая ещё обслуживает пользователей; потом один переключатель — и все на новой. Как и canary, это превращает релиз в управляемый, обратимый шаг.

_Diagram: Роутер переводит весь трафик с blue (v1) на green (v2) одним переключением; blue остаётся готовой для отката._

#### Blue-green deployment (сине-зелёный деплой)

- **Проблема:** Переключение на новую версию «на живую» рискованно и плохо откатывается.
- **Идея:** Две полные среды; трафик переключается со старой на новую разом.
- **Пример:** v2 поднята в green и проверена; роутер переводит на неё 100% трафика; при проблеме — обратно на blue.
- **Цена:** Нужно держать две полные среды — это вдвое больше ресурсов на время релиза.
- **Связи:** Мгновенный **Rollback**; в отличие от **Canary** переключает всех сразу.

### Infrastructure as Code (IaC) — инфраструктура как код

> Чертёж, по которому можно точно отстроить весь дом заново, против дома, построенного по памяти, что никто не воспроизведёт, если он сгорит.

Та же дисциплина распространяется на сами серверы. **Инфраструктура как код (infrastructure as code, IaC)** значит определять серверы, сети и конфигурацию в файлах, а не кликая по консоли руками. Теперь вся среда версионирована, ревьюируема и воспроизводима — её можно отстроить идентично, а изменения идут через тот же пайплайн, что и код. Это закрывает последний зазор, где «кто-то сменил настройку руками и забыл» мог бы отменить всю строгость в остальном.

_Diagram: Файлы инфраструктуры → ревью в git → пайплайн применяет их к staging и проду. Никаких ручных кликов в консоли._

#### Infrastructure as Code (IaC, инфраструктура как код)

- **Проблема:** Кто-то поменял настройку сервера руками и забыл — среду уже не воспроизвести.
- **Идея:** Описывать серверы, сети и настройки в файлах и менять их через тот же пайплайн.
- **Пример:** Файлы Terraform описывают сервер и базу; правка проходит ревью и применяется пайплайном.
- **Цена:** Ещё один язык и дисциплина: никаких «быстрых правок» руками в консоли.
- **Связи:** Едет через **Pipeline**; та же декларативная идея, что у **Desired state**.

#### Прежде чем полагаться на процесс деплоя

- **Автоматизирован ли он** от края до края — от коммита до прода через пайплайн, а не руками?
- **Собирает и тестирует ли CI** каждое изменение, держа main всегда рабочим?
- **То, что ты отгружаешь, — единый артефакт** или контейнер, идентичный от теста до прода?
- **Можешь ли ты откатиться** мгновенно к последней хорошей версии?
- **Выходят ли рискованные релизы постепенно** — canary или blue-green, а не всё разом?
- **Сама ли инфраструктура — код** — версионированная и воспроизводимая?

> Безопасная выкатка — это обратимая выкатка: автоматизируй пайплайн, отгружай один протестированный артефакт, держи откат в одно нажатие, выпускай рискованное постепенно и описывай инфраструктуру как код.

## 8. Как всё связано

Двадцать одно понятие — это одна линия. Изменение проходит CI, превращается в один артефакт, CD доставляет его, оркестратор запускает, а безопасные приёмы выкатки страхуют. Под всем этим — инфраструктура, описанная кодом.

### Одна картина: от коммита до пользователя

> Маршрут посылки: упаковали один раз, проверили на складе, отвезли, вручили — и на каждом шаге можно вернуть отправителю.

Читай схему слева направо: **Commit** → **CI** (сборка и тесты, на красном — стоп) → **Image** (артефакт, собран один раз) → **CD** (релиз) → **Kubernetes** (запускает и держит желаемое состояние). Как выкатывать безопасно, решают **Rolling update**, **Canary**, **Blue-green** и **Rollback**. А **Infrastructure as Code** — это те же правила для самих серверов: они тоже идут через пайплайн.

_Diagram: Пайплайн сверху, приёмы безопасной выкатки посередине, инфраструктура как код — фундамент, который идёт тем же путём._

#### Признаки, что ты отгружаешь хорошо

- Выкатка **скучна** — малая, автоматическая, делается часто, а не редкое страшное событие.
- **CI зелёный** до того, как что-то мёржится, и **main всегда работает**.
- Ты отгружаешь **тот же артефакт/контейнер**, что тестировал, до самого прода.
- Плохой релиз — это быстрый **откат**, а не кризис.
- Рискованные изменения выходят через **canary или blue-green**, а твоя инфра — это **код**.

## Шпаргалка: все 21 понятие

### Проблема деплоя

- **Deploy** (деплой, release): Сделать новую версию живой. Руками — медленно, страшно и редко.
- **Works on my machine** («работает у меня»): Баг из-за разницы сред: код тот же, версии и настройки — нет.
- **Boring releases** (small batches): Маленькие частые релизы безопаснее редких огромных.

### Continuous Integration

- **Continuous Integration** (CI): Каждое изменение автоматически собирается и тестируется за минуты.
- **Shift left** (ловить рано): Чем раньше нашёл баг, тем дешевле его чинить.
- **Green main branch** (main всегда рабочий): В main попадает только то, что прошло CI.

### Continuous Delivery

- **Continuous Delivery** (CD): Релиз хорошего изменения автоматизирован: шаги деплоя — это код.
- **Delivery vs Deployment** (кнопка или без кнопки): Delivery — человек жмёт кнопку; deployment — в прод само.
- **Artifact** (build once, deploy everywhere): Один собранный пакет едет через все среды — тестируешь то, что отгружаешь.

### Pipeline

- **Pipeline** (пайплайн): Автоматическая линия: build → test → deploy.
- **Fail fast** (red / green): Красный этап останавливает линию; дальше идёт только зелёное.

### Контейнеры

- **Container** (контейнер): Приложение вместе со средой — работает одинаково везде.
- **Docker** (докер): Инструмент, сделавший контейнеры стандартной «коробкой».
- **Image vs Container** (рецепт и блюдо): Образ — замороженный чертёж; контейнер — работающий экземпляр из него.

### Оркестрация

- **Kubernetes** (оркестратор): Раскладывает контейнеры по серверам, следит, перезапускает.
- **Desired state** (self-healing, auto-scaling): Объявляешь цель — система сама держит реальность в ней.
- **Rolling update** (накатывающее обновление): Меняет копии по несколько за раз — без простоя.

### Безопасные деплои

- **Rollback** (откат): Мгновенно вернуть последнюю хорошую версию.
- **Canary release** (канарейка): Новая версия сначала для малой доли пользователей.
- **Blue-green deployment** (две среды): Трафик переключается со старой среды на новую разом и обратно.
- **Infrastructure as Code** (IaC): Серверы и сети описаны в файлах и меняются через пайплайн.

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

Конец экспресс-курса · 8 глав · 21 понятие

Дальше — практика: возьми маленький проект, напиши Dockerfile, чтобы он работал в контейнере, и настрой пайплайн, что собирает и тестирует его на каждом изменении. Потом задеплой его, сломай и откатись. Вся философия щёлкает в тот миг, как релиз перестаёт ощущаться страшным, потому что ты знаешь, что линия его поймала, а ты можешь его отменить. Но держи одну мысль выше прочих: выкатка должна быть скучной. Автоматизируй путь, чтобы каждое изменение собиралось, тестировалось и деплоилось одинаково, и упакуй приложение, чтобы оно работало одинаково везде, — и «работает у меня на машине» наконец станет «работает везде».
