Код-ревью Middle Отладка в кластере обновлено

Ревью: почему под падает

Вопрос

Поды этого Deployment уходят в CrashLoopBackOff. Найди причины в манифесте (образ слушает 8080, старт около 40 секунд, приложение требует переменную DATABASE_URL).

spec:
  template:
    spec:
      containers:
        - name: api
          image: registry.example.com/api:1.4.2
          command: ["node", "dist/main.js", "&"]
          env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: api-secret
                  key: database_url
          livenessProbe:
            httpGet: { path: /healthz, port: 3000 }
            initialDelaySeconds: 10
            failureThreshold: 3
          resources:
            limits:
              memory: 64Mi

Коротко

Исправленный контейнер: Именованный порт http убирает рассинхронизацию номеров. Каждую из найденных причин подтверждает kubectl describe pod: Reason, Exit Code и события Liveness probe failed.

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

  1. Ошибкастрока 7
    Аргумент "&" передаётся node как обычная строка (shell не участвует в exec-форме): процесс получит лишний аргумент. Фоновый запуск в контейнере вообще не нужен, процесс должен работать на переднем плане.
  2. Ошибкастрока 15
    Liveness на порт 3000, а приложение слушает 8080: проверка всегда падает, контейнер убивается после трёх попыток (exit 137 или 143).
  3. Ошибкастрока 16
    Старт 40 секунд, а liveness начинает через 10: даже с правильным портом под будут убивать до запуска. Нужна startupProbe.
  4. Ошибкастрока 20
    Лимит памяти 64Mi для Node.js-приложения: OOMKilled при старте. Выставить по реальному потреблению.
  5. Производительность
    Нет readinessProbe и requests: трафик пойдёт на неготовые поды, планировщик не учитывает потребности.

Разбор

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

containers:
  - name: api
    image: registry.example.com/api:1.4.2
    command: ["node", "dist/main.js"]
    env:
      - name: DATABASE_URL
        valueFrom:
          secretKeyRef: { name: api-secret, key: database_url }
    ports:
      - { name: http, containerPort: 8080 }
    startupProbe:
      httpGet: { path: /healthz, port: http }
      periodSeconds: 5
      failureThreshold: 18
    livenessProbe:
      httpGet: { path: /healthz, port: http }
      periodSeconds: 10
      failureThreshold: 3
    readinessProbe:
      httpGet: { path: /ready, port: http }
    resources:
      requests: { cpu: 200m, memory: 384Mi }
      limits: { memory: 384Mi }

Именованный порт http убирает рассинхронизацию номеров. Каждую из найденных причин подтверждает kubectl describe pod: Reason, Exit Code и события Liveness probe failed.

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

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