Почему использование hostPort может неожиданно ограничить размещение реплик подов на узлах?
hostPort резервирует порт узла для конкретного пода. Поэтому две реплики, которым нужен один и тот же порт, не смогут одновременно размещаться на одном узле, даже если CPU и память ещё доступны. При большом числе реплик это уменьшает множество допустимых узлов и может привести к невозможности планирования.
Контейнеры изначально часто запускались с прямой публикацией портов узла, чтобы приложение было доступно без отдельного прокси или балансировщика. В оркестраторах такой подход сохранился для системных агентов, сетевых компонентов и приложений, которым нужен доступ через конкретный порт каждого узла.
Позже основным способом доступа стали сервисы, балансировщики и ingress-маршрутизация. Они отделяют адрес приложения от конкретного узла и обычно не требуют резервировать один и тот же порт на каждом экземпляре.
Предположим, Deployment должен поддерживать десять реплик, а каждая использует один и тот же hostPort. Если на кластере только шесть подходящих узлов, планировщик сможет разместить не более шести таких подов: на каждом узле соответствующий порт уже занят.
Нехватка CPU или памяти при этом может отсутствовать. Ошибка проявляется как невозможность назначить под узлу, потому что нарушается ограничение по порту. Это особенно опасно при масштабировании, rolling update и восстановлении после отказа узла: новая реплика может не разместиться, пока старая не будет удалена.
При использовании hostPort сетевой порт пода связывается с портом на узле, где этот под работает. Планировщик учитывает такую привязку как ресурсное ограничение: он исключает узлы, на которых уже есть несовместимое занятие того же порта и протокола. Ограничение действует для размещения на одном узле, а не обязательно для всего кластера.
Следовательно, доступность реплик зависит не только от ресурсов, taint и affinity, но и от количества подходящих узлов. Перенос пода на другой узел возможен лишь там, где нужный порт свободен и остальные правила размещения также выполнены.
Нужно отличать hostPort от публикации через Service типа NodePort. В первом случае порт закреплён за конкретным подом и учитывается как ограничение его размещения. Во втором случае порт обычно обслуживается сетевым механизмом сервиса и направляет трафик к набору подов, поэтому приложение не обязано занимать этот порт непосредственно на каждом узле.
hostPort оправдан для узловых агентов, локальных сетевых прокси и случаев, когда клиент действительно должен обращаться к конкретному узлу. Для обычного stateless-сервиса обычно лучше использовать Service, ingress или внешний балансировщик. Цена отказа от hostPort — дополнительный сетевой слой и потенциальная необходимость настроить маршрутизацию, health checks и балансировку.
Есть и операционные последствия. При rolling update старый и новый под могут временно существовать одновременно, поэтому новый под не разместится на том же узле, если порт уже занят старой репликой. При этом стратегия обновления и число доступных узлов должны учитывать такое ограничение.
Команда развернула несколько реплик HTTP-сервиса с hostPort 443. После увеличения числа реплик часть подов оставалась в состоянии ожидания, хотя кластер имел свободные вычислительные ресурсы. Анализ показал, что подходящих узлов было меньше, чем реплик, потому что порт 443 мог использовать только один экземпляр на узле.
Рассматривались два варианта. Добавление узлов решало проблему быстро, но увеличивало стоимость и сохраняло жёсткую связь масштабирования с числом узлов. Удаление hostPort и публикация сервиса через ingress требовали перенастройки сети и проверки TLS-маршрутизации, зато позволяли размещать несколько реплик на одном узле.
Выбрали ingress перед обычным Service, а TLS завершали на ingress-контроллере. После этого реплики стали распределяться по доступным ресурсам, rolling update перестал блокироваться из-за занятого порта, а количество узлов можно было изменять независимо от числа экземпляров приложения.
Нет. Обычно ограничение локально для узла: несколько подов могут использовать один и тот же hostPort, если они размещены на разных узлах и совпадают остальные условия совместимости. Поэтому итоговый максимум определяется числом подходящих узлов, а не простым числом реплик в кластере.
Планировщик проверяет не только количественные ресурсы, но и ограничения совместимости. Уже занятый порт является отдельным фильтром: узел отбрасывается, даже если на нём достаточно CPU и памяти. Поэтому диагностика должна учитывать события планирования и причины исключения узлов, а не только метрики загрузки.
Нет. Если сам под продолжает использовать hostPort, ограничение размещения сохраняется независимо от наличия Service. Service лишь предоставляет стабильную точку доступа и может распределять трафик между подами; чтобы снять ограничение, нужно убрать непосредственную привязку приложения к порту узла и обеспечить доступ другим сетевым способом.