Модуль 2.4: Стратегії деплойменту
Складність:
[MEDIUM]— концептуальне розуміння з практичною реалізацієюЧас на виконання: 40–50 хвилин
Передумови: Модуль 2.1 (Деплойменти), розуміння Сервісів
Що ви зможете робити
Розділ «Що ви зможете робити»Після завершення цього модуля ви зможете:
- Реалізувати blue/green та canary деплойменти, використовуючи нативні ресурси Kubernetes
- Порівняти стратегії ковзного оновлення, blue/green та canary з їх компромісами
- Спроєктувати стратегію деплойменту, що відповідає вимогам доступності та відкату
- Оцінити стан деплойменту під час розгортання та вирішити, коли продовжувати або відкочувати
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Те, як ви розгортаєте нові версії, має значення. Погана стратегія деплойменту може спричинити простій, пошкодження даних або помилки, видимі користувачам. CKAD очікує, що ви розумієте різні стратегії деплойменту та коли використовувати кожну.
Ви зіткнетесь із такими питаннями:
- Реалізувати blue/green-деплоймент
- Налаштувати canary-реліз
- Налаштувати параметри ковзного оновлення
- Обрати відповідну стратегію для сценарію
Аналогія з рестораном
Ковзні оновлення — це як поступова заміна страв у меню — клієнти, що замовляють у різний час, можуть отримати дещо різне меню. Blue/green — це як мати дві повноцінні кухні — ви переводите всіх клієнтів на нову кухню одночасно. Canary-релізи — це як дати нову страву спочатку 10% клієнтів — якщо їм сподобається, її отримають усі.
Огляд стратегій
Розділ «Огляд стратегій»Порівняння
Розділ «Порівняння»| Стратегія | Простій | Відкат | Вартість ресурсів | Ризик |
|---|---|---|---|---|
| Rolling Update | Немає | Повільний (поступовий) | Низька | Середній |
| Recreate | Так | Швидкий (перерозгортання старого) | Низька | Високий |
| Blue/Green | Немає | Миттєвий | 2x ресурсів | Низький |
| Canary | Немає | Миттєвий | Низька–середня | Дуже низький |
Коли використовувати кожну
Розділ «Коли використовувати кожну»| Стратегія | Найкраще для |
|---|---|
| Rolling Update | Більшість застосунків, вибір за замовчуванням |
| Recreate | Застосунки, що не можуть працювати з кількома версіями |
| Blue/Green | Критичні застосунки, що потребують миттєвого відкату |
| Canary | Обережні деплойменти, тестування з реальним трафіком |
Rolling Update (за замовчуванням)
Розділ «Rolling Update (за замовчуванням)»Kubernetes поступово замінює старі поди новими.
Конфігурація
Розділ «Конфігурація»apiVersion: apps/v1kind: Deploymentmetadata: name: web-appspec: replicas: 4 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # Може перевищити кількість реплік на 1 maxUnavailable: 1 # Максимум 1 недоступний selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: nginx image: nginx:1.20Поведінка оновлення
Розділ «Поведінка оновлення»З replicas=4, maxSurge=1, maxUnavailable=1:
Старт: [v1] [v1] [v1] [v1] (4 працюють)Крок 1: [v1] [v1] [v1] [--] [v2] (3 старих, 1 новий стартує)Крок 2: [v1] [v1] [--] [v2] [v2] (2 старих, 2 нових)Крок 3: [v1] [--] [v2] [v2] [v2] (1 старий, 3 нових)Крок 4: [v2] [v2] [v2] [v2] (4 нових, завершено)Запуск ковзного оновлення
Розділ «Запуск ковзного оновлення»# Оновити образk set image deploy/web-app nginx=nginx:1.21
# Спостерігати за розгортаннямk rollout status deploy/web-app
# Перевірити перехід подівk get pods -l app=web -wСтратегія Recreate
Розділ «Стратегія Recreate»Усі наявні поди знищуються перед створенням нових.
Конфігурація
Розділ «Конфігурація»apiVersion: apps/v1kind: Deploymentmetadata: name: database-appspec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: database template: metadata: labels: app: database spec: containers: - name: postgres image: postgres:13Поведінка оновлення
Розділ «Поведінка оновлення»Старт: [v1] [v1] [v1]Крок 1: [--] [--] [--] (усі старі поди завершені)Крок 2: [v2] [v2] [v2] (усі нові поди створені)Коли використовувати
Розділ «Коли використовувати»- Застосунки баз даних з вимогою єдиного запису
- Застосунки з блокуванням файлової системи
- Застосунки, що не можуть працювати з кількома версіями, які мають доступ до спільного стану
- Stateful-застосунки без належної підтримки міграції
Blue/Green-деплоймент
Розділ «Blue/Green-деплоймент»Запуск двох ідентичних середовищ. Миттєве перемикання трафіку через оновлення селектора Сервісу.
Реалізація
Розділ «Реалізація»Крок 1: Розгортання Blue (поточний)
apiVersion: apps/v1kind: Deploymentmetadata: name: app-bluespec: replicas: 3 selector: matchLabels: app: myapp version: blue template: metadata: labels: app: myapp version: blue spec: containers: - name: app image: myapp:1.0Крок 2: Створення Сервісу (вказує на Blue)
apiVersion: v1kind: Servicemetadata: name: myappspec: selector: app: myapp version: blue # Вказує на blue ports: - port: 80Крок 3: Розгортання Green (нова версія)
apiVersion: apps/v1kind: Deploymentmetadata: name: app-greenspec: replicas: 3 selector: matchLabels: app: myapp version: green template: metadata: labels: app: myapp version: green spec: containers: - name: app image: myapp:2.0Крок 4: Перемикання трафіку
# Перемикнути сервіс на greenk patch svc myapp -p '{"spec":{"selector":{"version":"green"}}}'
# Миттєвий відкат, якщо потрібноk patch svc myapp -p '{"spec":{"selector":{"version":"blue"}}}'Повний скрипт Blue/Green
Розділ «Повний скрипт Blue/Green»# Розгорнути bluek apply -f blue-deployment.yaml
# Створити сервіс, що вказує на bluek apply -f service.yaml
# Протестувати bluek run test --image=busybox --rm -it --restart=Never -- wget -qO- http://myapp
# Розгорнути green (без трафіку)k apply -f green-deployment.yaml
# Протестувати green напряму (port-forward або окремий сервіс)k port-forward deploy/app-green 8080:80 &curl localhost:8080
# Перемикнути трафік на greenk patch svc myapp -p '{"spec":{"selector":{"version":"green"}}}'
# Якщо проблеми — миттєвий відкатk patch svc myapp -p '{"spec":{"selector":{"version":"blue"}}}'
# Після підтвердження — видалити bluek delete deploy app-blueCanary-деплоймент
Розділ «Canary-деплоймент»Направлення невеликого відсотка трафіку на нову версію. Поступове збільшення у разі успіху.
Реалізація з кількома Деплойментами
Розділ «Реалізація з кількома Деплойментами»Стабільний Деплоймент (90% трафіку)
apiVersion: apps/v1kind: Deploymentmetadata: name: app-stablespec: replicas: 9 # 90% трафіку selector: matchLabels: app: myapp track: stable template: metadata: labels: app: myapp track: stable spec: containers: - name: app image: myapp:1.0Canary-деплоймент (10% трафіку)
apiVersion: apps/v1kind: Deploymentmetadata: name: app-canaryspec: replicas: 1 # 10% трафіку selector: matchLabels: app: myapp track: canary template: metadata: labels: app: myapp track: canary spec: containers: - name: app image: myapp:2.0Сервіс (маршрутизує до обох)
apiVersion: v1kind: Servicemetadata: name: myappspec: selector: app: myapp # Збігається і зі stable, і з canary ports: - port: 80Розподіл трафіку
Розділ «Розподіл трафіку»З 9 стабільними подами та 1 canary-подом:
- ~90% трафіку → stable (v1.0)
- ~10% трафіку → canary (v2.0)
Поступове canary-розгортання
Розділ «Поступове canary-розгортання»# Старт: 9 стабільних, 1 canary (10%)k scale deploy app-canary --replicas=1k scale deploy app-stable --replicas=9
# Збільшити canary до 25%k scale deploy app-canary --replicas=3k scale deploy app-stable --replicas=9
# Збільшити canary до 50%k scale deploy app-canary --replicas=5k scale deploy app-stable --replicas=5
# Повне розгортання (100% нова версія)k scale deploy app-canary --replicas=10k scale deploy app-stable --replicas=0
# Очищення: перейменувати canary на stablek delete deploy app-stablek patch deploy app-canary -p '{"metadata":{"name":"app-stable"}}'Параметри Rolling Update — глибоке занурення
Розділ «Параметри Rolling Update — глибоке занурення»maxSurge
Розділ «maxSurge»Максимальна кількість подів, що можуть бути створені понад бажану кількість:
rollingUpdate: maxSurge: 25% # 25% додаткових подів (за замовчуванням) # або maxSurge: 2 # 2 додаткових подиmaxUnavailable
Розділ «maxUnavailable»Максимум подів, що можуть бути недоступні під час оновлення:
rollingUpdate: maxUnavailable: 25% # 25% можуть бути вимкнені (за замовчуванням) # або maxUnavailable: 0 # Нульовий час простоюТипові конфігурації
Розділ «Типові конфігурації»# Нульовий час простою (консервативний)rollingUpdate: maxSurge: 1 maxUnavailable: 0
# Швидке оновлення (агресивний)rollingUpdate: maxSurge: 100% maxUnavailable: 50%
# Збалансований (за замовчуванням)rollingUpdate: maxSurge: 25% maxUnavailable: 25%Readiness Gates та проби
Розділ «Readiness Gates та проби»Правильні проби забезпечують гладке розгортання.
Проба готовності для Деплойментів
Розділ «Проба готовності для Деплойментів»spec: template: spec: containers: - name: app image: myapp readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5Без проб готовності Kubernetes вважає поди готовими одразу — трафік може потрапити до подів, які ще не повністю ініціалізовані.
minReadySeconds
Розділ «minReadySeconds»spec: minReadySeconds: 10 # Под має бути готовим 10 с, перш ніж буде вважатися доступнимЦе додає буфер для виявлення ранніх збоїв.
Практичні сценарії для іспиту
Розділ «Практичні сценарії для іспиту»Сценарій 1: Ковзне оновлення з нульовим простоєм
Розділ «Сценарій 1: Ковзне оновлення з нульовим простоєм»apiVersion: apps/v1kind: Deploymentmetadata: name: webappspec: replicas: 4 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 # Ключове: ніколи не зменшувати нижче бажаного selector: matchLabels: app: webapp template: metadata: labels: app: webapp spec: containers: - name: nginx image: nginx:1.20 readinessProbe: # Важливо для нульового простою httpGet: path: / port: 80 initialDelaySeconds: 2 periodSeconds: 3Сценарій 2: Швидке перемикання Blue/Green
Розділ «Сценарій 2: Швидке перемикання Blue/Green»# Створити blue-деплойментk create deploy app-blue --image=nginx:1.20 --replicas=3k label deploy app-blue version=blue
# Додати мітку версії до шаблону подівk patch deploy app-blue -p '{"spec":{"template":{"metadata":{"labels":{"version":"blue"}}}}}'
# Створити сервісk expose deploy app-blue --name=myapp --port=80 --selector=version=blue
# Розгорнути greenk create deploy app-green --image=nginx:1.21 --replicas=3k patch deploy app-green -p '{"spec":{"template":{"metadata":{"labels":{"version":"green"}}}}}'
# Перемикнути на greenk patch svc myapp -p '{"spec":{"selector":{"version":"green"}}}'Чи знали ви?
Розділ «Чи знали ви?»-
Ковзні оновлення Kubernetes є самовідновлювальними. Якщо новий под не проходить пробу готовності, розгортання автоматично призупиняється, запобігаючи повному розгортанню поганої версії.
-
Blue/green-деплойменти потребують 2x ресурсів під час перемикання. Це їхній головний недолік, але дозволяє миттєвий відкат.
-
Canary-деплойменти виникли в Google. Термін походить від «канарки у вугільній шахті» — шахтарі використовували канарок для виявлення токсичних газів. Якщо канарка гинула, шахтарі знали, що треба евакуюватися.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це шкодить | Рішення |
|---|---|---|
| Немає проби готовності | Трафік на неготові поди | Завжди додавайте проби готовності |
maxUnavailable: 100% | Усі поди знищуються одночасно | Тримайте на 25% або менше |
| Неправильний селектор сервісу для blue/green | Трафік не перемикається | Перевіряйте збіг міток |
| Не тестували canary окремо | Проблеми canary не виявлені | Спочатку протестуйте canary-поди напряму |
| Забули зменшити старий деплоймент | Марнування ресурсів | Зменшуйте після успішного перемикання |
Тест
Розділ «Тест»-
Яка стратегія деплойменту знищує всі старі поди перед створенням нових?
Відповідь
`Recreate`. Усі наявні поди завершуються перед створенням нових подів, що спричиняє простій. -
Як миттєво перемикнути трафік у blue/green?
Відповідь
Запатчити селектор Сервісу, щоб вказати на мітки нового деплойменту: `kubectl patch svc myapp -p '{"spec":{"selector":{"version":"green"}}}'` -
З 10 репліками та maxSurge=2, maxUnavailable=1 — скільки подів може існувати під час оновлення?
Відповідь
Максимум 12 подів (10 + maxSurge 2). Мінімум 9 доступних подів (10 - maxUnavailable 1). -
Як досягти 10% canary-трафіку за допомогою кількості подів?
Відповідь
Запустити 9 стабільних подів та 1 canary-под, із Сервісом, що вибирає обох. Трафік розподіляється приблизно пропорційно кількості подів: ~90% stable, ~10% canary.
Практична вправа
Розділ «Практична вправа»Завдання: Реалізувати всі три стратегії деплойменту.
Частина 1: Rolling Update з параметрами
# Створити деплоймент з кастомним ковзним оновленнямcat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: rolling-demospec: replicas: 4 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: rolling template: metadata: labels: app: rolling spec: containers: - name: nginx image: nginx:1.20EOF
# Оновити та спостерігати (має бути макс. 5 подів)k set image deploy/rolling-demo nginx=nginx:1.21k get pods -l app=rolling -w
# Очищенняk delete deploy rolling-demoЧастина 2: Blue/Green-деплоймент
# Blue-деплойментcat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: bluespec: replicas: 3 selector: matchLabels: app: demo version: blue template: metadata: labels: app: demo version: blue spec: containers: - name: nginx image: nginx:1.20EOF
# Сервіс, що вказує на bluecat << 'EOF' | k apply -f -apiVersion: v1kind: Servicemetadata: name: demo-svcspec: selector: app: demo version: blue ports: - port: 80EOF
# Green-деплойментcat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: greenspec: replicas: 3 selector: matchLabels: app: demo version: green template: metadata: labels: app: demo version: green spec: containers: - name: nginx image: nginx:1.21EOF
# Перемикнути на greenk patch svc demo-svc -p '{"spec":{"selector":{"version":"green"}}}'
# Відкат на bluek patch svc demo-svc -p '{"spec":{"selector":{"version":"blue"}}}'
# Очищенняk delete deploy blue greenk delete svc demo-svcЧастина 3: Canary-деплоймент
# Стабільний деплоймент (9 реплік)cat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: stablespec: replicas: 9 selector: matchLabels: app: canary-demo track: stable template: metadata: labels: app: canary-demo track: stable spec: containers: - name: nginx image: nginx:1.20EOF
# Canary-деплоймент (1 репліка = ~10%)cat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: canaryspec: replicas: 1 selector: matchLabels: app: canary-demo track: canary template: metadata: labels: app: canary-demo track: canary spec: containers: - name: nginx image: nginx:1.21EOF
# Сервіс маршрутизує до обохcat << 'EOF' | k apply -f -apiVersion: v1kind: Servicemetadata: name: canary-svcspec: selector: app: canary-demo ports: - port: 80EOF
# Поступове збільшення canaryk scale deploy canary --replicas=3 # ~25%k scale deploy stable --replicas=7
# Повне розгортанняk scale deploy canary --replicas=10k scale deploy stable --replicas=0
# Очищенняk delete deploy stable canaryk delete svc canary-svcПрактичні вправи
Розділ «Практичні вправи»Вправа 1: Конфігурація Rolling Update (Ціль: 3 хвилини)
Розділ «Вправа 1: Конфігурація Rolling Update (Ціль: 3 хвилини)»# Створити зі специфічними налаштуваннями ковзного оновленняk create deploy drill1 --image=nginx:1.20 --replicas=4
# Запатчити стратегіюk patch deploy drill1 -p '{"spec":{"strategy":{"type":"RollingUpdate","rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
# Оновити та спостерігатиk set image deploy/drill1 nginx=nginx:1.21k rollout status deploy/drill1
# Очищенняk delete deploy drill1Вправа 2: Стратегія Recreate (Ціль: 2 хвилини)
Розділ «Вправа 2: Стратегія Recreate (Ціль: 2 хвилини)»# Створити зі стратегією recreatecat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: drill2spec: replicas: 3 strategy: type: Recreate selector: matchLabels: app: drill2 template: metadata: labels: app: drill2 spec: containers: - name: nginx image: nginx:1.20EOF
# Оновити (спостерігати, як усі поди спочатку завершуються)k set image deploy/drill2 nginx=nginx:1.21k get pods -l app=drill2 -w
# Очищенняk delete deploy drill2Вправа 3: Перемикання Blue/Green (Ціль: 4 хвилини)
Розділ «Вправа 3: Перемикання Blue/Green (Ціль: 4 хвилини)»# Створити bluek create deploy blue --image=nginx:1.20 --replicas=2k patch deploy blue -p '{"spec":{"selector":{"matchLabels":{"version":"blue"}},"template":{"metadata":{"labels":{"version":"blue"}}}}}'
# Сервісk expose deploy blue --name=app --port=80 --selector=version=blue
# Створити greenk create deploy green --image=nginx:1.21 --replicas=2k patch deploy green -p '{"spec":{"selector":{"matchLabels":{"version":"green"}},"template":{"metadata":{"labels":{"version":"green"}}}}}'
# Перемикнутиk patch svc app -p '{"spec":{"selector":{"version":"green"}}}'
# Перевіритиk get ep app
# Очищенняk delete deploy blue greenk delete svc appВправа 4: Відсоток Canary (Ціль: 3 хвилини)
Розділ «Вправа 4: Відсоток Canary (Ціль: 3 хвилини)»# 10% canaryk create deploy stable --image=nginx:1.20 --replicas=9k create deploy canary --image=nginx:1.21 --replicas=1
# Додати спільну міткуk patch deploy stable -p '{"spec":{"template":{"metadata":{"labels":{"app":"myapp"}}}}}'k patch deploy canary -p '{"spec":{"template":{"metadata":{"labels":{"app":"myapp"}}}}}'
# Сервіс для обохk expose deploy stable --name=myapp --port=80 --selector=app=myapp
# Перевірити, що endpoints включають обохk get ep myapp
# Очищенняk delete deploy stable canaryk delete svc myappВправа 5: Перевірка нульового простою (Ціль: 3 хвилини)
Розділ «Вправа 5: Перевірка нульового простою (Ціль: 3 хвилини)»# Створити деплоймент з пробою готовностіcat << 'EOF' | k apply -f -apiVersion: apps/v1kind: Deploymentmetadata: name: drill5spec: replicas: 3 strategy: rollingUpdate: maxUnavailable: 0 selector: matchLabels: app: drill5 template: metadata: labels: app: drill5 spec: containers: - name: nginx image: nginx:1.20 readinessProbe: httpGet: path: / port: 80EOF
# Сервісk expose deploy drill5 --port=80
# Оновити (нульовий простій)k set image deploy/drill5 nginx=nginx:1.21k rollout status deploy/drill5
# Очищенняk delete deploy drill5k delete svc drill5Вправа 6: Повний сценарій стратегії деплойменту (Ціль: 6 хвилин)
Розділ «Вправа 6: Повний сценарій стратегії деплойменту (Ціль: 6 хвилин)»Сценарій: Production-деплоймент з canary-тестуванням.
# 1. Розгорнути стабільну версіюk create deploy prod --image=nginx:1.20 --replicas=5
# 2. Створити сервісk expose deploy prod --name=production --port=80
# 3. Створити canary (10%)k create deploy canary --image=nginx:1.21 --replicas=1
# 4. Спрямувати сервіс на обохk patch deploy prod -p '{"spec":{"template":{"metadata":{"labels":{"release":"production"}}}}}'k patch deploy canary -p '{"spec":{"template":{"metadata":{"labels":{"release":"production"}}}}}'k patch svc production -p '{"spec":{"selector":{"release":"production"}}}'
# 5. Протестувати canaryk logs -l app=canary
# 6. Поступове розгортанняk scale deploy canary --replicas=3k scale deploy prod --replicas=3
# 7. Повне розгортанняk scale deploy canary --replicas=5k scale deploy prod --replicas=0
# 8. Очищенняk delete deploy prod canaryk delete svc productionНаступний модуль
Розділ «Наступний модуль»Кумулятивний тест Частини 2 — перевірте свої знання з розгортання застосунків.