Перейти к содержанию

Журналы, ручное масштабирование и условия HPA

Замена версии показывает, как приложение меняется, а сопровождение требует понять, что с ним происходит сейчас. Рассмотрим журналы API и увеличение числа копий. Затем прочитаем декларацию HPA, явно отделив её предпосылки от базовой лаборатории. Результат урока — связать наблюдаемую проблему с конкретным процессом и не считать масштабирование универсальным ответом на любую ошибку.

В «Площадке» уже есть Deployment, Service, конфигурация, probes и requests. Автор не собирал метрики, не проводил нагрузку и не выполнял scale. Ниже нет выдуманных значений CPU или результатов «до и после». HPA включён в исходники как необязательная ветка, требующая рабочего Metrics API.

Структурированный журнал HTTP-запроса

Полный api/server.mjs пишет одну JSON-запись после завершения ответа. В ней находятся метод, путь, статус, длительность, имя Pod и версия окружения. Например, ожидаемая форма записи:

{
  "event": "request",
  "method": "GET",
  "path": "/api/lessons",
  "status": 200,
  "durationMs": 3,
  "pod": "api-<hash>-<suffix>",
  "version": "1"
}

Число 3 здесь иллюстрирует поле, а не измеренный результат. Реальное значение зависит от выполнения. Имя Pod не следует копировать в конфигурацию: оно помогает расследовать экземпляр. Форма JSON удобна для последующей обработки, потому что поля можно искать отдельно без разбора произвольной фразы.

В журнал не включается Authorization. Даже учебный токен не нужен для объяснения статуса запроса. В настоящем приложении также важно продумать обработку query string, идентификаторов пользователей и тела запроса. Подробный журнал полезен только тогда, когда не превращается в неконтролируемое хранилище чувствительных данных.

Журнал процесса и пользовательский статус связаны, но не совпадают. API мог завершить ответ 200, а соединение к браузеру оборвалось дальше. Или web вернул 502, не получив ответ upstream, и у нужного API нет соответствующей записи. Для полного расследования пригоден correlation ID, проходящий через все компоненты; в маленьком наборе он пока не реализован.

Как читать копии приложения

Будущие команды читателя:

kubectl --context kind-ploshchadka -n ploshchadka get pods -l app=api
kubectl --context kind-ploshchadka -n ploshchadka logs -l app=api --prefix --tail=50
kubectl --context kind-ploshchadka -n ploshchadka get events --sort-by=.metadata.creationTimestamp

Селектор собирает журналы подходящих Pod, а --prefix добавляет источник. Это удобнее, чем угадывать, какая копия обслужила запрос. При длинном расследовании нужны ограничение времени и постоянное централизованное хранение; локальный вывод kubectl не является долговременной системой журналов.

Если контейнер перезапустился, полезен logs конкретного Pod с --previous. Команда относится к предыдущему экземпляру контейнера в этом Pod, а не ко всем историческим Pod Deployment. После удаления объекта доступ к его локальному журналу не гарантирован. Поэтому регламент сопровождения должен определять, где сохраняются данные инцидента.

События Kubernetes объясняют создание, размещение, ошибки образов и probes. HTTP-журнал объясняет поведение процесса. Если Pod не был запущен, ждать от Node сообщения о неудачном запросе бессмысленно. И наоборот, Event о запуске контейнера не объяснит, почему конкретный endpoint вернул неверную бизнес-ошибку.

Ручное увеличение числа реплик

Для начала масштабирование можно выразить изменением replicas в полном манифесте API. Краткая учебная команда:

kubectl --context kind-ploshchadka -n ploshchadka scale deployment/api --replicas=3
kubectl --context kind-ploshchadka -n ploshchadka get deployments,pods

Ожидается третья копия того же шаблона. Нужно также сохранить replicas: 3 в текущей декларации, если это новое принятое состояние. Иначе повторное применение файла с двумя репликами вернёт прежнее намерение. Разница между оперативной командой и источником конфигурации должна оставаться видимой.

Три процесса API дают дополнительные независимые обработчики, но не обещают троекратную производительность. Все они делят один локальный узел. Если причина задержки — общий внешний сервис, новые экземпляры могут увеличить нагрузку на него. Если причина — ошибочный маршрут, копии будут одинаково возвращать ошибку. Сначала нужен диагноз, затем выбор действия.

Имя Pod в ответе каталога помогает увидеть распределение обращений между экземплярами. Однако несколько запросов не подтверждают равномерную балансировку, а временный port-forward выбирает конкретный Pod web. Нельзя превратить такое наблюдение в график производительности без реального сценария нагрузки и описания сетевого пути.

HPA и необходимая метрика

При наблюдении масштабирования отличайте желаемое количество от доступного. Команда scale может успешно обновить число, пока новые Pod ещё создаются или ожидают ресурс. Пользовательский эффект появится после готовности подходящих экземпляров. Поэтому короткий успешный ответ управляющего API не подтверждает, что дополнительная копия уже обслуживает каталог.

Срок реакции на рост нагрузки также важен. Даже установленный HPA не создаёт готовый процесс мгновенно: требуется метрика, решение, размещение, запуск и readiness. Для резкого пика нужен исходный запас мощности или другой предметный способ обработки запросов. В нашей «Площадке» маленький каталог не демонстрирует такую нагрузку; объяснение лишь задаёт вопросы для будущего продукта.

При уменьшении replicas активная работа должна учитывать завершение экземпляра. Обработчик SIGTERM из восьмого урока помогает сохранить завершение уже начатых коротких запросов. Поэтому масштабирование связано с жизненным циклом приложения, а не только с числом объектов на странице состояния.

HorizontalPodAutoscaler сравнивает наблюдаемую метрику с целью и изменяет желаемое число реплик. В 10-hpa.yaml используется CPU utilization относительно requests:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api
  namespace: ploshchadka
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 2
  maxReplicas: 4
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 120

Проценты относятся к request CPU, а не к limit или полной мощности ноутбука. Для request 50m цель 60 означает иной абсолютный уровень, чем при request 500m. Поэтому изменение request влияет на смысл того же HPA. Ресурсные настройки и политика масштабирования нужно рассматривать совместно.

В обычном kind Metrics Server автоматически не установлен. Если Metrics API отсутствует, HPA не получает нужные значения; создание объекта не делает метрики доступными. Файл применяется только после самостоятельной подготовки подходящей среды. В базовом маршруте курса остаётся ручное масштабирование, чтобы не выдавать необязательный компонент за проверенную часть лаборатории.

Stabilization window при уменьшении числа копий помогает избежать слишком резких колебаний. Верхняя граница 4 ограничивает намерение, но не гарантирует размещение всех четырёх Pod. Scheduler всё ещё учитывает requests, а приложение — реальные зависимости. Работа HPA описана в официальной документации.

Если HPA управляет replicas, одновременное ручное изменение того же поля создаёт конкурирующие источники намерения. Перед handoff выберите режим: ручное число в декларации либо установленная политика автоматического масштабирования. Для «Площадки» без Metrics API сохраняем ручной режим. Финальный урок собирает регламент передачи и восстановления лаборатории.

Оглавление серии