Какие типичные ошибки возникают при создании Deployment в Kubernetes?

«Какие типичные ошибки возникают при создании Deployment в Kubernetes?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

На основе своего опыта развёртывания приложений в продакшене, я часто сталкивался со следующими ошибками в манифестах Deployment:

  1. Отсутствие или некорректные Liveness и Readiness Probes: Без них kubelet не понимает, когда контейнер готов принимать трафик или когда его нужно перезапустить. Это приводит к даунтайму во время обновлений.

    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
  2. Не указаны Resource Requests и Limits: Это самая частая причина проблем со стабильностью кластера. Без requests планировщик не может правильно разместить под, а без limits контейнер может исчерпать всю память узла, вызвав OOMKill.

    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
      limits:
        memory: "256Mi"
        cpu: "500m"
  3. Использование тега latest для образа: Это нарушает принцип идемпотентности. Сегодня и завтра latest могут быть разными образами, что делает деплой непредсказуемым. Всегда используйте конкретный тег или SHA.

    # Плохо
    image: myapp:latest
    # Хорошо
    image: myapp:v1.2.3
    # Или лучше (полная детерминированность)
    image: myapp@sha256:abc123...
  4. Неправильная стратегия обновления (strategy): По умолчанию используется RollingUpdate, но без настройки maxUnavailable и maxSurge можно получить полную недоступность сервиса или чрезмерную нагрузку на узлы.

    strategy:
      type: RollingUpdate
      rollingUpdate:
        maxUnavailable: 25%
        maxSurge: 1
  5. Отсутствие меток (labels) и селекторов (selector): Несоответствие spec.selector.matchLabels и меток в spec.template.metadata.labels приведёт к тому, что Deployment не сможет управлять своими подами. Я всегда проверяю это в первую очередь.