← Kubernetes локально
10 мин · просто · Урок 7 из 8

Что доставить в свежий кластер

metrics-server для kubectl top, ситуация с закрытым ingress-nginx, Gateway API и StorageClass.

Кластер поднялся, ноды в Ready, kubectl отвечает. Дальше выясняется, что kubectl top pod ругается на отсутствующий Metrics API, объекты Ingress создаются, но никуда не ведут, а PersistentVolumeClaim висит в Pending. Ничего не сломано: этих компонентов в кластере просто нет либо они есть не везде.

Разберём четыре вещи, которых чаще всего не хватает.

Инструментmetrics-serverIngressStorageClass
kindставится и патчится рукаминативно с cloud-provider-kind v0.9.0standard
k3s и k3dуже в кластереTraefiklocal-path
minikubeаддон, патчить не надоаддон, ingress-nginx 1.14.3standard
MicroK8sаддонаддон, nginx-basedаддон microk8s-hostpath

metrics-server

kubectl top node и kubectl top pod не работают сами по себе. За ними стоит Metrics API, а его реализует отдельный компонент metrics-server. Он же кормит цифрами HorizontalPodAutoscaler.

Актуальная версия - v0.9.0 от 2026-07-13, образ registry.k8s.io/metrics-server/metrics-server:v0.9.0. Манифест лежит в релизах проекта:

https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.9.0/components.yaml

Первый URL всегда отдаёт последний релиз, второй прибит к конкретной версии.

Почему в локальном кластере нужен --kubelet-insecure-tls

metrics-server ходит за метриками в kubelet по HTTPS и проверяет его сертификат. В kind, k3d и minikube kubelet отдаёт самоподписанный serving-сертификат, который не проходит проверку x509. Поды metrics-server в итоге не доходят до состояния Ready, а kubectl top отвечает «Metrics API not available».

Лечится флагом --kubelet-insecure-tls, он выключает проверку. В дефолтном манифесте этого флага нет, и это правильно: манифест рассчитан на нормальный кластер, где выключенная проверка сертификата kubelet была бы дырой. README проекта помечает флаг именно как решение для тестовых окружений.

Для kind манифест ставят и потом патчат:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.9.0/components.yaml
kubectl -n kube-system patch deployment metrics-server --type=json \
  -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'

Где ставить не надо. В k3s и k3d metrics-server уже входит в packaged components вместе с coredns, traefik, local-storage и servicelb. Отключается флагом --disable=metrics-server.

Где включается аддоном:

minikube addons enable metrics-server   # собран с нужными флагами, патчить не надо
microk8s enable metrics-server

Ingress: ingress-nginx закрыт

Самый популярный Ingress-контроллер в Kubernetes больше не развивается. Об этом надо знать до того, как ты откроешь любой туториал двухлетней давности.

Репозиторий kubernetes/ingress-nginx архивирован 24 марта 2026 и переведён в read-only. README говорит прямо: «If you are not already using ingress-nginx, you should not be deploying it as it is not being developed. Instead you should identify a Gateway API implementation and use it».

Последний релиз - controller-v1.15.1 от 2026-03-19, Helm-чарт 4.15.1. Заявленная поддержка Kubernetes там 1.31-1.35, при том что апстрим уже 1.37. То есть на свежем кластере он формально вне заявленного окна поддержки.

Из совместного заявления Kubernetes Steering Committee и Security Response Committee: релизов, багфиксов и патчей безопасности больше не будет, существующие деплойменты продолжат работать с непропатченными уязвимостями. Причина обыденная - один-два мейнтейнера в свободное время и накопленный техдолг. Проект-преемник InGate тоже свёрнут, прямой drop-in замены нет.

При этом он никуда не делся

По оценке Steering Committee, ingress-nginx крутится примерно в половине cloud-native окружений. На сентябрь 2026 он продолжает работать в проде у множества команд: контроллер не самоуничтожается от того, что репозиторий заархивировали.

Практический вывод двойной. Разворачивать новый ingress-nginx не стоит. Но читать и понимать его аннотации (nginx.ingress.kubernetes.io/rewrite-target и остальные) всё ещё нужно - иначе не разберёшься в чужих манифестах, а их вокруг очень много.

Что делать с существующим: он не сломается сам по себе, но и не получит патчей, поэтому переезд планировать надо. Инструмент миграции на Gateway API - ingress2gateway версии 1.0.

Проверить, есть ли он в твоём кластере:

kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginx

Ловушка в minikube

minikube addons enable ingress до сих пор ставит ingress-nginx, причём версию 1.14.3 - даже не последнюю выпущенную 1.15.1. Issue kubernetes/minikube#22030 открыт с 2025-12-03, решения нет. Так что человек, который просто следует документации minikube, разворачивает у себя мёртвый контроллер и об этом не узнаёт.

microk8s enable ingress тоже nginx-based.

В kind ситуация изменилась. Документация переписана: с cloud-provider-kind v0.9.0 Ingress поддерживается нативно, «No third-party ingress controllers are required by default».

kind create cluster
kubectl apply -f https://kind.sigs.k8s.io/examples/ingress/usage.yaml
INGRESS_IP=$(kubectl get ingress example-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl ${INGRESS_IP}/foo

В k3d и k3s по умолчанию стоит Traefik, отключается через --k3s-arg "--disable=traefik@server:0".

Gateway API

Преемник Ingress, на который Kubernetes указывает как на дальнейший путь. Это набор CRD, то есть новые типы ресурсов, которые ставятся в кластер отдельно от контроллера.

Текущая версия CRD - v1.6.1 от 2026-07-16. Два канала:

kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/standard-install.yaml
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.6.1/experimental-install.yaml

Флаг --server-side здесь обязателен, а не желателен. Манифест слишком велик для client-side apply: при обычном kubectl apply он не помещается в аннотацию last-applied-configuration, и команда падает. Server-side apply хранит состояние на стороне API server и ограничения не имеет.

Standard - стабильный набор. Experimental добавляет к нему поля и ресурсы, которые ещё меняются.

Сами CRD ничего не маршрутизируют. Нужна реализация, которая их читает. Локально работают:

StorageClass

Без StorageClass любой PersistentVolumeClaim с динамическим провижнингом останется в Pending. Проверяется одной командой:

kubectl get storageclass

Из коробки есть в k3s и k3d (local-path, дефолтный), в kind (standard, provisioner rancher.io/local-path) и в minikube (standard, provisioner k8s.io/minikube-hostpath).

Руками ставить надо в MicroK8s: microk8s enable hostpath-storage, класс появится под именем microk8s-hostpath.

В kubeadm, k0s и Talos StorageClass нет вообще. Обычное решение - поставить rancher/local-path-provisioner, актуальная версия v0.0.37 от 2026-08-05.

Коротко

Прошли материал до конца? Отметьте урок пройденным.