Код-ревью Middle Pod и Deployment обновлено

Ревью: Deployment API

Вопрос

Найди проблемы в Deployment продового API.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 0
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: registry.example.com/api:latest
          ports:
            - containerPort: 8080
        - name: postgres
          image: postgres:16

Коротко

Исправленный вариант: База выносится в отдельный StatefulSet с томом или в управляемый сервис, приложение ходит к ней через Service. Для распределения реплик по узлам стоит добавить topologySpreadConstraints или anti-affinity.

Что должен найти ревьюер

  1. Ошибкастрока 6
    Одна реплика: при обновлении, падении или переносе пода сервис недоступен. Для прода минимум 2-3 реплики на разных узлах.
  2. Ошибкастрока 10
    С maxUnavailable: 1 и maxSurge: 0 при одной реплике старый под удаляется до создания нового: простой на каждом деплое. Нужно maxUnavailable: 0, maxSurge: 1.
  3. Ошибкастрока 22
    Тег latest: неизвестно, что запущено, rollout undo не вернёт прежний код, если тег перезаписан. Указать версию.
  4. Ошибкастрока 25
    База в том же поде, что и приложение: масштабирование API размножит базы, данные пропадут при пересоздании пода. База отдельно (StatefulSet или управляемая).
  5. Производительность
    Нет readiness и liveness probe: rolling update будет считать поды готовыми сразу после старта.
  6. Производительность
    Нет resources: под в классе BestEffort, планировщик не учитывает потребности.

Разбор

Исправленный вариант:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: registry.example.com/api:1.4.2
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet: { path: /ready, port: 8080 }
          resources:
            requests: { cpu: 200m, memory: 256Mi }
            limits: { memory: 256Mi }

База выносится в отдельный StatefulSet с томом или в управляемый сервис, приложение ходит к ней через Service. Для распределения реплик по узлам стоит добавить topologySpreadConstraints или anti-affinity.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме