tg-me.com/DevOPSitsec/1472
Last Update:
⚙️ DevOps‑челлендж «Zero‑Downtime? Серьёзно?»
Вам выдали репозиторий ShopCat (SaaS‑платформа).
Он уже «работает» в Kubernetes‑кластере AWS EKS, собирается GitHub Actions и раскатывается Helm‑чартом.
Менеджеры уверяют, что *«релизы без простоя, всё по‑мажору»* — но пользователи получают 502 при каждом деплое.
Ваша миссия — найти и устранить скрытую причину даунтайма, не внося изменений в само приложение.
📂 Что есть в репо
.
├─ docker/
│ └─ Dockerfile # двухступенчатая сборка
├─ helm/
│ └─ shopcat/ # Chart.yaml + values.yaml + templates/*
├─ k8s/
│ ├─ namespace.yaml
│ └─ ingress.yaml # AWS ALB Ingress Controller
├─ .github/workflows/
│ └─ deploy.yml # CI → CD
└─ terraform/
├─ eks.tf
├─ rds.tf
└─ outputs.tf
⚠️ Подвох № 1 (скрытый таймер)
В
Dockerfile
есть RUN adduser ...
с интерактивным sudo‐prompt’ом, который «застревает», но только если кеш Docker‑слоёв инвалидирован (например, при обновлении base‑image).
⚠️ Подвох № 2 (невидимая «дырка» в rolling‑update)
В шаблоне Deployment:
livenessProbe:
httpGet:
path: /healthz
port: 8080
---
readinessProbe:
httpGet:
path: /healthz
port: 8080
*
/healthz
возвращает 200 даже во время graceful‑shutdown (SIGTERM → 30 с drain). *
terminationGracePeriodSeconds
= 60
, а Ingress ALB считает Pod «живым», пока тот не закроется. * В итоге старый Pod уже не принимает новые запросы, но остаётся в EndpointSlice ещё ±60 секунд.
⚠️ Подвох № 3 («сам себе злобный Буратино»)
Helm‑values указывают образ
image: shopcat:latest
. GitHub Actions пушит тэгированный
:vX.Y.Z
, но тэг :latest
перезаписывается той же джобой PR‑preview. В production во время canary‑release может внезапно оказаться незамёрженый код Pull‑Request’а.
## 🏆 Задание
1. Настройте pipeline, чтобы:
* на каждый PR собирался
shopcat:<sha>
и катил preview‑релиз в namespace pr‑<num>
, * на
main
пушился shopcat:v<semver>
, после чего Helm делал blue/green‑deploy в prod
.2. Измените манифесты так, чтобы во время rolling‑update не было 502/504:
* никакого даунтайма, даже если контейнеру нужно 60 с на graceful‑shutdown;
* сетевой трафик должен _сначала_ уходить от старых Pod’ов, а _потом_ те выключаются.
3. Ограничьте blast‑radius: превратить
latest
в «immutable image tag» и запретить Helm обновлять release, если image.tag
уже был задеплоен (hint: .Chart.AppVersion
+ `helm.sh/hook`).4. Найдите и исправьте «застревающий» шаг в Dockerfile, чтобы кэш всегда использовался, а билд не ждал интерактива.
5. ✅ Предоставьте:
* патчи (`.diff`) или PR в репозиторий,
* скриншот успешного
kubectl rollout status deployment/shopcat ‑‑watch
,* краткое Post‑mortem (≤ 300 слов): *«Почему был даунтайм и какой фикс вы сделали»*.
## 💣 Неочевидные ограничения
* Нельзя менять исходный код приложения (только инфраструктура).
* Кластер prod имеет 2 ноды t3.medium (4 vCPU, 8 GiB) — бюджету больно от лишних replica‑set’ов.
* CI‑время — ≤ 5 мин на каждый PR.
* Все секреты — только через AWS Secrets Manager; в манифестах не должно быть
plaintext
.@DevOPSitsec