снизить blast radius релизов через метрико-управляемый progressive rollout
Прогрессивная доставка в Kubernetes: canary deployments и feature flags для контролируемых rollout
12 минут
Обычный rolling update всё равно отдаёт рискованные изменения всем пользователям сразу. В статье — связка canary-трафика через Flagger и feature flags: проверка релиза под реальной нагрузкой и быстрый откат без полного простоя.
Почему rolling update недостаточен для безопасности в production
Команды в production на Kubernetes регулярно видят один и тот же сценарий: выкатили новую версию, через минуты растут ошибки, дежурные спешат с откатом. Причина редко в одном изолированном баге. Чаще это сочетание выката непроверенного поведения на всю аудиторию сразу и отсутствия автоматической обратной связи до customer-visible инцидента. Readiness probes и стандартный rolling update снижают часть риска, но не заменяют осознанную progressive delivery. В GitOps desired state может быстро сойтись, а корректность ещё не подтверждена. Без контроля трафика и release gates команды возвращаются к ручным approvals или принимают рискованные деплои как норму.
Canary-трафик и feature flags решают разные уровни
Progressive delivery постепенно открывает новую версию для production-трафика и по сигналам observability решает, продолжать или прервать rollout. Canary deployments переводят настраиваемую долю трафика на новую версию и сравнивают error rate, latency и бизнес-метрики со stable baseline. Flagger или Argo Rollouts автоматизируют шаги веса и откат. Feature flags отделяют deployment от release: бинарник может быть везде, а конкретные code paths остаются выключенными до явного включения. Используйте оба механизма: canary управляет объёмом трафика на новую версию, flags — тем, какая функциональность активна для каких пользователей.
Опорный rollout: Flagger с Istio и анализом в Prometheus
Пример: API-сервис на Istio переходит с v1.3.2 на v1.4.0 с переписанным модулем аутентификации. Установите Flagger в namespace mesh, укажите Prometheus и опишите Canary resource с пошаговым увеличением веса и порогами метрик. Перед production сверьте поля CRD с установленной версией Flagger. Держите HPA на целевом Deployment, чтобы canary-масштабирование не «голодаало» stable release.
helm repo add flagger https://flagger.app
helm repo update
helm upgrade --install flagger flagger/flagger \
--namespace=istio-system \
--set meshProvider=istio \
--set metricsServer=http://prometheus:9090 \
--waitapiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: api-service
namespace: production
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service
service:
port: 8080
analysis:
interval: 1m
threshold: 5
maxWeight: 30
stepWeight: 10
metrics:
- name: request-success-rate
thresholdRange:
min: 99
interval: 1m
- name: request-duration
thresholdRange:
max: 500
interval: 1m
revertOnFailure: trueapiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-service
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70kubectl set image deployment/api-service \
api-service=registry.example.com/api-service:v1.4.0 \
-n productionДобавьте feature flags для рискованных code paths
Для переписанной аутентификации ограничьте canary-трафик и включайте новый handler через flag. Даже при 30% запросов на v1.4.0 только часть пользователей должна выполнять auth v2. Если новый путь ведёт себя плохо, отключите flag без отката всего deployment. В этом разделение traffic-level и code-level контролей и есть главная ценность подхода.
import os
import hashlib
TOGGLE_NEW_AUTH = os.environ.get("TOGGLE_NEW_AUTH", "false").lower() == "true"
def is_auth_v2_enabled(user_id: str) -> bool:
if not TOGGLE_NEW_AUTH:
return False
bucket = int(hashlib.md5(user_id.encode()).hexdigest(), 16) % 100
return bucket < 10from config import is_auth_v2_enabled
def authenticate(request):
user_id = request.headers.get("X-User-ID", "")
if is_auth_v2_enabled(user_id):
return auth_v2_authenticate(request)
return auth_v1_authenticate(request)Операционные практики, которые держат progressive delivery честным
Задайте пороги успеха до старта rollout и убедитесь, что labels в Prometheus позволяют сравнивать canary и primary. Окна анализа должны быть статистически значимыми: короткие интервалы помогают частым релизам, но нельзя продвигать canary по шуму. Изолируйте blast radius через NetworkPolicy или mesh authorization, чтобы canary pod не писал в shared production data paths без необходимости. Автоматизируйте rollback по метрикам, но оставьте ручной pause/rollback на случай задержек телеметрии или неверных запросов. Раз в квартал проводите учения по откату и фиксируйте каждую canary-попытку: версия, вес трафика, снимки метрик, итог. Feature flags — инструмент release, а не замена canary traffic split.
Свяжите темп rollout с политикой надёжности
Progressive delivery должна учитывать error budget. Если бюджет уже под давлением, замедлите шаги canary или усильте pre-production проверки. В зрелых контурах связывайте gates выката с burn-сигналами SLO и правилами promotion в GitOps, чтобы изменения desired state не опережали подтверждённое здоровье сервиса. Цель — сделать откат настолько дешёвым, чтобы production deploy стал рутинным экспериментом с понятными условиями abort, а не событием с высокими ставками.
Canary-анализ работает только при заранее заданных критериях успеха — их задаём в гайде по SLO, SLI и error budget для платформенных команд.
Если во время миграции схемы нужно держать две версии приложения, согласуйте политику выката с подходом к миграциям схемы БД в CI/CD.
